Android自定义View之(下拉刷新+侧滑删除)

以前项目中用到了一个放qq的侧滑删除的效果,结果github上一搜就copy了一个,不得不说大神们写的真心牛逼,那个时候呢看到一个东西能用就可以了,也不管怎么实现的,现在反过来一看,原来自定义还可以这么玩,当然,前面项目中也因此出现了一个bug,就是我使用的是PulltorefreshScrollView,因此也出现了ScrollView跟ListView的事件冲突,呵呵,不怕笑话,当是体验不好,直接变成了长按删除了,嘻嘻!!自从前面研究了一下事件分发,因此解决了困扰了我很久的问题。

看一下侧滑删除效果图:
这里写图片描述

copy github上的pulltorefresh下拉刷新效果图:
这里写图片描述

不同的侧滑效果:
这里写图片描述

我们简单看一下大神的SwipeMenu实现方式:
1、SwipeMenuListView继承ListView。

public class SwipeMenuListView extends ListView {

2、重写setAdapter方法,然后创建一个SwipeMenuLayout包含我们自己adapter中getView返回的View跟我们的侧滑菜单。

@Override
    public void setAdapter(ListAdapter adapter) {
        super.setAdapter(new SwipeMenuAdapter(getContext(), adapter) {
            @Override
            public void createMenu(SwipeMenu menu) {
                if (mMenuCreator != null) {
                    mMenuCreator.create(menu);
                    Log.e("TAG", "---createMenu--");
                }
            }

            @Override
            public void onItemClick(SwipeMenuView view, SwipeMenu menu,
                    int index) {
                if (mOnMenuItemClickListener != null) {
                    mOnMenuItemClickListener.onMenuItemClick(
                            view.getPosition(), menu, index);
                }
                if (mTouchView != null) {
                    mTouchView.smoothCloseMenu();
                }
            }
        });
    }

SwipeMenuAdapter的方法可以看到,new了一个SwipeMenuLayout(FrameLayout)然后把我们的contentView跟swipeMenu放在一起了,

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        SwipeMenuLayout layout = null;
        if (convertView == null) {
            View contentView = mAdapter.getView(position, convertView, parent);
            SwipeMenu menu = new SwipeMenu(mContext);
            menu.setViewType(mAdapter.getItemViewType(position));
            createMenu(menu);
            SwipeMenuView menuView = new SwipeMenuView(menu,
                    (SwipeMenuListView) parent);
            menuView.setOnSwipeItemClickListener(this);
            SwipeMenuListView listView = (SwipeMenuListView) parent;
            layout = new SwipeMenuLayout(contentView, menuView,
                    listView.getCloseInterpolator(),
                    listView.getOpenInterpolator());
            layout.setPosition(position);
        } else {
            layout = (SwipeMenuLayout) convertView;
            layout.closeMenu();
            layout.setPosition(position);
            View view = mAdapter.getView(position, layout.getContentView(),
                    parent);
        }
        return layout;
    }

3、也是最重要的一步:就是监听ListView的事件,处理SwipeMenuLayout的子控件(contentView+menu)的摆放位置,从而显示menu跟隐藏menu

大致实现思路就是这样了的,代码太多我就不一一列出了,下面我会给出demo的下载地址,我相信大家自己是能够看懂的。因为我用的是PullToRefreshScrollView,也就是把侧滑删除ListView放在了ScrollView中,解决事件冲突:

思路:重写dispatchTouchEvent方法,通过判断滑动的距离来定义是否需要拦截掉和不拦截事件,从而解决事件冲突。一般都是放在父类中的onintecerpterTouchEvent方法中去实现,今天我们用另外一种方式,通过父类的requestDisallowInterceptTouchEvent(boolean flag);方法决定父类是否需要拦截子控件事件。

/**
     * 处理ScrollerView嵌套ListView引发的事件冲突
     */
    private int mLastY;
    private int mLastX;
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        int action=ev.getAction();
        switch(action){
            case MotionEvent.ACTION_DOWN:
                mLastX=(int) ev.getX();
                mLastY=(int) ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                int duraX=Math.abs((int) (ev.getX()-mLastX));
                int duraY=Math.abs((int) (ev.getY()-mLastY));
                if((duraX>10&&duraY<40)||(mTouchState == TOUCH_STATE_X)){
                    /**
                     * 当x轴距离为>10并且y轴滑动距离<40的时候,认为是侧滑删除操作,父控件不拦截子控件的事件
                     */
                    this.getParent().requestDisallowInterceptTouchEvent(true);
                }else{
                    /**
                     * 拦截子控件的事件,交给父控件处理
                     */
                    this.getParent().requestDisallowInterceptTouchEvent(false);
                }
                mLastX=(int) ev.getX();
                mLastY=(int) ev.getY();
                break;

        }
        return super.dispatchTouchEvent(ev);
    }

对事件传递不是很熟悉的童鞋,也可以看看我前面写的两篇博客Android事件传递

是不是很简单哦,反正我是照着demo自己敲了很多遍,至少我觉得我收获挺多的。嘻嘻嘻~!!
最后附上我demo的链接地址:
https://github.com/913453448/SwipeMenuDemo.git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值