仿QQ側滑動刪除效果圖
自訂listview
public class DragDelListView extends ListView { private boolean moveable=false; private boolean closed=true; private float mDownX,mDownY; private int mTouchPosition,oldPosition=-1; private DragDelItem mTouchView,oldView; private Context context; public DragDelListView(Context context) { super(context); init(context); } public DragDelListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context); } public DragDelListView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } private void init(Context context) { this.context=context; } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY()); mTouchView=(DragDelItem)getChildAt(mTouchPosition - getFirstVisiblePosition()); mDownX = ev.getX(); mDownY=ev.getY(); if(oldPosition==mTouchPosition ||closed) { moveable=true; mTouchView.mDownX =(int)mDownX; }else { moveable=false; if(oldView!=null) { oldView.smoothCloseMenu(); } } oldPosition=mTouchPosition; oldView=mTouchView; break; case MotionEvent.ACTION_MOVE: if (Math.abs(mDownX-ev.getX()) < Math.abs(mDownY-ev.getY()) * dp2px(2)) { break; } if (moveable) { int dis = (int) (mTouchView.mDownX -ev.getX()); if(mTouchView.state==mTouchView.STATE_OPEN) dis+=mTouchView.mMenuView.getWidth(); mTouchView.swipe(dis); ev.setAction(MotionEvent.ACTION_CANCEL); } break; case MotionEvent.ACTION_UP: if (moveable) { if ((mTouchView.mDownX -ev.getX()) > (mTouchView.mMenuView.getWidth()/2)) { // open mTouchView.smoothOpenMenu(); closed=false; } else { // close mTouchView.smoothCloseMenu(); closed=true; } ev.setAction(MotionEvent.ACTION_CANCEL); } break; } return super.onTouchEvent(ev); } private int dp2px(int dp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getContext().getResources().getDisplayMetrics()); } }
自訂滑動條目
public class DragDelItem extends LinearLayout { public static final int STATE_CLOSE = 0; public static final int STATE_OPEN = 1; private View mContentView; public View mMenuView; public int mDownX; public int state = STATE_CLOSE; public boolean isFling; private int mBaseX; private Scroller scroll; public DragDelItem(View contentView, View menuView) { super(contentView.getContext()); scroll=new Scroller(getContext()); mContentView = contentView; mMenuView = menuView; init(); } private DragDelItem(Context context, AttributeSet attrs) { super(context, attrs); } private DragDelItem(Context context) { super(context); } private void init() { setLayoutParams(new AbsListView.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); LayoutParams contentParams = new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); mContentView.setLayoutParams(contentParams); mMenuView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); addView(mContentView); addView(mMenuView); } public void swipe(int dis) { if (dis > mMenuView.getWidth()) { dis = mMenuView.getWidth(); } if (dis < 0) { dis = 0; } mContentView.layout(-dis, mContentView.getTop(), mContentView.getWidth() - dis, getMeasuredHeight()); mMenuView.layout(mContentView.getWidth() - dis, mMenuView.getTop(), mContentView.getWidth() + mMenuView.getWidth() - dis, mMenuView.getBottom()); } @Override public void computeScroll() { if (state == STATE_OPEN) { if (scroll.computeScrollOffset()) { swipe(scroll.getCurrX()); postInvalidate(); } } else { if (scroll.computeScrollOffset()) { swipe(mBaseX - scroll.getCurrX()); postInvalidate(); } } } public void smoothCloseMenu() { state = STATE_CLOSE; mBaseX = -mContentView.getLeft(); scroll.startScroll(0, 0, mBaseX, 0, 350); postInvalidate(); } public void smoothOpenMenu() { state = STATE_OPEN; scroll.startScroll(-mContentView.getLeft(), 0, mMenuView.getWidth()/2, 0, 350); postInvalidate(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mMenuView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec( getMeasuredHeight(), MeasureSpec.EXACTLY)); mContentView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec( getMeasuredHeight(), MeasureSpec.EXACTLY)); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { mContentView.layout(0, 0, getMeasuredWidth(), mContentView.getMeasuredHeight()); mMenuView.layout(getMeasuredWidth(), 0, getMeasuredWidth() + mMenuView.getMeasuredWidth(), mContentView.getMeasuredHeight()); } }
所使用的佈局檔案
介面版面碼
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/rl_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#999999" android:padding="8dp" > <ImageView android:id="@+id/iv_icon" android:layout_width="50dp" android:layout_height="50dp" android:src="@drawable/ic_launcher" /> <TextView android:id="@+id/tv_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="10dp" android:layout_toRightOf="@+id/iv_icon" android:text="name" android:textColor="@android:color/black" android:textSize="18sp" /> </RelativeLayout> —swipemenu.xml代码 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="horizontal" > <TextView android:id="@+id/tv_open" android:layout_width="90dp" android:layout_height="match_parent" android:gravity="center" android:background="#C2C2C2" android:text="置顶" android:textColor="@android:color/white" android:textSize="18sp" /> <TextView android:id="@+id/tv_del" android:layout_width="90dp" android:layout_height="match_parent" android:gravity="center" android:background="#FF0000" android:text="删除" android:textColor="@android:color/white" android:textSize="18sp" /> </LinearLayout>
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援PHP中文網。
更多Android仿QQ微信側滑刪除效果相關文章請關注PHP中文網!

本文分析了2025年的前四個JavaScript框架(React,Angular,Vue,Susve),比較了它們的性能,可伸縮性和未來前景。 儘管由於強大的社區和生態系統,所有這些都保持占主導地位,但它們的相對人口

本文討論了使用咖啡因和Guava緩存在Java中實施多層緩存以提高應用程序性能。它涵蓋設置,集成和績效優勢,以及配置和驅逐政策管理最佳PRA

Node.js 20通過V8發動機改進可顯著提高性能,特別是更快的垃圾收集和I/O。 新功能包括更好的WebSembly支持和精製的調試工具,提高開發人員的生產率和應用速度。

Java的類上載涉及使用帶有引導,擴展程序和應用程序類負載器的分層系統加載,鏈接和初始化類。父代授權模型確保首先加載核心類別,從而影響自定義類LOA

本文介紹了SnakeyAml中的CVE-2022-1471漏洞,這是一個允許遠程代碼執行的關鍵缺陷。 它詳細介紹瞭如何升級春季啟動應用程序到Snakeyaml 1.33或更高版本的降低風險,強調了依賴性更新

本文使用lambda表達式,流API,方法參考和可選探索將功能編程集成到Java中。 它突出顯示了通過簡潔性和不變性改善代碼可讀性和可維護性等好處

本文探討了在黃瓜步驟之間共享數據的方法,比較方案上下文,全局變量,參數傳遞和數據結構。 它強調可維護性的最佳實踐,包括簡潔的上下文使用,描述性


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

Dreamweaver Mac版
視覺化網頁開發工具