您的位置:首页 > 其它

ExpandableListView侧滑删除

2017-06-21 14:24 162 查看
ExpandableListView 侧滑删除

最近工作上有个需求,类似于QQ的折叠效果,当然这种我们首先想到的就是 ExpandableListView 这个控件,但是在使用的过程中,用户提出了新的需求,需要增加侧滑删除功能,怎么办呢,网上我也看了一些其他处理方案,但效果不是很理想,最后在同事的帮助下通过HorizontalScrollView 实现

1. ExpandableListView的itme布局文件有两个,分别是组item,和子item,这儿通过子item进行侧滑处理,首先看布局文件

<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scrollView_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants"
android:overScrollMode="never"
android:scrollbars="none">

<LinearLayout
android:id="@+id/ll_group_control"
android:layout_width="wrap_content"
android:layout_height="@dimen/activity_item_margin"
android:orientation="horizontal">

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/activity_item_margin"
android:background="@mipmap/background_device_one"
android:orientation="horizontal">

<ImageView
android:id="@+id/iv_linajie"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/margin_size_10"
android:src="@mipmap/lianjie"/>

<TextView
android:id="@+id/child_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="5dp"
android:layout_toRightOf="@id/iv_linajie"
android:text="这是子item"
android:textColor="@color/write"
android:textSize="@dimen/margin_size_20"/>

</RelativeLayout>

<RelativeLayout
android:id="@+id/img_delete"
android:layout_width="70dp"
android:layout_height="match_parent"
android:background="@mipmap/delete_diban">

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@mipmap/jianhao"/>

</RelativeLayout>

</LinearLayout>

</HorizontalScrollView>




2. 首先我们定义几个接口

public interface OnAddDeviceListener {

//点击事件
void OnChildClick(int groupPosition, int childPosition);
//侧滑删除事件
void OnChildDel(int groupPosition, int childPosition);
//长按事件
void OnChildLongClick(int groupPosition, int childPosition);

}

public void setOnAddDeviceListener(OnAddDeviceListener l) {
this.listener = l;

}

private OnAddDeviceListener listener;


这儿肯定有好多疑问,按理来说定义一个侧滑回调完全足够了,为什么还这么麻烦定义点击和长按事件呢,这儿指出一个问题,那就是在通过HorizontalScrollView处理侧滑事件的时候,会覆写他的onTouch事件,导致控件本身的点击事件失效,所以此处我们需要自己定义这几个事件

适配器中处理,省略其他代码,直接处理和子类有关的getChildView方法,如下

//  获得子项显示的view
@Override
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View view, ViewGroup parent) {
if (view == null) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.child_item, null);
}
view.setTag(R.layout.parent_item, groupPosition);
view.setTag(R.layout.child_item, childPosition);

//这儿初始化HorizontalScrollView控件,设置TAG标签为groupPosition+childPosition,原因是为了后面的数据回调中传参
HorizontalScrollView scrollView_item = (HorizontalScrollView) view.findViewById(R.id.scrollView_item);
scrollView_item.setTag(groupPosition + "_" + childPosition);

//这当然是我们的侧滑删除事件了
RelativeLayout img_delete = (RelativeLayout) view.findViewById(R.id.img_delete);
img_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

if (listener != null)
listener.OnChildDel(groupPosition, childPosition);
}
});
scrollView_item.setOnTouchListener(new OnTouchListener() {
private float startX = 0;

@Override
public boolean onTouch(View v, MotionEvent event) {

int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 如果有划出删除按钮的itemView,就让他滑回去并且锁定本次touch操作,解锁会在父组件的dispatchTouchEvent中进行
if (mScrollView != null) {
scrollView(mScrollView, HorizontalScrollView.FOCUS_LEFT);
mScrollView = null;
mLockOnTouch = true;
return true;
}
startX = event.getX();

//按下去,默认开始长按事件

mLastMotionX = x;
mLastMotionY = y;
isMoved = false;
//开启线程进行事件监听,也就是定时器的效果
handler.postDelayed(mLongPressRunnable, ViewConfiguration.getLongPressTimeout());
tag = (String) v.getTag();

break;
case  MotionEvent.ACTION_MOVE:

if (isMoved) break;
//检测按下状态是否发生移动,如果超出限制释放长按事件线程
if (Math.abs(mLastMotionX - x) > TOUCH_SLOP
|| Math.abs(mLastMotionY - y) > TOUCH_SLOP_Y) {
//移动超过阈值,则表示移动了
isMoved = true;
handler.removeCallbacks(mLongPressRunnable);
iskey = true;
}

break;
case MotionEvent.ACTION_UP:
HorizontalScrollView view = (HorizontalScrollView) v;
//获取松开时的横向坐标坐标,
// 向左滑动100个像素,弹出删除按钮
if (startX > event.getX() + 100) {
startX = 0;// 因为公用一个事件处理对象,防止错乱,还原startX值
//调用滑动方法,向右移
scrollView(view, HorizontalScrollView.FOCUS_RIGHT);
mScrollView = view;
//                        return true;
} else {
//恢复item状态
if (Math.abs(event.getX()-startX)!=0) {
scrollView(view, HorizontalScrollView.FOCUS_LEFT);
}else{
//点击事件,iskey为false时候标识长按事件
if (listener != null && iskey) {
String TAG = (String) v.getTag();
String[] tags = TAG.split("_");
listener.OnChildClick(Integer.valueOf(tags[0]), Integer.valueOf(tags[1]));
}

}
}
//当然,抬起之后需要取消掉长按事件的状态
handler.removeCallbacks(mLongPressRunnable);
iskey = true;

break;
}
return false;

}
});

return view;
}


定时线程以及变量如下

//记录坐标信息
private int mLastMotionX, mLastMotionY;
//是否移动了
private boolean isMoved;
//长按的runnable
private Runnable mLongPressRunnable;
//移动的阈值
private final int TOUCH_SLOP = 20;
//Y轴移动阀值
private final int TOUCH_SLOP_Y = 4;
//区分点击事件和长按事件
private boolean iskey = true;
private String tag;

//长按的runnable
private Runnable mLongPressRunnable = new Runnable() {

@Override
public void run() {

handler.sendMessage(new Message());
iskey = false;
}
};


回调handle中处理事件的回调功能

Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);

try {
String[] tags = tag.split("_");
if (listener != null) {
if (tags.length == 2) {
//item长按事件
listener.OnChildLongClick(Integer.valueOf(tags[0]), Integer.valueOf(tags[1]));
}
}
} catch (NumberFormatException e) {
e.printStackTrace();
}

}
};


如果有需要可以直接把onTouch写在自定义控件HorizontalScrollView中,提高代码的简洁程度,至此功能结束,添加了长按事件,侧滑删除和点击事件,组item同样可以添加侧滑,原理一样
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息