Android条目拖拽删除功能实例代码

项目中需求,要做条目条目拖拽删除效果,实际效果和QQ消息删除一样,侧滑有制定和删除。

效果图

第一步效果图

1.0自定义控件 SwipeLayout 继承FrameLayout重写里面三个构造方法,分别调用initView().

2.0在布局中使用自定义控件

3.0在initView()方法中,创建拖拽辅辅助工具 ViewDragHelper()

该方法需要传入回调 MyCallBack()

4.0,创建MyCallBack()回调,继承ViewDragHelper.Callback

在回调中 覆盖tryCaptureView方法,返回true 允许child被拖拽,被 覆盖clampViewPositionHorizontal 返回left系统提供拖拽位置

5.0 onInterceptTouchEvent 返回:让ViewDragHelper判断是否需要拦截事件

6.0  onTouchEvent 返回true 并且让ViewDragHelper分析事件

具体代码:

布局:

<cn.itheima.swipelayout.SwipeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="wrap_content"> <!--正文部分--> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#fff" android:orientation="horizontal"> <TextView android:id="@+id/item_tv_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="10dp" android:text="张三" android:textSize="20sp" /> </RelativeLayout> <!--按钮部分--> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#888888" android:padding="10dp" android:text="呼叫" android:textSize="20sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#f00" android:padding="10dp" android:text="删除" android:textSize="20sp" /> </LinearLayout> </cn.itheima.swipelayout.SwipeLayout>

SwipeLayout 代码:

public class SwipeLayout extends FrameLayout { private ViewDragHelper mDragHelper; public SwipeLayout(Context context) { super(context); initView(); } public SwipeLayout(Context context, AttributeSet attrs) { super(context, attrs); initView(); } public SwipeLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(); } private void initView() { mDragHelper = ViewDragHelper.create(this,new MyCallBack()); } // 让ViewDragHelper就是拖拽辅助工具 返回true 则表示要拦截触摸事件 @Override public boolean onInterceptTouchEvent(MotionEvent ev) { //让拖拽辅助工具判断是否需要拦截 事件 return mDragHelper.shouldInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { //让拖拽辅助工具分析事件 分析用户手势 mDragHelper.processTouchEvent(event); return true; } private class MyCallBack extends ViewDragHelper.Callback{ /** * 如果返回 true 则表示 child 允许被拖拽 */ @Override public boolean tryCaptureView(View child, int pointerId) { return true; } /** * 固定被拖拽控件的水平位置, * 参数里的 left 是系统推荐移动到的位置,可以进行修正, * 方法返回的值就是 child 将要移动到的位置 */ @Override public int clampViewPositionHorizontal(View child, int left, int dx) { return left; } } }

第二步:

1.0创建onFinishInflate方法获取子控件,并且判断健壮性

/* 控件初始化时执行,可以用于获取子控件 */ @Override protected void onFinishInflate() { // 健壮性检查 if (getChildCount()!=2){ throw new RuntimeException("SwipeLayout 必须存放两个子控件"); } if (!(getChildAt(0) instanceof ViewGroup)||!(getChildAt(1) instanceof ViewGroup)){ throw new RuntimeException("SwipeLayout 的子控件必须是 ViewGroup"); } mContent = (ViewGroup) getChildAt(0); mDeletePanel = (ViewGroup) getChildAt(1); }

2.0创建onSizeChanged方法,在控件大小改变的时候调用,获取控件的宽高,和删除的面板的最大移动范围

/** * 当控件大小改变的时候调用这个方法 */ @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); int mWith = w; int mHeigth = h; //界面创建过程中,不能使用 getWidth 方法 int mRang = mDeletePanel.getMeasuredWidth(); }

3.0在onLayout中指定侧拉面板的位置

//指定侧拉面板的位置 @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); mDeletePanel.layout(mWith,0,mWith+mRang,mHeigth); }

4.0在onViewPositionChanged方法中实现联动效果

