最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時間:2016年08月31日 11:16:52   作者:FX_SKY  
這篇文章主要為大家詳細介紹了Android仿微信對話列表滑動刪除效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下

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

實現(xiàn)原理
 1.通過ListView的pointToPosition(int x, int y)來獲取按下的position,然后通過android.view.ViewGroup.getChildAt(position)來得到滑動對象swipeView
 2.在onTouchEvent中計算要滑動的距離,調(diào)用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的右邊布局已經(jīng)顯示,
  * <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的右邊布局已經(jīng)顯示,
  * <p>
  * 這時候左右滑動另外一個item,那個右邊布局顯示的item隱藏其右邊布局
  * <p>
  * 向左滑動只觸發(fā)該情況,向右滑動還會觸發(fā)情況五
  */
  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的右邊布局已經(jīng)顯示,
  * <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的右邊布局已經(jīng)顯示,
  * <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.jb51.net/201608/yuanma/SwipeListView(jb51.net).rar

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

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

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

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android高仿微信5.2.1主界面及消息提醒

    Android高仿微信5.2.1主界面及消息提醒

    這篇文章主要為大家詳細介紹了Android高仿微信5.2.1主界面及消息提醒,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • RecyclerView+CardView實現(xiàn)橫向卡片式滑動效果

    RecyclerView+CardView實現(xiàn)橫向卡片式滑動效果

    這篇文章主要為大家詳細介紹了RecyclerView+CardView實現(xiàn)橫向卡片式滑動效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • Android開啟新線程播放背景音樂

    Android開啟新線程播放背景音樂

    這篇文章主要為大家詳細介紹了Android開啟新線程播放背景音樂,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Android iconify 使用詳解

    Android iconify 使用詳解

    iconify是一個矢量圖標庫,包含使用 Dave Gandy 制作的超過370中矢量字體圖標,可以使Android應用開發(fā)者免于制作多種適用于不同屏幕大小尺寸的圖片,從而提高開發(fā)者工作效率。下文重點給大家介紹android iconify 使用,感興趣的朋友一起學習吧
    2017-08-08
  • Android開發(fā)之媒體播放工具類完整示例

    Android開發(fā)之媒體播放工具類完整示例

    這篇文章主要介紹了Android開發(fā)之媒體播放工具類,結(jié)合完整實例形式分析了基于MediaPlayer的事件監(jiān)聽與多媒體文件播放相關(guān)操作技巧,需要的朋友可以參考下
    2018-02-02
  • Android編程之播放器MediaPlayer實現(xiàn)均衡器效果示例

    Android編程之播放器MediaPlayer實現(xiàn)均衡器效果示例

    這篇文章主要介紹了Android編程之播放器MediaPlayer實現(xiàn)均衡器效果,結(jié)合具體實例形式分析了Android調(diào)用MediaPlayer相關(guān)API構(gòu)造均衡器的具體步驟與相關(guān)功能實現(xiàn)方法,需要的朋友可以參考下
    2017-08-08
  • 詳解如何從原生Android 跳轉(zhuǎn)到hbuilder項目

    詳解如何從原生Android 跳轉(zhuǎn)到hbuilder項目

    這篇文章主要介紹了從原生Android 跳轉(zhuǎn)到hbuilder項目,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • Android 日期選擇器實例代碼

    Android 日期選擇器實例代碼

    這篇文章主要介紹了Android 日期選擇器實例代碼,需要的朋友可以參考下
    2017-05-05
  • Android手機內(nèi)存中文件的讀寫方法小結(jié)

    Android手機內(nèi)存中文件的讀寫方法小結(jié)

    這篇文章主要介紹了Android手機內(nèi)存中文件的讀寫方法,實例總結(jié)了Android針對文件讀寫操作的相關(guān)技巧,非常具有實用價值,需要的朋友可以參考下
    2015-04-04
  • android編程實現(xiàn)懸浮窗體的方法

    android編程實現(xiàn)懸浮窗體的方法

    這篇文章主要介紹了android編程實現(xiàn)懸浮窗體的方法,以實例形式較為詳細的分析了Android懸浮窗體的權(quán)限控制、布局及功能實現(xiàn)技巧,非常具有實用價值,需要的朋友可以參考下
    2015-11-11

最新評論

博湖县| 台东县| 沂水县| 麻阳| 汤阴县| 水富县| 阿瓦提县| 漾濞| 定日县| 曲靖市| 苏尼特左旗| 墨玉县| 大埔区| 施甸县| 新竹县| 洛川县| 驻马店市| 萨迦县| 平南县| 巫溪县| 吴江市| 黄石市| 灵丘县| 西乌| 龙山县| 广安市| 孝昌县| 济南市| 句容市| 河曲县| 攀枝花市| 海安县| 米易县| 多伦县| 大方县| 巴林左旗| 台江县| 扎赉特旗| 渭源县| 商丘市| 苍溪县|