Android編程實現(xiàn)列表側(cè)滑刪除的方法詳解
本文實例講述了Android編程實現(xiàn)列表側(cè)滑刪除的方法。分享給大家供大家參考,具體如下:
前言:今天突然想起來了列表的滑動刪除功能,一些下拉刷新的框架也會帶這個側(cè)滑刪除的功能,比如一些listview的和recycleview的刷新框架都有這個功能,我今天寫這個博客的目的是如何不依賴這些框架也是實現(xiàn)側(cè)滑刪除,如果自己已經(jīng)使用的列表框架沒有側(cè)滑刪除怎么給單獨加入側(cè)滑刪除功能。
概括:我今天寫的這個文章就是講的是怎么單獨給列表加入側(cè)滑刪除功能,不去為了側(cè)滑刪除而依賴一個列表框架,就是說如果需要的話可以簡簡單單的在自己的列表中加入這個側(cè)滑刪除的功能。主要實現(xiàn)就是自定義列表條目的容器view,來實現(xiàn)對手勢的監(jiān)聽,從而通過手勢的側(cè)滑實現(xiàn)刪除按鈕的出現(xiàn)效果。
好了,下面開始正文吧。。。
首先給出自定義條目容器控件的代碼:
里面的注釋請好好看看,有助于你快速的看懂這個類的實現(xiàn),并且實現(xiàn)你的自定義!!
public class DragListItem extends LinearLayout {
private Context mContext;
private View mHidenDragView;
private LinearLayout mContentView;//將包裹實際的內(nèi)容
private LinearLayout mHidenLayout;
private Scroller mScroller;
private int mLastX, mLastY;
private int mDragOutWidth;//完全側(cè)滑出來的距離
private double mfraction = 0.75;//觸發(fā)自動側(cè)滑的臨界點
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)來整個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è)滑邏輯的判斷,從而實現(xiàn)側(cè)滑時刪除按鈕滑出的效果功能
*/
public void onDragTouchEvent(MotionEvent event) {
if (isDrag) {//手指在橫向滑動時設(shè)置條目不可點擊
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;
//縱向的滑動大于橫向的滑動時是不處罰側(cè)滑效果的
// 此處的加上100是為了讓條目的側(cè)滑更容易觸發(fā),根據(jù)自己的需要可以調(diào)整該值
if (Math.abs(deltaX) + 100 < Math.abs(deltaY))
{
break;
}
if (deltaX != 0) {//手指正在橫向滑動
isDrag = true;
int newScrollX = scrollX - deltaX;//當(dāng)這個值變小時,view視圖向左滑動
if (newScrollX < 0) {//保持大于等于0,等于0時view左上角x值和屏幕左上角x值重合
newScrollX = 0;
setClickable(true);
} else if (newScrollX > mDragOutWidth) {//當(dāng)?shù)竭_(dá)隱藏布局的邊界時 是不能再側(cè)滑了
newScrollX = mDragOutWidth;
}
scrollTo(newScrollX, 0);
}
break;
case MotionEvent.ACTION_UP:
hsaMove = false;
default:
int finalScrollX = 0;
//左滑到足夠自動滑動的位置時可以自動滑出刪除布局
// ,否則就自動回縮隱藏刪除布局
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)聽過手勢的滑動,用來作為判斷是否進(jìn)行條目左右滑動的條件之一
public boolean isHsaMove() {
return hsaMove;
}
public void setHsaMove(boolean hsaMove) {
this.hsaMove = hsaMove;
}
public void setIsDrag(boolean isDrag) {
this.isDrag = isDrag;
}
/**
* 自動回滾到封閉狀態(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)重置后將是否滑動過置為沒有滑動過
}
}, 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的實際內(nèi)容
*/
public void setContentView(View view) {
mContentView.addView(view);
}
public double getMfraction() {
return mfraction;
}
public void setMfraction(double mfraction) {
this.mfraction = mfraction;
}
}
對這個控件做一下簡單的解釋:
在上面的自定義控件里面,通過注釋大家可以清晰的看到是將原來的條目的布局包裹在該自定義的容器里面,然后攔截手指的事件做側(cè)滑事件的處理,使得刪除布局的顯示和隱藏,就實現(xiàn)了側(cè)滑的刪除。
當(dāng)然了,這個實現(xiàn)原理還是很簡單的,看懂的人都可以根據(jù)自己的需要做定制的修改從而實現(xiàn)自己需要的效果和功能。
比如:隱藏的布局可以任意設(shè)置,所以不一定是刪除功能,只要是需要側(cè)滑實現(xiàn)的都是可以靠這個控件給快速簡單的實現(xiàn)出來。
下面是這個控件需要加載的布局文件:(這是我項目的效果,不同的人可以根據(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">
<!-- 實際顯示的內(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>
好了,這個自定義的控件的代碼和布局文件已經(jīng)提供給你了,原理我也已經(jīng)說完了,就是靠這個 自定義的控件實現(xiàn)的側(cè)滑刪除效果。
下面就簡單的以listview作為示例,給大家演示一下這個控件的簡單用法:(在適配器里做這樣的處理就好了)
@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() {//給條目添加點擊事件
@Override
public void onClick(View v) {
}
});
viewHolder.hideItem.setOnClickListener(new View.OnClickListener() {//給隱藏的布局設(shè)置點擊事件 比如點擊刪除功能
@Override
public void onClick(View v) {
Toast.makeText(mContext, "刪除", Toast.LENGTH_SHORT).show();
}
});
return dragListItem;
}
這樣側(cè)滑刪除功能就在列表中給實現(xiàn)了?。?!
雖然我是以listview作為的示例,但是只要是Android技術(shù)可以的同僚們,都能看出來這個實現(xiàn)可以在任何的列表中給集成進(jìn)去從而簡單快速的實現(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è)計有所幫助。
- Android高仿QQ6.0側(cè)滑刪除實例代碼
- Android仿QQ微信側(cè)滑刪除效果
- Android開發(fā)中記一個SwipeMenuListView側(cè)滑刪除錯亂的Bug
- Android recyclerview實現(xiàn)拖拽排序和側(cè)滑刪除
- Android自定義view系列之99.99%實現(xiàn)QQ側(cè)滑刪除效果實例代碼詳解
- Android 模仿QQ側(cè)滑刪除ListView功能示例
- android的RecyclerView實現(xiàn)拖拽排序和側(cè)滑刪除示例
- Android使用Item Swipemenulistview實現(xiàn)仿QQ側(cè)滑刪除功能
- android實現(xiàn)QQ微信側(cè)滑刪除效果
- android基于SwipeRefreshLayout實現(xiàn)類QQ的側(cè)滑刪除
- Android實現(xiàn)微信側(cè)滑刪除當(dāng)前頁面
相關(guān)文章
Androidstudio調(diào)用攝像頭拍照并保存照片
這篇文章主要為大家詳細(xì)介紹了Androidstudio調(diào)用攝像頭拍照并保存照片,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03
Android判斷后臺服務(wù)是否開啟的兩種方法實例詳解
這篇文章主要介紹了Android判斷后臺服務(wù)是否開啟的方法的相關(guān)資料,這里提供了兩種方法及實例,需要的朋友可以參考下2017-07-07

