总有那么几个二比产品,让你上拉刷新下拉加载之后,又想让你可以侧滑删除,我想静静.
产品狗虽然可恨,可是我们还是得乖乖的去实现,没办法,谁让我们是打工的,加油骚年们.
看下我们的效果
这里写图片描述
首先定义我们最重要的一个侧滑处理类,使用ViewDragHelper来处理的.不懂的可以看下弘扬大神的博客
Android ViewDragHelper完全解析 自定义ViewGroup神器
package yuan.kuo.yu.view;
import android.content.Context;
import android.graphics.Rect;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
/**
* Created by yukuoyuan on 2017/3/10.
* 这是一个可以侧滑菜单的条目的父布局
*/
public class SwipeRecycleviewItemLayout extends FrameLayout {
private View menu;
private View content;
private final ViewDragHelper dragHelper;
private boolean isOpen;
private int currentState;
/**
* 构造方法
*
* @param context 上下文
* @param attrs 属性集合
*/
public SwipeRecycleviewItemLayout(Context context, AttributeSet attrs) {
super(context, attrs);
/**
* 初始化我们自定义处理触摸事件的方法
*/
dragHelper = ViewDragHelper.create(this, rightCallback);
}
private ViewDragHelper.Callback rightCallback = new ViewDragHelper.Callback() {
// 触摸到View的时候就会回调这个方法。
// return true表示抓取这个View。
@Override
public boolean tryCaptureView(View child, int pointerId) {
return content == child;
}
/**
* 重新处理子view的左侧
* @param child
* @param left
* @param dx
* @return
*/
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
return left > 0 ? 0 : left < -menu.getWidth() ? -menu.getWidth() : left;
}
/**
* 当手指释放的时候回调
* @param releasedChild
* @param xvel
* @param yvel
*/
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
// x轴移动速度大于菜单一半,或者已经移动到菜单的一般之后,展开菜单
if (isOpen) {
if (xvel > menu.getWidth() || -content.getLeft() < menu.getWidth() / 2) {
close();
} else {
open();
}
} else {
if (-xvel > menu.getWidth() || -content.getLeft() > menu.getWidth() / 2) {
open();
} else {
close();
}
}
}
/**
* view 横向移动的范围
* @param child
* @return
*/
@Override
public int getViewHorizontalDragRange(View child) {
return 1;
}
/**
*view纵向移动的范围
* @param child
* @return
*/
@Override
public int getViewVerticalDragRange(View child) {
return 1;
}
/**
* 当ViewDragHelper状态发生变化的时候调用(IDLE,DRAGGING,SETTING[自动滚动时])
* @param state
*/
@Override
public void onViewDragStateChanged(int state) {
super.onViewDragStateChanged(state);
currentState = state;
}
};
/**
* 处理触摸事件(交给draghelper去处理)
*
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
dragHelper.processTouchEvent(event);
return true;
}
/**
* 处理触摸事件
*
* @param ev
* @return
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return dragHelper.shouldInterceptTouchEvent(ev);
}
/**
* 获取当前的状态
*
* @return
*/
public int getState() {
return currentState;
}
private Rect outRect = new Rect();
public Rect getMenuRect() {
menu.getHitRect(outRect);
return outRect;
}
/**
* 当绘制完毕调用的方法
*/
@Override
protected void onFinishInflate() {
super.onFinishInflate();
menu = getChildAt(0);
content = getChildAt(1);
}
/**
* 这是一个关闭菜单的方法
*/
public void close() {
dragHelper.smoothSlideViewTo(content, 0, 0);
isOpen = false;
invalidate();
}
/**
* 这是一个打开菜单的方法
*/
public void open() {
dragHelper.smoothSlideViewTo(content, -menu.getWidth(), 0);
isOpen = true;
invalidate();
}
/**
* 计算滚动事件
*/
@Override
public void computeScroll() {
super.computeScroll();
if (dragHelper.continueSettling(true)) {
invalidate();
}
}
/**
* 设置点击事件
*
* @param l
*/
@Override
public void setOnClickListener(OnClickListener l) {
content.setOnClickListener(l);
}
public boolean isOpen() {
return this.isOpen;
}
}
然后定义我们的两个布局
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="?android:colorBackground"
android:layout_height="60dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/item_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#49ff0000"
android:gravity="center"
android:text="小雨来了"
android:textColor="@android:color/white"
android:textSize="16sp" />
</RelativeLayout>
</FrameLayout>
带侧滑删除的类型
<?xml version="1.0" encoding="utf-8"?>
<yuan.kuo.yu.view.SwipeRecycleviewItemLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="?android:colorBackground">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="right"
android:orientation="horizontal">
<TextView
android:id="@+id/delete"
android:layout_width="60dp"
android:layout_height="match_parent"
android:background="#FF6A6A"
android:gravity="center"
android:text="删除"
android:textColor="#fff"
android:textSize="18sp" />
<TextView
android:id="@+id/ok"
android:layout_width="60dp"
android:layout_height="match_parent"
android:background="#e0e0e0"
android:gravity="center"
android:text="确定"
android:textColor="#fff"
android:textSize="16sp" />
</LinearLayout>
<include layout="@layout/item_content" />
</yuan.kuo.yu.view.SwipeRecycleviewItemLayout>
接下来看下我们的适配器
package cn.yu.yuan;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
/**
* Created by yukuo on 2016/4/30.
*/
public class DemoSwipeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<SwipeDate> list = new ArrayList<>();
public DemoSwipeAdapter(List<SwipeDate> list) {
this.list = list;
}
public void addReFreshData() {
notifyDataSetChanged();
}
public void addRLoadMOreData() {
notifyDataSetChanged();
}
/**
* 删除一个数据的方法
*
* @param position 索引
*/
// TODO 一定要按照这个方式写,不然会crash,希望你有更好的解决方案
public void removeData(int position) {
list.remove(position);
notifyItemRemoved(position + 1);
if (position != list.size()) {
if (position == 0) {
notifyDataSetChanged();
} else if (position == (list.size() - 1)) {
notifyItemRangeChanged(position, 0);
} else {
notifyItemRangeChanged(position, list.size() - position);
}
}
}
@Override
public int getItemViewType(int position) {
return list.get(position).type;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
if (viewType == 1) {
view = View.inflate(parent.getContext(), R.layout.item_swipe_menu, null);
return new MySwipeMenuHolder(view);
} else {
view = View.inflate(parent.getContext(), R.layout.item_content, null);
return new MyHolder(view);
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
if (holder instanceof MyHolder) {
MyHolder myHolder = (MyHolder) holder;
myHolder.item_content.setText(list.get(position).name);
} else if (holder instanceof MySwipeMenuHolder) {
MySwipeMenuHolder myHolder = (MySwipeMenuHolder) holder;
myHolder.item_content.setText(list.get(position).name + "######" + position);
myHolder.item_content.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(v.getContext(), list.get(position).name, Toast.LENGTH_SHORT).show();
}
});
myHolder.delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
removeData(position);
}
});
}
}
@Override
public int getItemCount() {
return list.size();
}
class MyHolder extends RecyclerView.ViewHolder {
private final TextView item_content;
public MyHolder(View itemView) {
super(itemView);
item_content = (TextView) itemView.findViewById(R.id.item_content);
}
}
class MySwipeMenuHolder extends RecyclerView.ViewHolder {
private final TextView delete;
private final TextView ok;
private final TextView item_content;
public MySwipeMenuHolder(View itemView) {
super(itemView);
item_content = (TextView) itemView.findViewById(R.id.item_content);
delete = (TextView) itemView.findViewById(R.id.delete);
ok = (TextView) itemView.findViewById(R.id.ok);
}
}
}
ok,到此我们自定义的侧滑删除功能就实现了,其实并没有太多难点,主要是在viewDragHelper这个类里边
Demo地址
欢迎Fork和Star,如果有问题,记得留言反馈给我啊.谢谢
网友评论