本篇文章給大家分享的是有關(guān)Android中怎么實現(xiàn)條目拖拽刪除功能,小編覺得挺實用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
創(chuàng)新互聯(lián)公司服務(wù)項目包括定海網(wǎng)站建設(shè)、定海網(wǎng)站制作、定海網(wǎng)頁制作以及定海網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,定海網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到定海省份的部分城市,未來相信會繼續(xù)擴大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
第一步效果圖
1.0自定義控件 SwipeLayout 繼承FrameLayout重寫里面三個構(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分析事件
具體代碼:
布局:
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)推薦移動到的位置,可以進行修正, * 方法返回的值就是 child 將要移動到的位置 */ @Override public int clampViewPositionHorizontal(View child, int left, int dx) { return left; } } }
第二步:
1.0創(chuàng)建onFinishInflate方法獲取子控件,并且判斷健壯性
/* 控件初始化時執(zhí)行,可以用于獲取子控件 */ @Override protected void onFinishInflate() { // 健壯性檢查 if (getChildCount()!=2){ throw new RuntimeException("SwipeLayout 必須存放兩個子控件"); } 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方法,在控件大小改變的時候調(diào)用,獲取控件的寬高,和刪除的面板的最大移動范圍
/** * 當控件大小改變的時候調(diào)用這個方法 */ @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方法中實現(xiàn)聯(lián)動效果
/** * 當被拖拽的控件已經(jīng)移動過后,會調(diào)用這個方法,可以用于處理控件間的聯(lián)動效果 * @left 被拖拽控件的真實移動位置 * @dx 被拖拽控件的真實偏移大小 */ @Override public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { if (changedView==mContent){ // 移動正文的同時也要移動側(cè)欄 mDeletePanel.offsetLeftAndRight(dx); }else{ mContent.offsetLeftAndRight(dx); } }
5.0在 clampViewPositionHorizontal方法中 固定被拖拽控件的水平位置,
/** * 固定被拖拽控件的水平位置, * 參數(shù)里的 left 是系統(tǒng)推薦移動到的位置,可以進行修正, * 方法返回的值就是 child 將要移動到的位置 */ @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第三步:
效果圖
1.0onViewReleased中根據(jù)來開局里面,判斷是否打開還是關(guān)閉
2.0 在 moveContent中第一次滑動
3.0computeScroll中,繼續(xù)滑動,直到滑動到指定的位置
4.0注意在onViewPositionChanged中手動刷新界面,調(diào)用invalidate方法
如果不手動刷新界面,效果展示不出來
/** * 當用戶松手時執(zhí)行 * @xvel 松手時在 X 方向的移動速度,如果為 正數(shù) 則說明是向右移動,如果是 負數(shù) 則說明是向左移動,如果為零,說明是靜止狀態(tài) */ @Override public void onViewReleased(View releasedChild, float xvel, float yvel) { if (xvel>0){ //向右移動 close(); }else if (xvel<0){ //向左移動 opend(); }else if (xvel>-mRang/2){// 靜止狀態(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) { // 開啟平滑滾動,如果返回 true 則說明要繼續(xù)刷新界面,保持滾動 if(mDragHelper.smoothSlideViewTo(mContent,left,0)){ invalidate(); } } @Override public void computeScroll() { // 繼續(xù)平滑滾動,如果返回 true 則說明要繼續(xù)刷新界面,保持滾動 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// 記錄上一個打開的面板。注意:一定要是 靜態(tài)變量
private static SwipeLayout preSwipeLayout;4.0在onViewPositionChanged中創(chuàng)建一個方法操作關(guān)閉面板
// 關(guān)閉上一個打開的面板 closePre();5.0closePre()在這個方法中,判斷當前面板的狀態(tài),并且根據(jù)狀態(tài),關(guān)閉上一個打開的面板
// 判斷當前面板是否正在打開,如果正在打開則將上一個打開的面板關(guān)閉 private void closePre() { //記錄舊狀態(tài) Status preStatus=status; if (mContent.getLeft()==-mRang){ //記錄當前面板已經(jīng)打開 status=status.OPENED; }else if (mContent.getLeft()==0){ //當前面板已經(jīng)關(guān)閉 status=status.CLOSED; }else { status=status.DRAGING; } // 如果當前面板舊狀態(tài)為關(guān)閉,并且新狀態(tài)為拖拽,那么此時可以關(guān)閉之前打開的面板 if (preStatus==status.CLOSED&&status==status.DRAGING){ if (preSwipeLayout!=null&&preSwipeLayout!=this){ // 關(guān)閉上一個面板 preSwipeLayout.close(); } // 將當前面板標記為 打開的面板 preSwipeLayout=this; } }以上就是Android中怎么實現(xiàn)條目拖拽刪除功能,小編相信有部分知識點可能是我們?nèi)粘9ぷ鲿姷交蛴玫降摹OM隳芡ㄟ^這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
當前標題:Android中怎么實現(xiàn)條目拖拽刪除功能
本文鏈接:http://weahome.cn/article/pcceci.html