ExpandableListView侧滑删除
2017-06-21 14:24
162 查看
ExpandableListView 侧滑删除
最近工作上有个需求,类似于QQ的折叠效果,当然这种我们首先想到的就是 ExpandableListView 这个控件,但是在使用的过程中,用户提出了新的需求,需要增加侧滑删除功能,怎么办呢,网上我也看了一些其他处理方案,但效果不是很理想,最后在同事的帮助下通过HorizontalScrollView 实现
1. ExpandableListView的itme布局文件有两个,分别是组item,和子item,这儿通过子item进行侧滑处理,首先看布局文件
2. 首先我们定义几个接口
这儿肯定有好多疑问,按理来说定义一个侧滑回调完全足够了,为什么还这么麻烦定义点击和长按事件呢,这儿指出一个问题,那就是在通过HorizontalScrollView处理侧滑事件的时候,会覆写他的onTouch事件,导致控件本身的点击事件失效,所以此处我们需要自己定义这几个事件
适配器中处理,省略其他代码,直接处理和子类有关的getChildView方法,如下
定时线程以及变量如下
回调handle中处理事件的回调功能
如果有需要可以直接把onTouch写在自定义控件HorizontalScrollView中,提高代码的简洁程度,至此功能结束,添加了长按事件,侧滑删除和点击事件,组item同样可以添加侧滑,原理一样
最近工作上有个需求,类似于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同样可以添加侧滑,原理一样
相关文章推荐
- expandableListview实现侧滑删除
- android--------ListView和ExpandableListView的侧滑删除操作
- android--------ListView和ExpandableListView的侧滑删除操作
- android--------ListView和ExpandableListView的侧滑删除操作
- 一个可以左滑删除的完整购物车DelSlideExpandableListView
- 侧滑可以删除的ListView
- 安卓仿ios侧滑删除地址-SwipeMenuListView
- 侧滑删除 SwipeMenuListView的使用
- Android listview 侧滑 SwipeListView 详解 实现微信,QQ等滑动删除效果
- Android 模仿QQ侧滑删除ListView功能示例
- SwipeListView实现QQ消息侧滑删除功能
- Android 仿QQListView侧滑删除
- ExpandableListView实例(三)_实现QQ中"未分组"效果和"未分组"不可编辑删除功能
- Android ListView 侧滑效果实现(滑动展开、滑动删除)
- 仿QQ侧滑删除Item:Swipemenulistview的简单实现
- ListView侧滑删除的实现,SlideDeleteListView,针对ScrollView嵌套ListView视图和手势冲突优化
- ExpandableListView 删除group notifyDataSetChanged child重复
- Androidlistview 的侧滑删除仿的QQ效果的几种实现方式
- 动态添加删除ExpandableListView的item的例子
- ListView侧滑删除的实现,利用SwipemenuListView开源框架