RecyclerView的实现与滑动删除

RecyclerView : 回收和定位屏幕上的view
ViewHolder : 容纳View视图
Adapter : 创建并绑定ViewHolder至模型层数据

1.添加依赖

    implementation 'com.android.support:appcompat-v7:26.1.0'
//    implementation 'com.android.support:recyclerview-v7:26.1.0'

2.新建ViewHolder与Adapter


public class DemoAdapter extends RecyclerView.Adapter<DemoAdapter.ViewHolder> {
    private List<DemoBean> mDemoBeanList;

    public DemoAdapter(List<DemoBean> demoBeanList) {
        mDemoBeanList = demoBeanList;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.demo_bean,parent,false);
        ViewHolder viewHolder=new ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        DemoBean demoBean=mDemoBeanList.get(position);
        holder.mImageView.setImageResource(demoBean.getImageId());
        holder.mTextView.setText(demoBean.getMsg());
    }

    @Override
    public int getItemCount() {
        return mDemoBeanList.size();
    }

    static class ViewHolder extends RecyclerView.ViewHolder {
        ImageView mImageView;
        TextView mTextView;

        public ViewHolder(View itemView) {
            super(itemView);
            mImageView=(ImageView) itemView.findViewById(R.id.imageview);
            mTextView=(TextView) itemView.findViewById(R.id.textview);
        }
    }
}

3.配置LayoutManager & Adapter

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
        RecyclerView recyclerView=(RecyclerView) findViewById(R.id.recyclerview);
              //GridLayoutManager 实现网格布局  StaggeredGridLayoutManager实现瀑布流布局
        LinearLayoutManager linearLayoutManager=new LinearLayoutManager(this);
        recyclerView.setLayoutManager(linearLayoutManager);
        DemoAdapter demoAdapter=new DemoAdapter(mDemoBeanList);
        recyclerView.setAdapter(demoAdapter);
    }

S: ItemTouchHelper实现滑动删除

 final ItemTouchHelper helper=new ItemTouchHelper(new ItemTouchHelper.Callback() {
            @Override
            public boolean isLongPressDragEnabled() {
                return true;
            }

            @Override
            public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
                super.onSelectedChanged(viewHolder, actionState);
            }

            @Override
            public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
                int dragFlags=ItemTouchHelper.UP|ItemTouchHelper.DOWN;
                int swipFlags=ItemTouchHelper.END|ItemTouchHelper.START;
                return makeMovementFlags(dragFlags,swipFlags);
            }

            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                int from=viewHolder.getAdapterPosition();
                int to=target.getAdapterPosition();
                Collections.swap(mPicList,from,to);
                recyclerView.getAdapter().notifyItemMoved(from,to);
                return true;
            }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                int position=viewHolder.getAdapterPosition();
                m.getAdapter().notifyItemRemoved(position);
                mPicList.remove(position);

            }
        });
        helper.attachToRecyclerView(m);

SS: 自定义ViewGroup实现滑动删除

1.自定义ViewGroup

public class MySlidingItemView extends ViewGroup {
    private View leftView;
    private View rightView;
    private ViewDragHelper mHelper;
    private ViewDragHelper.Callback callback=new ViewDragHelper.Callback() {
        @Override
        public boolean tryCaptureView(View child, int pointerId) {
            return true;
        }

        @Override
        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
            if(changedView==leftView){
                rightView.layout(rightView.getLeft()+dx,0,rightView.getRight()+dx,rightView.getBottom()+dy);
            }else if(changedView==rightView){
                leftView.layout(leftView.getLeft()+dx,0,leftView.getRight()+dx,leftView.getBottom()+dy);
            }
        }

        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {
            if(child==leftView){
                if(left>=0){
                    left=0;
                }else if(left<=-rightView.getMeasuredWidth()){
                    left=-rightView.getMeasuredWidth();
                }
            }else if(child==rightView){
                if(left<=leftView.getMeasuredWidth()-rightView.getMeasuredWidth()){
                    left=leftView.getMeasuredWidth()-rightView.getMeasuredWidth();
                }else if(left>=leftView.getMeasuredWidth()){
                    left=leftView.getMeasuredWidth();
                }
            }
            return left;
        }

        @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
            if(releasedChild==leftView){
                if(rightView.getLeft()<getMeasuredWidth()-rightView.getMeasuredWidth()/2){
                    mHelper.smoothSlideViewTo(rightView,getMeasuredWidth()-rightView.getMeasuredWidth(),0);
                    invalidate();
                }else{
                    mHelper.smoothSlideViewTo(rightView,getMeasuredWidth(),0);
                    invalidate();
                }
            }
        }

    };
    public MySlidingItemView(Context context) {
        this(context,null);
    }

    public MySlidingItemView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public MySlidingItemView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mHelper=ViewDragHelper.create(this,callback);
    }

    @Override
    public void computeScroll() {
        if(mHelper.continueSettling(true)){
            ViewCompat.postInvalidateOnAnimation(this);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        for(int i=0;i<getChildCount();i++){
            measureChild(getChildAt(i),widthMeasureSpec,heightMeasureSpec);
        }

    }

    @Override
    protected void onLayout(boolean b, int i, int i1, int i2, int i3) {
        leftView=getChildAt(0);
        rightView=getChildAt(1);
        leftView.layout(0,0,leftView.getMeasuredWidth(),leftView.getMeasuredHeight());
        rightView.layout(leftView.getMeasuredWidth(),0,leftView.getMeasuredWidth()+
                rightView.getMeasuredWidth(),rightView.getMeasuredHeight());

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mHelper.processTouchEvent(event);
        return true;
    }
}

