效果:
触摸:按下,移动,抬起
点击:一组触摸事件的组合(按下,松开)
长按:一组触摸事件的组合(按下,持续超过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时:
当onTouch返回true时:
不在响应点击事件了
我们的需求是,在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)
时间: 2024-10-12 02:38:22