[Android]模仿QQ在listview上滑动出现删除键

基于前人的经验改善而来。

资料连接:  

仿 QQ消息列表的滑动出现 删除按钮   

http://www.eoeandroid.com/thread-313964-1-1.html  

android listView滑动删除  

http://my.eoe.cn/jiaxiaoya/archive/20879.html

 第二种实现的工程
  https://github.com/axlecho/moli_blog_qqdel


listview响应ontouch事件主要有两种方法,一种是重载Adapter里的getView,给每个item加ontouchlistener。由于经常获取不到ACTION_UP事件(与listview的手势事件有关),经常出现无法按下之后无法释放的情况。而且在item的clickenvent体验不好。
另外一种是直接在view或activity中监听ontouchevent,这样既不用修改Adapter ,效果也比较好。
比较少提及的是animation的实现,一般都是直接View.VISIBLE和View.INVISIBLE。 要做到跟qq那样的效果,至少要两层动画,一层遮罩,一层按钮。显示的时候按钮直接显示,遮罩scale变小。就可以作出从左到右按钮出现的效果。

第一种的实现

private class ListAdapter extends BaseAdapter {

    @Override
    public int getCount() {
        return listDatas.size();
    }

    @Override
        public Object getItem(int pos) {
        return listDatas.get(pos);
    }

    @Override
    public long getItemId(int pos) {
        return 0;
    }

    @Override
    public View getView(final int pos, View convertView, ViewGroup parent) {
        View view = getLayoutInflater().inflate(R.layout.list_item_view, null);
        TextView textView = (TextView) view.findViewById(R.id.text);
        textView.setText(listDatas.get(pos));
        view.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent me) {
                switch (me.getAction()) {
                case MotionEvent.ACTION_MOVE:break;
    
                case MotionEvent.ACTION_DOWN:
                    v.setBackgroundColor(Color.CYAN); //模拟按下效果
                    downX = me.getX();
                    break;

                case MotionEvent.ACTION_UP:
                    upX = me.getX();
                    v.setBackgroundColor(Color.TRANSPARENT);
                    if (Math.abs(upX - downX) > 20) {
                        //滑动事件的响应
                    } else {
                        //点击事件的调用,记住这个pos必须是getview的参数,
                        //必须为final,可能是跟调用闭包有关
                        //手动调用列表的点击操作。
                    listView.performItemClick(v, pos, listView.getItemIdAtPosition(pos));  
                    }
                    break;

                default:break;
                }
                return true;
            }
        });
        return view;
    }
}

第二种的实现

private class ListViewEx extends ListView implements OnTouchListener {  
    private int pointX = -1;
    private int pointY = -1;
    private int position = -1;
    private int endX = -1;
    private int endY = -1;
    private int newpos = -1;
    private Button curDel_btn;
    private TextView curMask;
    private Context parentContext;


    public ListViewEx(Context context) {
        super(context);
        setOnTouchListener(this);
        parentContext = context;
    }


    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // 手指按下,计算焦点位于ListView的那个条目
                pointX = (int) event.getX();
                pointY = (int) event.getY();
                position = listView.pointToPosition(pointX, pointY);
                if (curDel_btn != null) {
                    curDel_btn.setVisibility(View.GONE);
                }

                if (curMask != null) {
                    curMask.setVisibility(View.GONE);
                }
            break;

            case MotionEvent.ACTION_MOVE:break;

            case MotionEvent.ACTION_UP:
                endX = (int) event.getX();
                endY = (int) event.getY();
                newpos = listView.pointToPosition(endX, endY);
                // 原本想着加上这个条件(newpos==position)是不是更精确些,
                // 经过实践发现,其实我们在滑动listView的列表的时候有时候更渴望有滑动就ok
                // 只允许从右向左滑
                if (endX - pointX < -50) {
                // 获取到ListView第一个可见条目的position
                    int firstVisiblePosition = listView.getFirstVisiblePosition();
                    View view = listView.getChildAt(position - firstVisiblePosition);
                    if (view == null)break;
                    Button delbtn = (Button) view.findViewById(R.id.btn_del);
                    TextView delbtnMask = (TextView) view.findViewById(R.id.btn_del_mask);
                    TextView bottomMask = (TextView) view.findViewById(R.id.bottom_mask);
                    
                    //加载动画
                    bottomMask.setVisibility(View.VISIBLE);
                    delbtn.setVisibility(View.VISIBLE);
                    delbtnMask.setVisibility(View.VISIBLE);
                    delbtnMask.startAnimation(AnimationUtils.loadAnimation(parentContext,
                        R.anim.delete_show));                                   
                    delbtnMask.setVisibility(View.INVISIBLE);

                    curDel_btn = delbtn;
                    curMask = bottomMask;
                    delbtn.setOnClickListener(new View.OnClickListener() {

                        @Override
                        public void onClick(View v) {
                            deleteRecord(listDatas.get(position));
                            listDatas.remove(position);
                            adapter.notifyDataSetChanged();
                        }
                    });
                }
                break;
                default:break;
            }
        return false;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值