美文网首页
Android 实现QQ侧滑删除效果

Android 实现QQ侧滑删除效果

作者: 因为我的心 | 来源:发表于2020-06-21 10:05 被阅读0次

    一、前言:

    分析: Android中什么组件自带了水平滑动? 我首当其冲就想到HorizontalScrollView。既然是简单实现,那我们何方不继承一下HorizontalScrollView呢?

    接下来我们将HorizontalScrollView分成ItemView + 抽屉部分。

    我们只需要监听用户的滑动事件,当用户滑动超过指定距离时,就移动HorizontalScrollView,将隐藏的“抽屉部分”显示出来,当用户做相反的滑动时,隐藏“抽屉部分”即可。

    gitee地址:https://gitee.com/luoyanyong/SlidingDeleteDemo

    效果图:


    图片.png

    二、实现:

    1、依赖:

      //recyclerview使用
        implementation 'androidx.recyclerview:recyclerview:1.0.0'
    //  implementation 'com.android.support:recyclerview-v7:29.0.0'
        //BRVAH使用
        implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.47'
        //万能插件
        implementation 'com.blankj:utilcodex:1.25.2'
    

    2、 自定义SlidingDeleteView

    /**
     * 滑动删除widget
     *
     * @author Junhui
     */
    
    public class SlidingDeleteView extends HorizontalScrollView {
        private static final String TAG = "SlidingDeleteView";
    
        /**
         * 抽屉视图(注意:recyclerview/listview中不能使用button,button会抢夺焦点) - 父件
         */
        private LinearLayout slidingParent;
        /**
         * 是否开启滑动抽屉
         */
        public boolean isEnable = true;
        /**
         * 抽屉视图是否可见
         */
        public boolean deleteViewVisibile = false;
    
        private boolean isFirst = true;
        //监听器
        private OnDeleteViewStateChangedListener onStateChangedListener;
    
        /**
         * 抽屉视图状态变化回调接口
         */
        public interface OnDeleteViewStateChangedListener {
            void onVisibile();
    
            void onGone();
    
            void onDownOrMove();
        }
    
        public SlidingDeleteView(Context context) {
            this(context, null);
        }
    
        public SlidingDeleteView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public SlidingDeleteView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            if (isFirst) {
                init();
                isFirst = false;
            }
        }
    
        private void init() {
            slidingParent = (LinearLayout) findViewById(R.id.lay_sliding);
        }
    
        public void setOnDeleteViewStateChangedListener(OnDeleteViewStateChangedListener onStateChangedListener) {
            this.onStateChangedListener = onStateChangedListener;
        }
    
        public boolean isEnable() {
            return isEnable;
        }
    
        public void setEnable(boolean enable) {
            isEnable = enable;
        }
    
        @Override
        protected void onScrollChanged(int l, int t, int oldl, int oldt) {
            super.onScrollChanged(l, t, oldl, oldt);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent ev) {
            int action = ev.getAction();
            switch (action) {
                case MotionEvent.ACTION_MOVE:
                    if (!isEnable) {
                        return false;
                    }
                case MotionEvent.ACTION_DOWN:
                    if (onStateChangedListener != null) {
                        onStateChangedListener.onDownOrMove();
                    }
                    break;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    measureScrollX();
                    return true;
                default:
                    break;
            }
            return super.onTouchEvent(ev);
        }
    
        /**
         * 计算X轴滑动距离,并做出相应操作
         */
        private void measureScrollX() {
            if (getScrollX() < slidingParent.getWidth() / 3) {
                //TODO 当滑动距离小于 抽屉视图宽度 * 1/3 时,隐藏删除视图
                setDeleteViewGone();
            } else {
                setDeleteViewVisibile();
            }
        }
    
        /**
         * 隐藏滑动布局
         */
        public void setDeleteViewGone() {
            deleteViewVisibile = false;
            this.smoothScrollTo(0, 0);
            if (onStateChangedListener != null) {
                onStateChangedListener.onGone();
            }
        }
        /**
         * 显示滑动布局
         */
        public void setDeleteViewVisibile() {
            Log.d(TAG, "抽屉的固定宽度为 == " + slidingParent.getWidth());
            deleteViewVisibile = true;
            this.smoothScrollTo(slidingParent.getWidth(), 0);
    
            if (onStateChangedListener != null) {
                onStateChangedListener.onVisibile();
            }
        }
    
    }
    

    2、 MainActivity

    public class MainActivity extends AppCompatActivity {
    
        RecyclerView rv_list;
        private List<LoginBean>  list = new ArrayList<>();
        private  MyListAdapter myListAdapter;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            rv_list = (RecyclerView) findViewById(R.id.rv_list);
            init();
        }
        /**
         * 初始化数据
         */
        private void init() {
    
            try {
                for (int i=1;i<21;i++){
                    list.add(new LoginBean("第"+i+"条数据"));
                }
                if (myListAdapter==null){
                    rv_list.setLayoutManager(new LinearLayoutManager(this));
                    rv_list.addItemDecoration(new DividerItemDecoration(this, LinearLayout.VERTICAL));
                    myListAdapter = new MyListAdapter(R.layout.sample_slidingview,list);
                    rv_list.setAdapter(myListAdapter);
                }else {
                    myListAdapter.notifyDataSetChanged();
                }
    
                myListAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
                    @Override
                    public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
                        switch (view.getId()){
                            case R.id.tv_delete:
                                list.remove(position);
                                myListAdapter.notifyDataSetChanged();
                                Log.d("LUO","===删除==");
                                break;
                            case R.id.tv_cancel:
                               // SlidingDeleteView  slidingDeleteView = (SlidingDeleteView) adapter.getViewByPosition(rv_list, position, R.id.slidingview);
                                //slidingDeleteView.setDeleteViewGone();
                               // myListAdapter.notifyItemChanged(position);
                                myListAdapter.notifyDataSetChanged();
                                Log.d("LUO","===隐藏==");
                                break;
                            default:
                                break;
                        }
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    3、MyListAdapter 类

    public class MyListAdapter extends BaseQuickAdapter<LoginBean, BaseViewHolder> {
        public MyListAdapter(int layoutResId, List<LoginBean> data) {
            super(layoutResId, data);
        }
    
        @Override
        protected void convert(BaseViewHolder helper, LoginBean item) {
            //TODO 这里需要重新计算 item - containerView的宽度,否则containerView会显示错误(重要)
            LinearLayout containerView = helper.getView(R.id.lay_container);
            final SlidingDeleteView slidingDeleteView = helper.getView(R.id.slidingview);
            TextView tv_key = helper.getView(R.id.tv_key);
            TextView tv_cancel = helper.getView(R.id.tv_cancel);
            TextView tv_delete = helper.getView(R.id.tv_delete);
    
            containerView.getLayoutParams().width = ScreenUtils.getScreenWidth();
            slidingDeleteView.setEnable(true);
            //默认隐藏
            slidingDeleteView.setDeleteViewGone();
    
            tv_key.setText(item.getName());
            slidingDeleteView.setOnDeleteViewStateChangedListener(new SlidingDeleteView.OnDeleteViewStateChangedListener() {
                @Override
                public void onVisibile() {
                    Log.d("LUO", "显示抽屉视图");
                }
    
                @Override
                public void onGone() {
                    Log.d("LUO", "隐藏抽屉视图");
                }
    
                @Override
                public void onDownOrMove() {
    
                }
            });
            
            //添加点击事件
            helper.addOnClickListener(R.id.tv_key);
            helper.addOnClickListener(R.id.tv_cancel);
            helper.addOnClickListener(R.id.tv_delete);
    
        }
    }
    

    相关文章

      网友评论

          本文标题:Android 实现QQ侧滑删除效果

          本文链接:https://www.haomeiwen.com/subject/jryoxktx.html