/** * 当被拖拽的控件已经移动过后,会调用这个方法,可以用于处理控件间的联动效果 * @left 被拖拽控件的真实移动位置 * @dx 被拖拽控件的真实偏移大小 */ @Override public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { if (changedView==mContent){ // 移动正文的同时也要移动侧栏 mDeletePanel.offsetLeftAndRight(dx); }else{ mContent.offsetLeftAndRight(dx); } }

5.0在 clampViewPositionHorizontal方法中  固定被拖拽控件的水平位置,

/** * 固定被拖拽控件的水平位置, * 参数里的 left 是系统推荐移动到的位置,可以进行修正, * 方法返回的值就是 child 将要移动到的位置 */ @Override public int clampViewPositionHorizontal(View child, int left, int dx) { if (child==mContent){ if (left>0){ left=0; }else if (left<-mRang){ left=-mRang; } }else{ if (left>mWith){//mWith是屏幕的宽度 left=mWith; }else if (left<mWith-mRang){ left=mWith-mRang; } } return left; }

第三步:

效果图

1.0onViewReleased中根据来开局里面,判断是否打开还是关闭

2.0  在  moveContent中第一次滑动

3.0computeScroll中,继续滑动,直到滑动到指定的位置

4.0注意在onViewPositionChanged中手动刷新界面,调用invalidate方法

如果不手动刷新界面,效果展示不出来

/** * 当用户松手时执行 * @xvel 松手时在 X 方向的移动速度,如果为 正数 则说明是向右移动,如果是 负数 则说明是向左移动,如果为零,说明是静止状态 */ @Override public void onViewReleased(View releasedChild, float xvel, float yvel) { if (xvel>0){ //向右移动 close(); }else if (xvel<0){ //向左移动 opend(); }else if (xvel>-mRang/2){// 静止状态 close();// 展开不到一半,关闭面板 }else{ opend(); } } } /** * 打开面板 */ private void opend() { int left=-mRang; moveContent(left); } /** * 关闭面板 */ private void close() { int left=0; moveContent(left); } private void moveContent(int left) { // 开启平滑滚动,如果返回 true 则说明要继续刷新界面,保持滚动 if(mDragHelper.smoothSlideViewTo(mContent,left,0)){ invalidate(); } } @Override public void computeScroll() { // 继续平滑滚动,如果返回 true 则说明要继续刷新界面,保持滚动 if (mDragHelper.continueSettling(true)){ invalidate(); } }

第四步:

1.0现给ListView赋值   在这就省略

2.0在SwipeLayout中使用枚举记录面板的状态

private enum Status{ CLOSED,OPENED,DRAGING; } private Status status = Status.CLOSED; public Status getStatus() { return status; }

3.0// 记录上一个打开的面板。注意:一定要是 静态变量

private static SwipeLayout preSwipeLayout;

4.0在onViewPositionChanged中创建一个方法操作关闭面板

// 关闭上一个打开的面板 closePre();

5.0closePre()在这个方法中,判断当前面板的状态,并且根据状态,关闭上一个打开的面板

// 判断当前面板是否正在打开,如果正在打开则将上一个打开的面板关闭 private void closePre() { //记录旧状态 Status preStatus=status; if (mContent.getLeft()==-mRang){ //记录当前面板已经打开 status=status.OPENED; }else if (mContent.getLeft()==0){ //当前面板已经关闭 status=status.CLOSED; }else { status=status.DRAGING; } // 如果当前面板旧状态为关闭,并且新状态为拖拽,那么此时可以关闭之前打开的面板 if (preStatus==status.CLOSED&&status==status.DRAGING){ if (preSwipeLayout!=null&&preSwipeLayout!=this){ // 关闭上一个面板 preSwipeLayout.close(); } // 将当前面板标记为 打开的面板 preSwipeLayout=this; } }

总结

以上所述是小编给大家介绍的Android条目拖拽删除功能实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

时间: 2024-08-21 14:55:48

Android条目拖拽删除功能实例代码的相关文章

GRID拖拽行的实例代码

这篇文章介绍了GRID拖拽行的实例代码,有需要的朋友可以参考一下   ---------------------GRID拖拽行的实例代码  单行拖拽--------------------------------------- 复制代码 代码如下: //创建第一个GRID var firstGrid = new Ext.grid.GridPanel({ ddGroup : 'secondGridDdGroup',//这里是第二个GRID的ddGroup store       : firstGr

Android 百度地图POI搜索功能实例代码_Android

在没介绍正文之前先给大家说下poi是什么意思. 由于工作的关系,经常在文件中会看到POI这三个字母的缩写,但是一直对POI的概念和含义没有很详细的去研究其背后代表的意思.今天下班之前,又看到了POI这三个字母,决定认认真真的搜索一些POI具体的含义. POI是英文的缩写,原来的单词是point of interest, 直译成中文就是兴趣点的意思.兴趣点这个词最早来自于导航地图厂商.地图厂商为了提供尽可能多的位置信息,花费了很大的精力去寻找诸如加油站,餐馆,酒店,景点等目的地,这些目的地其实都可

GRID拖拽行的实例代码_javascript技巧

---------------------GRID拖拽行的实例代码  单行拖拽--------------------------------------- 复制代码 代码如下: //创建第一个GRIDvar firstGrid = new Ext.grid.GridPanel({ddGroup : 'secondGridDdGroup',//这里是第二个GRID的ddGroupstore       : firstGridStore,enableDragDrop : true,//True表示

Android 百度地图POI搜索功能实例代码

在没介绍正文之前先给大家说下poi是什么意思. 由于工作的关系,经常在文件中会看到POI这三个字母的缩写,但是一直对POI的概念和含义没有很详细的去研究其背后代表的意思.今天下班之前,又看到了POI这三个字母,决定认认真真的搜索一些POI具体的含义. POI是英文的缩写,原来的单词是point of interest, 直译成中文就是兴趣点的意思.兴趣点这个词最早来自于导航地图厂商.地图厂商为了提供尽可能多的位置信息,花费了很大的精力去寻找诸如加油站,餐馆,酒店,景点等目的地,这些目的地其实都可

Android模拟强制下线通知功能实例代码

package com.itheima74.broadcastbestpractice; import android.content.Intent; import android.os.Bundle; import android.os.SystemClock; import android.support.v4.content.LocalBroadcastManager; import android.view.View; /** * 模拟强制下线通知 * 1.登录成功后10秒发送一条本地自

Android中加入名片扫描功能实例代码_Android

要想实现android手机通过扫描名片,得到名片信息,可以使用脉可寻提供的第三方SDK,即Maketion ScanCard SDK,脉可寻云名片识别服务.他们的官方网站为http://www.maketion.com/. 一.概述 Maketion ScanCardSDK(以下简称SDK)是提供给第三方合作伙伴接入脉可寻云名片识别服务,合作伙伴需要先申请key和secure才可以使用. SDK不能独立运行,使用时需要嵌入到Android的Project中. SDK支持Android2.1版本及

Android中加入名片扫描功能实例代码

要想实现android手机通过扫描名片,得到名片信息,可以使用脉可寻提供的第三方SDK,即Maketion ScanCard SDK,脉可寻云名片识别服务.他们的官方网站为http://www.maketion.com/. 一.概述 Maketion ScanCardSDK(以下简称SDK)是提供给第三方合作伙伴接入脉可寻云名片识别服务,合作伙伴需要先申请key和secure才可以使用. SDK不能独立运行,使用时需要嵌入到Android的Project中. SDK支持Android2.1版本及

Android自定义ListView实现仿QQ可拖拽列表功能_Android

我们大致的思路,其实是这样子的,也是我的设想,我们可以先去实现一个简单的ListView的数据,但是他的Adapter,我们可以用系统封装好的,然后传递进去一个实体类,最后自定义一个listview去操作,所以我们先把准备的工作做好,比如? list_item.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.a

Android自定义ListView实现仿QQ可拖拽列表功能

我们大致的思路,其实是这样子的,也是我的设想,我们可以先去实现一个简单的ListView的数据,但是他的Adapter,我们可以用系统封装好的,然后传递进去一个实体类,最后自定义一个listview去操作,所以我们先把准备的工作做好,比如? list_item.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.a