Android編程實(shí)現(xiàn)列表側(cè)滑刪除的方法詳解
本文實(shí)例講述了Android編程實(shí)現(xiàn)列表側(cè)滑刪除的方法。分享給大家供大家參考,具體如下:
前言:今天突然想起來(lái)了列表的滑動(dòng)刪除功能,一些下拉刷新的框架也會(huì)帶這個(gè)側(cè)滑刪除的功能,比如一些listview的和recycleview的刷新框架都有這個(gè)功能,我今天寫這個(gè)博客的目的是如何不依賴這些框架也是實(shí)現(xiàn)側(cè)滑刪除,如果自己已經(jīng)使用的列表框架沒(méi)有側(cè)滑刪除怎么給單獨(dú)加入側(cè)滑刪除功能。
概括:我今天寫的這個(gè)文章就是講的是怎么單獨(dú)給列表加入側(cè)滑刪除功能,不去為了側(cè)滑刪除而依賴一個(gè)列表框架,就是說(shuō)如果需要的話可以簡(jiǎn)簡(jiǎn)單單的在自己的列表中加入這個(gè)側(cè)滑刪除的功能。主要實(shí)現(xiàn)就是自定義列表?xiàng)l目的容器view,來(lái)實(shí)現(xiàn)對(duì)手勢(shì)的監(jiān)聽,從而通過(guò)手勢(shì)的側(cè)滑實(shí)現(xiàn)刪除按鈕的出現(xiàn)效果。
好了,下面開始正文吧。。。
首先給出自定義條目容器控件的代碼:
里面的注釋請(qǐng)好好看看,有助于你快速的看懂這個(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è)滑出來(lái)的距離
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)來(lái)整個(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)來(lái)的事件,在此進(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)聽過(guò)手勢(shì)的滑動(dòng),用來(lái)作為判斷是否進(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,沒(méi)有側(cè)滑出
hsaMove = false;//狀態(tài)重置后將是否滑動(dòng)過(guò)置為沒(méi)有滑動(dòng)過(guò)
}
}, 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();
}
}
/**
* 更改隱藏頁(yè)的文字
*/
public void setFirstHidenView(CharSequence charSequence) {
TextView textView = (TextView) mHidenLayout.findViewById(R.id.hide_delete);
textView.setText(charSequence);
}
/**
* 給使用者添加隱藏頁(yè)的視圖(不僅僅是刪除)
*/
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;
}
}
對(duì)這個(gè)控件做一下簡(jiǎn)單的解釋:
在上面的自定義控件里面,通過(guò)注釋大家可以清晰的看到是將原來(lái)的條目的布局包裹在該自定義的容器里面,然后攔截手指的事件做側(cè)滑事件的處理,使得刪除布局的顯示和隱藏,就實(shí)現(xiàn)了側(cè)滑的刪除。
當(dāng)然了,這個(gè)實(shí)現(xiàn)原理還是很簡(jiǎn)單的,看懂的人都可以根據(jù)自己的需要做定制的修改從而實(shí)現(xiàn)自己需要的效果和功能。
比如:隱藏的布局可以任意設(shè)置,所以不一定是刪除功能,只要是需要側(cè)滑實(shí)現(xiàn)的都是可以靠這個(gè)控件給快速簡(jiǎn)單的實(shí)現(xiàn)出來(lái)。
下面是這個(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)說(shuō)完了,就是靠這個(gè) 自定義的控件實(shí)現(xiàn)的側(cè)滑刪除效果。
下面就簡(jiǎn)單的以listview作為示例,給大家演示一下這個(gè)控件的簡(jiǎn)單用法:(在適配器里做這樣的處理就好了)
@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ù)可以的同僚們,都能看出來(lái)這個(gè)實(shí)現(xiàn)可以在任何的列表中給集成進(jìn)去從而簡(jiǎn)單快速的實(shí)現(xiàn)側(cè)滑刪除的效果!!
更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android開發(fā)入門與進(jìn)階教程》、《Android調(diào)試技巧與常見問(wèn)題解決方法匯總》、《Android基本組件用法總結(jié)》、《Android視圖View技巧總結(jié)》、《Android布局layout技巧總結(jié)》及《Android控件用法總結(jié)》
希望本文所述對(duì)大家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)前頁(yè)面
相關(guān)文章
Androidstudio調(diào)用攝像頭拍照并保存照片
這篇文章主要為大家詳細(xì)介紹了Androidstudio調(diào)用攝像頭拍照并保存照片,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
Android 通過(guò)觸摸動(dòng)態(tài)地在屏幕上畫矩形效果
在屏幕上用手指畫出一個(gè)區(qū)域,返回所圈的區(qū)域坐標(biāo)。通過(guò)自定義view設(shè)置畫筆及對(duì)應(yīng)參數(shù),在onTouchEvent()回調(diào)函數(shù)里,對(duì)觸摸事件進(jìn)行判斷。畫出矩形圖形,具體實(shí)現(xiàn)代碼大家參考下本文2017-07-07
Android判斷后臺(tái)服務(wù)是否開啟的兩種方法實(shí)例詳解
這篇文章主要介紹了Android判斷后臺(tái)服務(wù)是否開啟的方法的相關(guān)資料,這里提供了兩種方法及實(shí)例,需要的朋友可以參考下2017-07-07
Android實(shí)現(xiàn)跑馬燈效果的兩種簡(jiǎn)單方式
這篇文章主要給大家介紹了關(guān)于Android實(shí)現(xiàn)跑馬燈的兩種簡(jiǎn)單方式,文中介紹了兩種方法,分別說(shuō)了每個(gè)方法的優(yōu)缺點(diǎn),需要的朋友可以選擇性使用,下面來(lái)一起看看吧2021-07-07

