Android編程實(shí)現(xiàn)列表側(cè)滑刪除的方法詳解
本文實(shí)例講述了Android編程實(shí)現(xiàn)列表側(cè)滑刪除的方法。分享給大家供大家參考,具體如下:
前言:今天突然想起來了列表的滑動(dòng)刪除功能,一些下拉刷新的框架也會帶這個(gè)側(cè)滑刪除的功能,比如一些listview的和recycleview的刷新框架都有這個(gè)功能,我今天寫這個(gè)博客的目的是如何不依賴這些框架也是實(shí)現(xiàn)側(cè)滑刪除,如果自己已經(jīng)使用的列表框架沒有側(cè)滑刪除怎么給單獨(dú)加入側(cè)滑刪除功能。
概括:我今天寫的這個(gè)文章就是講的是怎么單獨(dú)給列表加入側(cè)滑刪除功能,不去為了側(cè)滑刪除而依賴一個(gè)列表框架,就是說如果需要的話可以簡簡單單的在自己的列表中加入這個(gè)側(cè)滑刪除的功能。主要實(shí)現(xiàn)就是自定義列表?xiàng)l目的容器view,來實(shí)現(xiàn)對手勢的監(jiān)聽,從而通過手勢的側(cè)滑實(shí)現(xiàn)刪除按鈕的出現(xiàn)效果。
好了,下面開始正文吧。。。
首先給出自定義條目容器控件的代碼:
里面的注釋請好好看看,有助于你快速的看懂這個(gè)類的實(shí)現(xiàn),并且實(shí)現(xiàn)你的自定義!!
public class DragListItem extends LinearLayout { private Context mContext; private View mHidenDragView; private LinearLayout mContentView;//將包裹實(shí)際的內(nèi)容 private LinearLayout mHidenLayout; private Scroller mScroller; private int mLastX, mLastY; private int mDragOutWidth;//完全側(cè)滑出來的距離 private double mfraction = 0.75;//觸發(fā)自動(dòng)側(cè)滑的臨界點(diǎn) private boolean isDrag = false; public DragListItem(Context context) { super(context); mContext = context; initView(); } public DragListItem(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; initView(); } private void initView() { setOrientation(HORIZONTAL); //merge進(jìn)來整個(gè)listItem,在這里可以自己定義刪除按鈕的顯示的布局,隨便按照的喜好修改都行 mHidenDragView = View.inflate(mContext, R.layout.hide_drag_item, this); mContentView = (LinearLayout) mHidenDragView.findViewById(R.id.show_content_view); mHidenLayout = (LinearLayout) mHidenDragView.findViewById(R.id.hide_view); mScroller = new Scroller(mContext); //將隱藏的刪除布局的寬度賦值給邊界的值,根據(jù)自己的需要可以任意的修改 mDragOutWidth = dip2px(mContext, 120); } public static int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } /** * 根據(jù)傳遞進(jìn)來的事件,在此進(jìn)行側(cè)滑邏輯的判斷,從而實(shí)現(xiàn)側(cè)滑時(shí)刪除按鈕滑出的效果功能 */ public void onDragTouchEvent(MotionEvent event) { if (isDrag) {//手指在橫向滑動(dòng)時(shí)設(shè)置條目不可點(diǎn)擊 setClickable(false); } else { setClickable(true); } int x = (int) event.getX(); int y = (int) event.getY(); int scrollX = getScrollX();//手機(jī)屏幕左上角x軸的值 - view的左上角x軸的值 switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (!mScroller.isFinished()) { mScroller.abortAnimation(); } break; case MotionEvent.ACTION_MOVE: hsaMove = true; int deltaX = x - mLastX; int deltaY = y - mLastY; //縱向的滑動(dòng)大于橫向的滑動(dòng)時(shí)是不處罰側(cè)滑效果的 // 此處的加上100是為了讓條目的側(cè)滑更容易觸發(fā),根據(jù)自己的需要可以調(diào)整該值 if (Math.abs(deltaX) + 100 < Math.abs(deltaY)) { break; } if (deltaX != 0) {//手指正在橫向滑動(dòng) isDrag = true; int newScrollX = scrollX - deltaX;//當(dāng)這個(gè)值變小時(shí),view視圖向左滑動(dòng) if (newScrollX < 0) {//保持大于等于0,等于0時(shí)view左上角x值和屏幕左上角x值重合 newScrollX = 0; setClickable(true); } else if (newScrollX > mDragOutWidth) {//當(dāng)?shù)竭_(dá)隱藏布局的邊界時(shí) 是不能再側(cè)滑了 newScrollX = mDragOutWidth; } scrollTo(newScrollX, 0); } break; case MotionEvent.ACTION_UP: hsaMove = false; default: int finalScrollX = 0; //左滑到足夠自動(dòng)滑動(dòng)的位置時(shí)可以自動(dòng)滑出刪除布局 // ,否則就自動(dòng)回縮隱藏刪除布局 if (scrollX > mDragOutWidth * mfraction) { finalScrollX = mDragOutWidth; autoScrollToX(finalScrollX, 500); } else { rollBack(); isDrag = false; } break; } mLastX = x; mLastY = y; } private boolean hsaMove = false;//該條目是否已經(jīng)監(jiān)聽過手勢的滑動(dòng),用來作為判斷是否進(jìn)行條目左右滑動(dòng)的條件之一 public boolean isHsaMove() { return hsaMove; } public void setHsaMove(boolean hsaMove) { this.hsaMove = hsaMove; } public void setIsDrag(boolean isDrag) { this.isDrag = isDrag; } /** * 自動(dòng)回滾到封閉狀態(tài) */ public void rollBack() { if (getScrollX() != 0) { autoScrollToX(0, 100); new Handler().postDelayed(new Runnable() { public void run() { setClickable(true); isDrag = false;//將狀態(tài)置為false,沒有側(cè)滑出 hsaMove = false;//狀態(tài)重置后將是否滑動(dòng)過置為沒有滑動(dòng)過 } }, 10); } } private void autoScrollToX(int finalX, int duration) { mScroller.startScroll(getScrollX(), 0, finalX - getScrollX(), 0, duration); invalidate(); } public boolean getDragState() { return isDrag; } @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); postInvalidate(); } } /** * 更改隱藏頁的文字 */ public void setFirstHidenView(CharSequence charSequence) { TextView textView = (TextView) mHidenLayout.findViewById(R.id.hide_delete); textView.setText(charSequence); } /** * 給使用者添加隱藏頁的視圖(不僅僅是刪除) */ public void addHidenView(TextView view) { mHidenLayout.addView(view); } /** * 給使用者設(shè)置listItem的實(shí)際內(nèi)容 */ public void setContentView(View view) { mContentView.addView(view); } public double getMfraction() { return mfraction; } public void setMfraction(double mfraction) { this.mfraction = mfraction; } }
對這個(gè)控件做一下簡單的解釋:
在上面的自定義控件里面,通過注釋大家可以清晰的看到是將原來的條目的布局包裹在該自定義的容器里面,然后攔截手指的事件做側(cè)滑事件的處理,使得刪除布局的顯示和隱藏,就實(shí)現(xiàn)了側(cè)滑的刪除。
當(dāng)然了,這個(gè)實(shí)現(xiàn)原理還是很簡單的,看懂的人都可以根據(jù)自己的需要做定制的修改從而實(shí)現(xiàn)自己需要的效果和功能。
比如:隱藏的布局可以任意設(shè)置,所以不一定是刪除功能,只要是需要側(cè)滑實(shí)現(xiàn)的都是可以靠這個(gè)控件給快速簡單的實(shí)現(xiàn)出來。
下面是這個(gè)控件需要加載的布局文件:(這是我項(xiàng)目的效果,不同的人可以根據(jù)自己的需要做不同的修改)
<?xml version="1.0" encoding="utf-8"?> <merge xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!-- 實(shí)際顯示的內(nèi)容--> <LinearLayout android:id="@+id/show_content_view" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > </LinearLayout> <!--隱藏在后面的刪除--> <LinearLayout android:id="@+id/hide_view" android:layout_width="120dp" android:layout_height="match_parent" android:background="@android:color/holo_red_dark" android:orientation="horizontal"> <TextView android:id="@+id/hide_delete" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_weight="1" android:gravity="center" android:text="刪除" android:textSize="20sp" /> </LinearLayout> </merge>
好了,這個(gè)自定義的控件的代碼和布局文件已經(jīng)提供給你了,原理我也已經(jīng)說完了,就是靠這個(gè) 自定義的控件實(shí)現(xiàn)的側(cè)滑刪除效果。
下面就簡單的以listview作為示例,給大家演示一下這個(gè)控件的簡單用法:(在適配器里做這樣的處理就好了)
@Override public View getView(int position, View convertView, ViewGroup parent) { final ViewHolder viewHolder; DragListItem dragListItem = (DragListItem) convertView; if (dragListItem == null) { View view = layoutInflater.inflate(R.layout.list_item_drag, parent, false); dragListItem = new DragListItem(mContext); dragListItem.setContentView(view); viewHolder = new ViewHolder(dragListItem); dragListItem.setTag(viewHolder); } else { viewHolder = (ViewHolder) dragListItem.getTag(); } dragListItem.rollBack(); dragListItem.setOnClickListener(new View.OnClickListener() {//給條目添加點(diǎn)擊事件 @Override public void onClick(View v) { } }); viewHolder.hideItem.setOnClickListener(new View.OnClickListener() {//給隱藏的布局設(shè)置點(diǎn)擊事件 比如點(diǎn)擊刪除功能 @Override public void onClick(View v) { Toast.makeText(mContext, "刪除", Toast.LENGTH_SHORT).show(); } }); return dragListItem; }
這樣側(cè)滑刪除功能就在列表中給實(shí)現(xiàn)了?。?!
雖然我是以listview作為的示例,但是只要是Android技術(shù)可以的同僚們,都能看出來這個(gè)實(shí)現(xiàn)可以在任何的列表中給集成進(jìn)去從而簡單快速的實(shí)現(xiàn)側(cè)滑刪除的效果??!
更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android開發(fā)入門與進(jìn)階教程》、《Android調(diào)試技巧與常見問題解決方法匯總》、《Android基本組件用法總結(jié)》、《Android視圖View技巧總結(jié)》、《Android布局layout技巧總結(jié)》及《Android控件用法總結(jié)》
希望本文所述對大家Android程序設(shè)計(jì)有所幫助。
- Android高仿QQ6.0側(cè)滑刪除實(shí)例代碼
- Android仿QQ微信側(cè)滑刪除效果
- Android開發(fā)中記一個(gè)SwipeMenuListView側(cè)滑刪除錯(cuò)亂的Bug
- Android recyclerview實(shí)現(xiàn)拖拽排序和側(cè)滑刪除
- Android自定義view系列之99.99%實(shí)現(xiàn)QQ側(cè)滑刪除效果實(shí)例代碼詳解
- Android 模仿QQ側(cè)滑刪除ListView功能示例
- android的RecyclerView實(shí)現(xiàn)拖拽排序和側(cè)滑刪除示例
- Android使用Item Swipemenulistview實(shí)現(xiàn)仿QQ側(cè)滑刪除功能
- android實(shí)現(xiàn)QQ微信側(cè)滑刪除效果
- android基于SwipeRefreshLayout實(shí)現(xiàn)類QQ的側(cè)滑刪除
- Android實(shí)現(xiàn)微信側(cè)滑刪除當(dāng)前頁面
相關(guān)文章
Android?自定義來電秀實(shí)現(xiàn)總結(jié)
這篇文章主要為大家介紹了Android?自定義來電秀實(shí)現(xiàn)總結(jié)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01Android原生實(shí)現(xiàn)多線程斷點(diǎn)下載實(shí)例代碼
本篇文章主要介紹了Android原生實(shí)現(xiàn)多線程斷點(diǎn)下載實(shí)例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05舉例講解Android應(yīng)用中SimpleAdapter簡單適配器的使用
這篇文章主要介紹了Android應(yīng)用中SimpleAdapter簡單適配器的使用例子,SimpleAdapter經(jīng)常在ListView被使用,需要的朋友可以參考下2016-04-04Flutter?彈性布局基石flex算法flexible示例詳解
這篇文章主要為大家介紹了Flutter?彈性布局基石flex算法flexible示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12淺談Android Studio 4.1 更新內(nèi)容
這篇文章主要介紹了淺談Android Studio 4.1 更新內(nèi)容,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10Android 編輯頭像功能簡單實(shí)現(xiàn)實(shí)例(圖片選取,裁剪)
這篇文章主要介紹了Android 編輯頭像功能簡單實(shí)現(xiàn)實(shí)例(圖片選取,裁剪),非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-06-06Android使用Intent顯示實(shí)現(xiàn)頁面跳轉(zhuǎn)
這篇文章主要為大家詳細(xì)介紹了Android使用Intent顯示實(shí)現(xiàn)頁面跳轉(zhuǎn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08Android編程之ActionBar Tabs用法實(shí)例分析
這篇文章主要介紹了Android編程之ActionBar Tabs用法,結(jié)合實(shí)例形式分析了ActionBar Tabs的功能及Tab切換不同的Fragment的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-03-03詳解Android更改APP語言模式的實(shí)現(xiàn)過程
本文詳細(xì)介紹如何更改Android中APP的語言模式,這個(gè)功能對于大家開發(fā)Android APP很有幫助,本文運(yùn)用文字介紹和代碼示例把過程寫的很詳細(xì),有需要的可以參考借鑒。2016-08-08