控制View的OnClick OnTouch来实现LsitView的Item的侧滑出现删除
2015-05-04 21:06 阅读(190)

效果: 

154527pbdt4w1keahqdwhh.jpg

触摸:按下,移动,抬起 
点击:一组触摸事件的组合(按下,松开) 
长按:一组触摸事件的组合(按下,持续超过500ms(Android中))

为一个View设置点击事件:

view.setOnClickListener(new OnClickListener() {             
    @Override
   public void onClick(View v) {
     Log.i("", "onClick");
   }
});

为一个View设置touch事件:

view.setOnTouchListener(new OnTouchListener() {            
    @Override
    public boolean onTouch(View v, MotionEvent event) {
 
                switch (event.getAction()) {
 
                    case MotionEvent.ACTION_DOWN:
                        Log.i("", "ACTION_DOWN");
                        break;
 
                    case MotionEvent.ACTION_MOVE:
                        Log.i("", "ACTION_MOVE");
                        break;
 
                    case MotionEvent.ACTION_CANCEL:
                    case MotionEvent.ACTION_UP:
                        Log.i("", "ACTION_UP");
                        break;
                }           
                return false;
            }
        });

当同时为一个View设置点击和touch事件时:

在onTouch返回false时: 

20150320202716541.jpg

当onTouch返回true时: 

20150320202702783.jpg

不在响应点击事件了

我们的需求是,在item关闭时可以响应点击事件(onTouch中返回false),在item打开时不响应点击事件(onTouch中返回true)

下面处理Touch事件:

ACTION_DOWN: 记录下手指按下的位置 
ACTION_MOVE: 判断移动的距离(带正负号)移动item
ACTION_UP:根据手指抬起位置,将视图移动到合适的位置

listView 的 item 的布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout"
    android:layout_width="match_parent"
    android:layout_height="86dp"
    android:layout_below="@+id/Listview" >
 
    <TextView
        android:id="@+id/more"
        android:layout_width="60dp"
        android:layout_height="match_parent"
        android:layout_toLeftOf="@+id/delete"
        android:background="@android:color/darker_gray"
        android:clickable="true"
        android:gravity="center"
        android:onClick="more"
        android:text="更多"
        android:textColor="@android:color/white"
        android:textSize="16sp" />
 
    <TextView
        android:id="@+id/delete"
        android:layout_width="60dp"
        android:layout_height="match_parent"
        android:layout_alignParentRight="true"
        android:background="@android:color/holo_red_light"
        android:clickable="true"
        android:gravity="center"
        android:onClick="delete"
        android:text="删除"
        android:textColor="@android:color/white"
        android:textSize="16sp" />
 
    <TextView
        android:id="@+id/tv_top"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/holo_orange_dark"
        android:gravity="center"
        android:text="item"
        android:textSize="20sp" />
 
</RelativeLayout>

自定义的View

package com.zyh.slideview;
 
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
 
public class MoveLayout extends RelativeLayout implements OnClickListener {
 
    private Context context;
    private int downX;
    private TextView tv_top;
    private TextView delete;
    private TextView more;
 
    public MoveLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }
 
    public MoveLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
 
    public MoveLayout(Context context) {
        this(context, null);
    }
 
    private void init(Context context) {
        this.context = context;
        LayoutInflater.from(context).inflate(R.layout.move_layout, this, true);
        delete = (TextView) findViewById(R.id.delete);
        more = (TextView) findViewById(R.id.more);
        tv_top = (TextView) findViewById(R.id.tv_top);
        tv_top.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return handlerTouch(v, event);
            }
        });
        tv_top.setOnClickListener(this);
        more.setOnClickListener(this);
        delete.setOnClickListener(this);
    }
 
    /* ---------------------处理 Touch-------------------------- */
    boolean result = false;
    boolean isOpen = false;
 
    protected boolean handlerTouch(View v, MotionEvent event) {
 
        int bottomWidth = delete.getWidth() + delete.getWidth();
 
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // Log.i("", "ACTION_DOWN");
                downX = (int) event.getRawX();
                break;
            case MotionEvent.ACTION_MOVE:
                // Log.i("", "ACTION_MOVE");
                // if (isAniming)
                // break;
                int dx = (int) (event.getRawX() - downX);
                // Log.i("", "dy___" + dx);
                if (isOpen) {
                    // 打开状态
                    // 向右滑动
                    if (dx > 0 && dx < bottomWidth) {
                        v.setTranslationX(dx - bottomWidth);
                        // 允许移动,阻止点击
                        result = true;
                    }
                } else {
                    // 闭合状态
                    // 向左移动
                    if (dx < 0 && Math.abs(dx) < bottomWidth) {
                        v.setTranslationX(dx);
                        // 允许移动,阻止点击
                        result = true;
                    }
                }
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
 
                // Log.i("", "ACTION_UP" + v.getTranslationX());
 
                // 获取已经移动的
                float ddx = v.getTranslationX();
 
                // 判断打开还是关闭
 
                if (ddx <= 0 && ddx > -(bottomWidth / 2)) {
                    // 关闭
                    ObjectAnimator oa1 = ObjectAnimator.ofFloat(v, "translationX", ddx, 0).setDuration(100);
                    oa1.start();
                    oa1.addListener(new AnimatorListener() {
                        @Override
                        public void onAnimationStart(Animator animation) {
                        }
 
                        @Override
                        public void onAnimationRepeat(Animator animation) {
                        }
 
                        @Override
                        public void onAnimationEnd(Animator animation) {
                            isOpen = false;
                            result = false;
                        }
 
                        @Override
                        public void onAnimationCancel(Animator animation) {
                            isOpen = false;
                            result = false;
                        }
                    });
 
                }
                if (ddx <= -(bottomWidth / 2) && ddx > -bottomWidth) {
                    // 打开
                    ObjectAnimator oa1 = ObjectAnimator.ofFloat(v, "translationX", ddx, -bottomWidth)
                            .setDuration(100);
                    oa1.start();
                    result = true;
                    isOpen = true;
                }
                break;
        }
        return result;
    }
 
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tv_top:
                Toast.makeText(context, "item", 0).show();
                break;
            case R.id.more:
                Toast.makeText(context, "more", 0).show();
                break;
            case R.id.delete:
                Toast.makeText(context, "delete", 0).show();
                break;
        }
    }
}

源代码:github](https://github.com/18236887539/SlideLayout)