안 드 로 이 드 위 챗 대화 목록 슬라이딩 삭제 효과

위 챗 대화 목록 슬라이딩 삭제 효과 가 좋 습 니 다.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;
 }
}
데모 다운로드 주소:http://xiazai.jb51.net/201608/yuanma/SwipeListView(jb51.net).rar
Demo 에서 SwipeAdapter 소스 코드 중 하 나 는 부주의 로 잘못 썼 기 때문에 아래로 미 끄 러 질 때 배열 의 경계 이상 이 발생 할 수 있 습 니 다.다음 과 같이 정정 합 니 다.

@Override
 public int getCount() {
// return 100;
 return data.size();
 }
본 고 는 이미《Android 위 챗 개발 튜 토리 얼 집계》로 정리 되 었 으 니,여러분 의 학습 과 독 서 를 환영 합 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기