前言:
项目源码下载地址:download.csdn.net/detail/mtx_…
此篇主要是通过自动以RecyclerView,同过scrollTo()、Scroller来实现左划删除功能。
1.基础知识引入
scrollTo(int x,inty):
它是View中的方法,可以对View中的内容进行滚动,强调一下滑动的是view的“内容”,scrollTo()是让View相对于初始的位置滚动某段距离
RecyclerView实现左划删除
首选我来看Item的布局文件Recycler_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/item_root"
>
<TextView
android:id="@+id/item_text"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_gravity="center"
android:gravity="center"
android:text="text" />
<TextView
android:id="@+id/item_del"
android:layout_width="100dp"
android:layout_height="fill_parent"
android:background="#EE2C2C"
android:text="删除"
android:textSize="25dp"
android:gravity="center" />
</LinearLayout>复制代码
item有两个水平的textView文件组成,第一个TextView是我们正常显示的Item,它的宽度占满屏幕,第二TextView就是我们的删除按钮,它被隐藏在屏幕之外。下面在看看Adapter部分CustomAdapter.java。
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.CustomViewHolder> {
private List<String> mDatas;
public CustomAdapter(List<String> mDatas, Context mContext) {
this.mDatas = mDatas;
}
@Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item, parent, false);
return new CustomViewHolder(view);
}
@Override
public void onBindViewHolder(final CustomViewHolder holder, final int position) {
holder.textView.setText(mDatas.get(position));
}
@Override
public int getItemCount() {
return mDatas.size();
}
class CustomViewHolder extends RecyclerView.ViewHolder {
TextView textView;
TextView deleteView;
public CustomViewHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.item_text);
deleteView = (TextView) itemView.findViewById(R.id.item_del);
}
}
}复制代码
这个比较简单,没啥可说的,下面我来来看看我的重点部分自定义的CustomRecyclerView类的实现
public class CustomRecyclerView extends RecyclerView{
//item的根布局
private LinearLayout itemRoot;
//上一次滑动的Item根布局
private LinearLayout itemRootLast;
//上次X轴的滑动坐标
private int mlastX = 0;
//上次Y轴的滑动坐标
private int mlastY = 0;
//滑动的最大距离
private final int MAX_WIDTH = 100;
private Context mContext;
private Scroller mScroller;
public CustomRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mContext = context;
mScroller = new Scroller(context, new LinearInterpolator(context, null));
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int maxLength = dipToPx(mContext, MAX_WIDTH);
int x = (int) event.getX();
int y = (int) event.getY();
final int position;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
//恢复上一次侧滑的ITEM
if(itemRootLast !=null){
itemRootLast.scrollTo(0, 0);
invalidate();
}
//根据点击的坐标获取那个Item被点击了
View view = findChildViewUnder(x, y);
if(view == null){
return false;
}
final CustomAdapter.CustomViewHolder viewHolder = (CustomAdapter.CustomViewHolder) getChildViewHolder(view);
itemRootLast = itemRoot = (LinearLayout) viewHolder.textView.getParent();
position= viewHolder.getAdapterPosition();
if(mOnItemClickListener !=null){
viewHolder.deleteView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
mOnItemClickListener.onClick(viewHolder.itemView,position);
}
});
}
}
break;
case MotionEvent.ACTION_MOVE: {
if(itemRoot ==null){
return false;
}
if( Math.abs(mlastX -x)>0 && Math.abs(mlastX -x) > Math.abs(mlastY-y)){
int scrollX = itemRoot.getScrollX();
int newScrollX = scrollX + mlastX - x;
if (newScrollX < 0) {
newScrollX = 0;
} else if (newScrollX > maxLength) {
newScrollX = maxLength;
}
itemRoot.scrollTo(newScrollX, 0);
}
}
break;
case MotionEvent.ACTION_UP: {
if(itemRoot ==null){
return false;
}
int scrollX = itemRoot.getScrollX();
int newScrollX = scrollX + mlastX - x;
if (scrollX > maxLength / 2) {
newScrollX = maxLength;
} else {
newScrollX = 0;
}
mScroller.startScroll(scrollX, 0, newScrollX - scrollX, 0);
invalidate();
}
break;
}
mlastX = x;
mlastY = y;
return super.onTouchEvent(event);
}
private int dipToPx(Context context, int dip) {
return (int) (dip * context.getResources().getDisplayMetrics().density + 0.5f);
}
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
itemRoot.scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
if(itemRootLast !=null){
itemRootLast.scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
}
}
invalidate();
}
private OnItemClickListener mOnItemClickListener;
public interface OnItemClickListener{
void onClick(View view,int position);
}
public void setOnItemClickListenre(OnItemClickListener mOnItemClickListener){
this.mOnItemClickListener = mOnItemClickListener;
}
}复制代码
我来来详细看一下上面的代码:
首选在MotionEvent.ACTION_DOWN事件发生时,如果上次有Item已经侧滑出了,这里就让它恢复正常的显示,接着看
我们通过findChildViewUnder(x, y)方法来实现根据当前点击的坐标值,得到被点击的Item的view,这一步是很关键的,接着我们通过刚才得到view获取到我们的viewHolder对象,拿到它我们就好办了,我们就可以得到点击Item的position等。
我们在MotionEvent.ACTION_MOVE事件中去根据手指滑动的距离来实时处理View的滑动
MotionEvent.ACTION_UP事件中,如果此时滑动的距离大于最大滑动距离的一半,我们就让整个按钮都滑动出来,反之我就让它恢复原来的状态.
删除按钮监听在ACTION_DOWN事件中绑定监听事件即可,监听接口如下
我们在MainActivity中实现给就可就Ok了
项目源码下载地址: download.csdn.net/detail/mtx_…