欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android條目拖拽刪除功能實(shí)例代碼

 更新時(shí)間:2017年08月09日 14:15:05   作者:王虎的博客  
最近做項(xiàng)目遇到這樣的需求,要做條目條目拖拽刪除效果,實(shí)際效果和QQ消息刪除一樣,側(cè)滑有制定和刪除,下面通過本文給大家分享Android條目拖拽刪除功能,需要的朋友參考下吧

項(xiàng)目中需求,要做條目條目拖拽刪除效果,實(shí)際效果和QQ消息刪除一樣,側(cè)滑有制定和刪除。

效果圖

第一步效果圖

1.0自定義控件 SwipeLayout 繼承FrameLayout重寫里面三個(gè)構(gòu)造方法,分別調(diào)用initView().

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

3.0在initView()方法中,創(chuàng)建拖拽輔輔助工具 ViewDragHelper()

 該方法需要傳入回調(diào) MyCallBack()

4.0,創(chuàng)建MyCallBack()回調(diào),繼承ViewDragHelper.Callback

  在回調(diào)中 覆蓋tryCaptureView方法,返回true 允許child被拖拽,被 覆蓋clampViewPositionHorizontal 返回left系統(tǒng)提供拖拽位置

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; 
  } 
  /** 
   * 固定被拖拽控件的水平位置, 
   * 參數(shù)里的 left 是系統(tǒng)推薦移動(dòng)到的位置,可以進(jìn)行修正, 
   * 方法返回的值就是 child 將要移動(dòng)到的位置 
   */ 
  @Override 
  public int clampViewPositionHorizontal(View child, int left, int dx) { 
   return left; 
  } 
 } 
} 

第二步:

1.0創(chuàng)建onFinishInflate方法獲取子控件,并且判斷健壯性

/* 
  控件初始化時(shí)執(zhí)行,可以用于獲取子控件 
  */ 
 @Override 
 protected void onFinishInflate() { 
  // 健壯性檢查 
  if (getChildCount()!=2){ 
   throw new RuntimeException("SwipeLayout 必須存放兩個(gè)子控件"); 
  } 
  if (!(getChildAt(0) instanceof ViewGroup)||!(getChildAt(1) instanceof ViewGroup)){ 
   throw new RuntimeException("SwipeLayout 的子控件必須是 ViewGroup"); 
  } 
  mContent = (ViewGroup) getChildAt(0); 
  mDeletePanel = (ViewGroup) getChildAt(1); 
 } 

2.0創(chuàng)建onSizeChanged方法,在控件大小改變的時(shí)候調(diào)用,獲取控件的寬高,和刪除的面板的最大移動(dòng)范圍

/** 
  * 當(dāng)控件大小改變的時(shí)候調(diào)用這個(gè)方法 
  */ 
 @Override 
 protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
  super.onSizeChanged(w, h, oldw, oldh); 
  int mWith = w; 
  int mHeigth = h; 
  //界面創(chuàng)建過程中,不能使用 getWidth 方法 
  int mRang = mDeletePanel.getMeasuredWidth(); 
 } 

3.0在onLayout中指定側(cè)拉面板的位置

//指定側(cè)拉面板的位置 
 @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方法中實(shí)現(xiàn)聯(lián)動(dòng)效果

/** 
  * 當(dāng)被拖拽的控件已經(jīng)移動(dòng)過后,會(huì)調(diào)用這個(gè)方法,可以用于處理控件間的聯(lián)動(dòng)效果 
  * @left 被拖拽控件的真實(shí)移動(dòng)位置 
  * @dx 被拖拽控件的真實(shí)偏移大小 
  */ 
  @Override 
  public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { 
   if (changedView==mContent){ 
    // 移動(dòng)正文的同時(shí)也要移動(dòng)側(cè)欄 
    mDeletePanel.offsetLeftAndRight(dx); 
   }else{ 
    mContent.offsetLeftAndRight(dx); 
   } 
  } 

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

/** 
   * 固定被拖拽控件的水平位置, 
   * 參數(shù)里的 left 是系統(tǒng)推薦移動(dòng)到的位置,可以進(jìn)行修正, 
   * 方法返回的值就是 child 將要移動(dòng)到的位置 
   */ 
  @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中根據(jù)來開局里面,判斷是否打開還是關(guān)閉