2.item布局

<com.kangcreator.myapplication.MySlidingItemView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="80dp"
    xmlns:Tools="http://schemas.android.com/tools">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="80dp"
            android:orientation="horizontal">
                <ImageView
                    android:id="@+id/image"
                    android:layout_width="80dp"
                    android:layout_height="80dp"
                    android:scaleType="centerCrop"
                    Tools:src="@drawable/t13"/>

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_marginLeft="20dp"
                    android:gravity="bottom"
                    android:text="Hi.............................."
                    android:textColor="#36a11e"
                    android:textSize="30sp"/>
        </LinearLayout>
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
                <Button
                    android:id="@+id/del"
                    android:layout_width="100dp"
                    android:layout_height="80dp"
                    android:text="del"
                    android:textColor="#103c89"
                    android:textSize="30sp"/>
                <Button
                    android:layout_width="100dp"
                    android:layout_height="80dp"
                    android:text="del"
                    android:textColor="#103c89"
                    android:textSize="30sp"/>
        </LinearLayout>
</com.kangcreator.myapplication.MySlidingItemView>

3.Adapter

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>  {
    private  List<Pic> mPicList;
    private Context mContext;


    public MyAdapter(List<Pic> picList, Context context) {
        mPicList = picList;
        mContext=context;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v= LayoutInflater.from(mContext).inflate(R.layout.slidingview,parent,false);
        ViewHolder viewHolder=new ViewHolder(v);

        return viewHolder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        Pic pic=mPicList.get(position);
        holder.mImageView.setImageResource(pic.getId());
        holder.mDel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mPicList.remove(position);
                notifyDataSetChanged();
            }
        });


    }

    @Override
    public int getItemCount() {
        return mPicList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        private ImageView mImageView;
        private Button mDel;

        public ViewHolder(View itemView) {
            super(itemView);
            mImageView= itemView.findViewById(R.id.image);
            mDel=itemView.findViewById(R.id.del);

        }
    }
}

4.MainActivity

public class MainActivity extends AppCompatActivity {
    private List<Pic> mPicList=new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final  RecyclerView m=findViewById(R.id.recyclerview);
        Pic pic=new Pic(R.drawable.t0);
        mPicList.add(pic);
        pic=new Pic(R.drawable.t1);
        mPicList.add(pic);
        pic=new Pic(R.drawable.t2);
        mPicList.add(pic);
        pic=new Pic(R.drawable.t4);
        mPicList.add(pic);
        pic=new Pic(R.drawable.t6);
        mPicList.add(pic);
        pic=new Pic(R.drawable.t9);
        mPicList.add(pic);
        pic=new Pic(R.drawable.t10);
        mPicList.add(pic);
        pic=new Pic(R.drawable.t13);
        mPicList.add(pic);
        pic=new Pic(R.drawable.t14);
        mPicList.add(pic);
        RecyclerView.LayoutManager layoutManager=new LinearLayoutManager(this);
        m.setLayoutManager(layoutManager);
        m.setAdapter(new MyAdapter(mPicList,this));
//        m.setOndelListener(new MyRecyclerView.OnDelActivatedListener() {
//            @Override
//            public void ondel(int position) {
//                m.getAdapter().notifyItemRemoved(position);
//                mPicList.remove(position);
//                m.getAdapter().notifyItemRangeChanged(position,mPicList.size());
//            }
//        });
        final ItemTouchHelper helper=new ItemTouchHelper(new ItemTouchHelper.Callback() {
            @Override
            public boolean isLongPressDragEnabled() {
                return true;
            }

            @Override
            public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
                super.onSelectedChanged(viewHolder, actionState);
            }

            @Override
            public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
                int dragFlags=ItemTouchHelper.UP|ItemTouchHelper.DOWN;
              //  int swipFlags=ItemTouchHelper.END|ItemTouchHelper.START;
                return makeMovementFlags(dragFlags,0);
            }

            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                int from=viewHolder.getAdapterPosition();
                int to=target.getAdapterPosition();
                Collections.swap(mPicList,from,to);
                recyclerView.getAdapter().notifyItemMoved(from,to);
                return true;
            }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
//                int position=viewHolder.getAdapterPosition();
//                m.getAdapter().notifyItemRemoved(position);
//                mPicList.remove(position);

            }
        });
        helper.attachToRecyclerView(m);
    }
}

