欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2023-12-09 20:46:03
项目中需求,要做条目条目拖拽删除效果,实际效果和qq消息删除一样,侧滑有制定和删除。 效果图 第一步效果图 1.0自定义控件 swipelayout 继承fr...

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

效果图

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

第一步效果图

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

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; 
  } 

第三步:

效果图

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

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条目拖拽删除功能实例代码,希望对大家有所帮助