2.0  在  moveContent中第一次滑動(dòng)

3.0computeScroll中,繼續(xù)滑動(dòng),直到滑動(dòng)到指定的位置

4.0注意在onViewPositionChanged中手動(dòng)刷新界面,調(diào)用invalidate方法

如果不手動(dòng)刷新界面,效果展示不出來

/** 
  * 當(dāng)用戶松手時(shí)執(zhí)行 
  * @xvel 松手時(shí)在 X 方向的移動(dòng)速度,如果為 正數(shù) 則說明是向右移動(dòng),如果是 負(fù)數(shù) 則說明是向左移動(dòng),如果為零,說明是靜止?fàn)顟B(tài) 
  */ 
  @Override 
  public void onViewReleased(View releasedChild, float xvel, float yvel) { 
   if (xvel>0){ 
    //向右移動(dòng) 
    close(); 
   }else if (xvel<0){ 
    //向左移動(dòng) 
    opend(); 
   }else if (xvel>-mRang/2){// 靜止?fàn)顟B(tài) 
    close();// 展開不到一半,關(guān)閉面板 
   }else{ 
    opend(); 
   } 
  } 
 } 
 /** 
 * 打開面板 
 */ 
 private void opend() { 
  int left=-mRang; 
  moveContent(left); 
 } 
 /** 
 * 關(guān)閉面板 
 */ 
 private void close() { 
  int left=0; 
  moveContent(left); 
 } 
 private void moveContent(int left) { 
  // 開啟平滑滾動(dòng),如果返回 true 則說明要繼續(xù)刷新界面,保持滾動(dòng) 
  if(mDragHelper.smoothSlideViewTo(mContent,left,0)){ 
   invalidate(); 
  } 
 } 
 @Override 
 public void computeScroll() { 
  // 繼續(xù)平滑滾動(dòng),如果返回 true 則說明要繼續(xù)刷新界面,保持滾動(dòng) 
  if (mDragHelper.continueSettling(true)){ 
   invalidate(); 
  } 
 } 

第四步:

1.0現(xiàn)給ListView賦值   在這就省略

2.0在SwipeLayout中使用枚舉記錄面板的狀態(tài)

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

3.0// 記錄上一個(gè)打開的面板。注意:一定要是 靜態(tài)變量

private static SwipeLayout preSwipeLayout;

4.0在onViewPositionChanged中創(chuàng)建一個(gè)方法操作關(guān)閉面板

// 關(guān)閉上一個(gè)打開的面板
closePre();

5.0closePre()在這個(gè)方法中,判斷當(dāng)前面板的狀態(tài),并且根據(jù)狀態(tài),關(guān)閉上一個(gè)打開的面板

// 判斷當(dāng)前面板是否正在打開,如果正在打開則將上一個(gè)打開的面板關(guān)閉 
 private void closePre() { 
  //記錄舊狀態(tài) 
  Status preStatus=status; 
  if (mContent.getLeft()==-mRang){ 
   //記錄當(dāng)前面板已經(jīng)打開 
   status=status.OPENED; 
  }else if (mContent.getLeft()==0){ 
   //當(dāng)前面板已經(jīng)關(guān)閉 
   status=status.CLOSED; 
  }else { 
   status=status.DRAGING; 
  } 
  // 如果當(dāng)前面板舊狀態(tài)為關(guān)閉,并且新狀態(tài)為拖拽,那么此時(shí)可以關(guān)閉之前打開的面板 
  if (preStatus==status.CLOSED&&status==status.DRAGING){ 
   if (preSwipeLayout!=null&&preSwipeLayout!=this){ 
    // 關(guān)閉上一個(gè)面板 
    preSwipeLayout.close(); 
   } 
   // 將當(dāng)前面板標(biāo)記為 打開的面板 
   preSwipeLayout=this; 
  } 
 } 

總結(jié)

以上所述是小編給大家介紹的Android條目拖拽刪除功能實(shí)例代碼,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

最新評(píng)論