国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android仿微信對話列表滑動刪除效果

2019-12-12 05:28:36
字體:
來源:轉載
供稿:網友

微信對話列表滑動刪除效果很不錯的,借鑒了github上SwipeListView(項目地址:https://github.com/likebamboo/SwipeListView),在其上進行了一些重構,最終實現了微信對話列表滑動刪除效果。

實現原理
 1.通過ListView的pointToPosition(int x, int y)來獲取按下的position,然后通過android.view.ViewGroup.getChildAt(position)來得到滑動對象swipeView
 2.在onTouchEvent中計算要滑動的距離,調用swipeView.scrollTo即可。

運行效果如下

下面是最核心的部分SwipeListView代碼: 

package com.fxsky.swipelist.widget;import android.annotation.SuppressLint;import android.content.Context;import android.content.res.TypedArray;import android.os.Handler;import android.os.Message;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.widget.ListView;import com.fxsky.swipelist.R;public class SwipeListView extends ListView { private Boolean mIsHorizontal; private View mPreItemView; private View mCurrentItemView; private float mFirstX; private float mFirstY; private int mRightViewWidth; // private boolean mIsInAnimation = false; private final int mDuration = 100; private final int mDurationStep = 10; private boolean mIsShown; public SwipeListView(Context context) { this(context,null); } public SwipeListView(Context context, AttributeSet attrs) { this(context, attrs,0); } public SwipeListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle);  TypedArray mTypedArray = context.obtainStyledAttributes(attrs,  R.styleable.swipelistviewstyle);   //獲取自定義屬性和默認值  mRightViewWidth = (int) mTypedArray.getDimension(R.styleable.swipelistviewstyle_right_width, 200);   mTypedArray.recycle();  } /** * return true, deliver to listView. return false, deliver to child. if * move, return true */ @Override public boolean onInterceptTouchEvent(MotionEvent ev) { float lastX = ev.getX(); float lastY = ev.getY(); switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mIsHorizontal = null; System.out.println("onInterceptTouchEvent----->ACTION_DOWN"); mFirstX = lastX; mFirstY = lastY; int motionPosition = pointToPosition((int)mFirstX, (int)mFirstY); if (motionPosition >= 0) {  View currentItemView = getChildAt(motionPosition - getFirstVisiblePosition());  mPreItemView = mCurrentItemView;  mCurrentItemView = currentItemView; } break; case MotionEvent.ACTION_MOVE: float dx = lastX - mFirstX; float dy = lastY - mFirstY; if (Math.abs(dx) >= 5 && Math.abs(dy) >= 5) {  return true; } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: System.out.println("onInterceptTouchEvent----->ACTION_UP"); if (mIsShown && (mPreItemView != mCurrentItemView || isHitCurItemLeft(lastX))) {  System.out.println("1---> hiddenRight");  /**  * 情況一:  * <p>  * 一個Item的右邊布局已經顯示,  * <p>  * 這時候點擊任意一個item, 那么那個右邊布局顯示的item隱藏其右邊布局  */  hiddenRight(mPreItemView); } break; } return super.onInterceptTouchEvent(ev); } private boolean isHitCurItemLeft(float x) { return x < getWidth() - mRightViewWidth; } /** * @param dx * @param dy * @return judge if can judge scroll direction */ private boolean judgeScrollDirection(float dx, float dy) { boolean canJudge = true; if (Math.abs(dx) > 30 && Math.abs(dx) > 2 * Math.abs(dy)) { mIsHorizontal = true; System.out.println("mIsHorizontal---->" + mIsHorizontal); } else if (Math.abs(dy) > 30 && Math.abs(dy) > 2 * Math.abs(dx)) { mIsHorizontal = false; System.out.println("mIsHorizontal---->" + mIsHorizontal); } else { canJudge = false; } return canJudge; } /** * return false, can't move any direction. return true, cant't move * vertical, can move horizontal. return super.onTouchEvent(ev), can move * both. */ @Override public boolean onTouchEvent(MotionEvent ev) { float lastX = ev.getX(); float lastY = ev.getY(); switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: System.out.println("---->ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: float dx = lastX - mFirstX; float dy = lastY - mFirstY; // confirm is scroll direction if (mIsHorizontal == null) {  if (!judgeScrollDirection(dx, dy)) {  break;  } } if (mIsHorizontal) {  if (mIsShown && mPreItemView != mCurrentItemView) {  System.out.println("2---> hiddenRight");  /**  * 情況二:  * <p>  * 一個Item的右邊布局已經顯示,  * <p>  * 這時候左右滑動另外一個item,那個右邊布局顯示的item隱藏其右邊布局  * <p>  * 向左滑動只觸發該情況,向右滑動還會觸發情況五  */  hiddenRight(mPreItemView);  }  if (mIsShown && mPreItemView == mCurrentItemView) {  dx = dx - mRightViewWidth;  System.out.println("======dx " + dx);  }  // can't move beyond boundary  if (dx < 0 && dx > -mRightViewWidth) {  mCurrentItemView.scrollTo((int)(-dx), 0);  }  return true; } else {  if (mIsShown) {  System.out.println("3---> hiddenRight");  /**  * 情況三:  * <p>  * 一個Item的右邊布局已經顯示,  * <p>  * 這時候上下滾動ListView,那么那個右邊布局顯示的item隱藏其右邊布局  */  hiddenRight(mPreItemView);  } } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: System.out.println("============ACTION_UP"); clearPressedState(); if (mIsShown) {  System.out.println("4---> hiddenRight");  /**  * 情況四:  * <p>  * 一個Item的右邊布局已經顯示,  * <p>  * 這時候左右滑動當前一個item,那個右邊布局顯示的item隱藏其右邊布局  */  hiddenRight(mPreItemView); } if (mIsHorizontal != null && mIsHorizontal) {  if (mFirstX - lastX > mRightViewWidth / 2) {  showRight(mCurrentItemView);  } else {  System.out.println("5---> hiddenRight");  /**  * 情況五:  * <p>  * 向右滑動一個item,且滑動的距離超過了右邊View的寬度的一半,隱藏之。  */  hiddenRight(mCurrentItemView);  }  return true; } break; } return super.onTouchEvent(ev); } private void clearPressedState() { // TODO current item is still has background, issue mCurrentItemView.setPressed(false); setPressed(false); refreshDrawableState(); // invalidate(); } private void showRight(View view) { System.out.println("=========showRight"); Message msg = new MoveHandler().obtainMessage(); msg.obj = view; msg.arg1 = view.getScrollX(); msg.arg2 = mRightViewWidth; msg.sendToTarget(); mIsShown = true; } private void hiddenRight(View view) { System.out.println("=========hiddenRight"); if (mCurrentItemView == null) { return; } Message msg = new MoveHandler().obtainMessage();// msg.obj = view; msg.arg1 = view.getScrollX(); msg.arg2 = 0; msg.sendToTarget(); mIsShown = false; } /** * show or hide right layout animation */ @SuppressLint("HandlerLeak") class MoveHandler extends Handler { int stepX = 0; int fromX; int toX; View view; private boolean mIsInAnimation = false; private void animatioOver() { mIsInAnimation = false; stepX = 0; } @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (stepX == 0) { if (mIsInAnimation) {  return; } mIsInAnimation = true; view = (View)msg.obj; fromX = msg.arg1; toX = msg.arg2; stepX = (int)((toX - fromX) * mDurationStep * 1.0 / mDuration); if (stepX < 0 && stepX > -1) {  stepX = -1; } else if (stepX > 0 && stepX < 1) {  stepX = 1; } if (Math.abs(toX - fromX) < 10) {  view.scrollTo(toX, 0);  animatioOver();  return; } } fromX += stepX; boolean isLastStep = (stepX > 0 && fromX > toX) || (stepX < 0 && fromX < toX); if (isLastStep) { fromX = toX; } view.scrollTo(fromX, 0); invalidate(); if (!isLastStep) { this.sendEmptyMessageDelayed(0, mDurationStep); } else { animatioOver(); } } } public int getRightViewWidth() { return mRightViewWidth; } public void setRightViewWidth(int mRightViewWidth) { this.mRightViewWidth = mRightViewWidth; }}

Demo下載地址:http://xiazai.VeVB.COm/201608/yuanma/SwipeListView(VeVB.COm).rar

Demo中SwipeAdapter源碼中有一處由于粗心寫錯了,會導致向下滑動時出現數組越界異常,現更正如下:

@Override public int getCount() {// return 100; return data.size(); }

本文已被整理到了《Android微信開發教程匯總》,歡迎大家學習閱讀。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 额尔古纳市| 福安市| 醴陵市| 松原市| 金乡县| 柳河县| 中山市| 永修县| 寿宁县| 仁怀市| 宁都县| 乳源| 滕州市| 武清区| 峨眉山市| 敖汉旗| 确山县| 那曲县| 南召县| 武隆县| 昆明市| 中江县| 廉江市| 临颍县| 闸北区| 宣化县| 河西区| 安多县| 平定县| 新郑市| 孝义市| 板桥市| 电白县| 昌宁县| 滦平县| 芮城县| 安顺市| 福清市| 长治县| 雷山县| 贞丰县|