XXX:

 @Override  
    public boolean onTouchEvent(MotionEvent e) {  
        switch (e.getAction()) {  
            case MotionEvent.ACTION_DOWN:  
                if(mItemLayout==null ||mItemLayout.getScrollX()!=0){  
                    return true;  
                }  
                break;  
        }  
        return super.onTouchEvent(e);  
    }  

    @Override  
    public boolean onInterceptTouchEvent(MotionEvent e) {  
        mVelocityTracker.addMovement(e);  

        int x = (int) e.getX();  
        int y = (int) e.getY();  
        switch (e.getAction()) {  
            case MotionEvent.ACTION_DOWN:  
                getParent().requestDisallowInterceptTouchEvent(isItemMoving);  
                if (mDeleteBtnState == 0) {  
                    View view = findChildViewUnder(x, y);  
                    if (view == null) {  
                        return false;  
                    }  

                    ViewHolder viewHolder = getChildViewHolder(view);  

                    mItemLayout = viewHolder.itemView;  
                    mItemLayout.setClickable(true);  
                    mPosition = viewHolder.getAdapterPosition();  

                    mDelete = (TextView) mItemLayout.findViewById(item_delete);  
                    mMaxLength = mDelete.getWidth();  
                    mDelete.setOnClickListener(v -> {  
                        mListener.onItemClick(v,mPosition);  
                        mItemLayout.scrollTo(0, 0);  
                        mDeleteBtnState = 0;  
                    });  
                } else if (mDeleteBtnState == 3){  
                    mScroller.startScroll(mItemLayout.getScrollX(), 0, -mMaxLength, 0, 200);  
                    invalidate();  
                    mDeleteBtnState = 0;  
                    return false;  
                }else{  
                    return false;  
                }  

                break;  
            case MotionEvent.ACTION_MOVE:  

                int dx = mLastX - x;  
                int dy = mLastY - y;  

                if(dy<80 && x>=mItemLayout.getWidth()/2 || mItemLayout.getScrollX()>0){  
                    isItemMoving=true;  
                    int scrollX = mItemLayout.getScrollX();  
                    if (Math.abs(dx) > Math.abs(dy)) {//左边界检测  
                        if (scrollX + dx <= 0) {  
                            mItemLayout.scrollTo(0, 0);  
                            return true;  
                        } else if (scrollX + dx >= mMaxLength) {//右边界检测  
                            mItemLayout.scrollTo(mMaxLength, 0);  
                            return true;  
                        }  
                        mItemLayout.scrollBy(dx, 0);//item跟随手指滑动  
                    }  
                }else{  
                    isItemMoving=false;  
                }  
                getParent().requestDisallowInterceptTouchEvent(isItemMoving);  
               return false;  
            case MotionEvent.ACTION_UP:  

                mVelocityTracker.computeCurrentVelocity(1000);//计算手指滑动的速度  
                float xVelocity = mVelocityTracker.getXVelocity();//水平方向速度(向左为负)  
                float yVelocity = mVelocityTracker.getYVelocity();//垂直方向速度  

                int deltaX = 0;  
                int upScrollX = mItemLayout.getScrollX();  

                if (Math.abs(xVelocity) > 100 && Math.abs(xVelocity) > Math.abs(yVelocity)) {  
                    if (xVelocity <= -100) {//左滑速度大于100,则删除按钮显示  
                        deltaX = mMaxLength - upScrollX;  
                        mDeleteBtnState = 2;  
                    } else if (xVelocity > 100) {//右滑速度大于100,则删除按钮隐藏  
                        deltaX = -upScrollX;  
                        mDeleteBtnState = 1;  
                    }  
                } else {  
                    if (upScrollX >= mMaxLength / 2) {//item的左滑动距离大于删除按钮宽度的一半,则则显示删除按钮  
                        deltaX = mMaxLength - upScrollX;  
                        mDeleteBtnState = 2;  
                    } else if (upScrollX < mMaxLength / 2) {//否则隐藏  
                        deltaX = -upScrollX;  
                        mDeleteBtnState = 1;  
                    }  
                }  

                //item自动滑动到指定位置  
                mScroller.startScroll(upScrollX, 0, deltaX, 0, 200);  
                isStartScroll = true;  
                getParent().requestDisallowInterceptTouchEvent(false);  

                mVelocityTracker.clear();  
                break;  
        }  

        mLastX = x;  
        mLastY = y;  
        return super.onInterceptTouchEvent(e);  
    }  

    @Override  
    public void computeScroll() {  
        if (mScroller.computeScrollOffset()) {  
            mItemLayout.scrollTo(mScroller.getCurrX(), mScroller.getCurrY());  
            invalidate();  
        } else if (isStartScroll) {  
            isStartScroll = false;  
            if (mDeleteBtnState == 1) {  
                mDeleteBtnState = 0;  
            }  

            if (mDeleteBtnState == 2) {  
                mDeleteBtnState = 3;  
            }  
        }  
    }  

    @Override  
    protected void onDetachedFromWindow() {  
        mVelocityTracker.recycle();  
        super.onDetachedFromWindow();  
    }  

    @Override  
    public void onScrollStateChanged(int state) {  
        super.onScrollStateChanged(state);  
        isDragging = state == SCROLL_STATE_DRAGGING;  
    }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值