项目中需求,要做条目条目拖拽删除效果,实际效果和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 top,int right,int bottom) { super.onLayout(changed,left,top,right,bottom); mDeletePanel.layout(mWith,mWith+mRang,mHeigth); }
4.0在onVIEwpositionChanged方法中实现联动效果
/** * 当被拖拽的控件已经移动过后,会调用这个方法,可以用于处理控件间的联动效果 * @left 被拖拽控件的真实移动位置 * @dx 被拖拽控件的真实偏移大小 */ @OverrIDe public voID onVIEwpositionChanged(VIEw changedVIEw,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 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,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条目拖拽删除功能实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持!
总结以上是内存溢出为你收集整理的Android条目拖拽删除功能实例代码全部内容,希望文章能够帮你解决Android条目拖拽删除功能实例代码所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)