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

首頁 > 系統 > Android > 正文

Android ViewDragHelper實現京東、淘寶拖拽詳情功能的實現

2019-10-22 18:12:39
字體:
來源:轉載
供稿:網友

先上效果圖,如果大家感覺不錯,請參考實例代碼,效果圖如下所述:

Android,ViewDragHelper,拖拽

要實現這個效果有三種方式:

① 手勢

② 動畫
③ android/106181.html">ViewDragHelper

這里我使用的是ViewDragHelper類.

public class ViewDragLayout extends ViewGroup {  //垂直方向的滑動速度  private static final int VEL_THRESHOLD = 300;  //垂直方向的滑動距離  private static final int DISTANCE_THRESHOLD = 300;  //上面可見的View  private View mTopView;  //下面詳情View  private View mBottomView;  //ViewDragHelper實例  private ViewDragHelper mViewDragHelper;  private GestureDetectorCompat mGestureDetectorCompat;  private int mFirstHeight;  public ViewDragLayout(Context context) {    super(context);    init();  }  public ViewDragLayout(Context context, AttributeSet attrs) {    super(context, attrs);    init();  }  public ViewDragLayout(Context context, AttributeSet attrs, int defStyleAttr) {    super(context, attrs, defStyleAttr);    init();  }  @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)  public ViewDragLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {    super(context, attrs, defStyleAttr, defStyleRes);    init();  }  private void init() {    mViewDragHelper = ViewDragHelper.create(this, 1.0f, new DragHelperCallback());    mGestureDetectorCompat = new GestureDetectorCompat(getContext(), new YScrollDetector());  }  @Override  protected void onFinishInflate() {    super.onFinishInflate();    mTopView = getChildAt(0);    mBottomView = getChildAt(1);   }  @Override  protected void onLayout(boolean changed, int l, int t, int r, int b) {    if (mTopView.getTop() == 0) {      mTopView.layout(l, 0, r, b-t );      mBottomView.layout(l, 0, r, b-t );      mFirstHeight = mTopView.getMeasuredHeight();      mBottomView.offsetTopAndBottom(mFirstHeight);    }else{         mTopView.layout(l, mTopView.getTop(), r, mTopView.getBottom());      mBottomView.layout(l, mBottomView.getTop(), r, mBottomView.getBottom());    }  }  @Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    measureChildren(widthMeasureSpec,heightMeasureSpec);    int maxWidth = MeasureSpec.getSize(widthMeasureSpec);    int maxHeight = MeasureSpec.getSize(heightMeasureSpec);    setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, 0),        resolveSizeAndState(maxHeight, heightMeasureSpec, 0));  }  private class DragHelperCallback extends ViewDragHelper.Callback {    @Override    public boolean tryCaptureView(View child, int pointerId) {      return true;    }    /**     * @param child     * @param top     * @param dy     * @return     */    @Override    public int clampViewPositionVertical(View child, int top, int dy) {      int finalTop=top;      if (child == mTopView) {        if (top > 0) {          finalTop=0;        }      }else if(child==mBottomView){               if(top<0){          finalTop=0;        }      }      return finalTop;    }    @Override    public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {      if (changedView == mTopView) {        mBottomView.offsetTopAndBottom(dy);      }else if (changedView==mBottomView){        mTopView.offsetTopAndBottom(dy);      }      ViewCompat.postInvalidateOnAnimation(ViewDragLayout.this);    }    /**     *     * @param releasedChild     * @param xvel 水平方向的速度(向右為正)     * @param yvel 豎直方向的速度(向下為正)     */    @Override    public void onViewReleased(View releasedChild, float xvel, float yvel) {      animTopOrBottom(releasedChild, yvel);    }  }  //動畫實現滾動  private void animTopOrBottom(View releasedChild, float yvel) {    int finalTop=0;    if (releasedChild == mTopView) {      if (yvel < -VEL_THRESHOLD || (releasedChild.getTop() < -DISTANCE_THRESHOLD)) {        finalTop=-mFirstHeight;      }    } else if (releasedChild == mBottomView) {      if (yvel > VEL_THRESHOLD || (releasedChild.getTop() > DISTANCE_THRESHOLD)) {        finalTop=mFirstHeight;      }    }    if (mViewDragHelper.smoothSlideViewTo(releasedChild, 0, finalTop)) {      ViewCompat.postInvalidateOnAnimation(this);    }  }  @Override  public void computeScroll() {    if (mViewDragHelper.continueSettling(true)) {      ViewCompat.postInvalidateOnAnimation(this);    }  }  //是否攔截手勢操作  @Override  public boolean onInterceptTouchEvent(MotionEvent ev) {    if (mTopView.getTop() < 0 && mTopView.getBottom() > 0) {      return false;    }    boolean isCanTouch = mGestureDetectorCompat.onTouchEvent(ev);    boolean shouldIntercept = mViewDragHelper.shouldInterceptTouchEvent(ev);    if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {      mViewDragHelper.processTouchEvent(ev);    }    return isCanTouch&&shouldIntercept;  }  //將touch事件交給ViewDragHelper處理  @Override  public boolean onTouchEvent(MotionEvent event) {     mViewDragHelper.processTouchEvent(event);    return true;  }  //垂直方向上才滾動  private class YScrollDetector extends GestureDetector.SimpleOnGestureListener {    @Override    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {      return Math.abs(distanceY) > Math.abs(distanceX);    }  }}

使用ViewDragLayout

<gesture.com.cn.widget.ViewDragLayout    android:id="@+id/view_drag_layout"    android:layout_width="match_parent"    android:layout_height="match_parent"    >    <FrameLayout      android:id="@+id/top_fragment_view"      android:layout_width="match_parent"      android:layout_height="match_parent"      />    <FrameLayout      android:id="@+id/bottom_fragment_view"      android:layout_width="match_parent"      android:layout_height="match_parent"/></gesture.com.cn.widget.ViewDragLayout>

bottom_fragment_view中使用了ScrollView,但是原生是不行的,所以這里我又將ScrollView重寫了一下

這里主要是處理dispatchTouchEvent(MotionEvent ev)方法,判斷將touch事件交給自己處理還是交給父View處理

public class CustomScrollView extends ScrollView {   //滾動臨界值  private int mTouchSlop;  //獲取初始X坐標  private float mRawX;  //獲取初始Y坐標  private float mRawY;  //是否向上滑動  private boolean mCanScrollUp;  //是否向下滑動  private boolean mCanScrollDown;  public CustomScrollView(Context context) {    super(context);    init();  }  public CustomScrollView(Context context, @Nullable AttributeSet attrs) {    super(context, attrs);    init();  }  public CustomScrollView(Context context, @Nullable AttributeSet attrs, int defStyle) {    super(context, attrs, defStyle);    init();  }  private void init() {    ViewConfiguration configuration = ViewConfiguration.get(getContext());    mTouchSlop = configuration.getScaledTouchSlop();  }  @Override  public boolean dispatchTouchEvent(MotionEvent ev) {    switch (ev.getActionMasked()) {      case MotionEvent.ACTION_DOWN:        mRawX = ev.getRawX();        mRawY = ev.getRawY();        mCanScrollUp = canScrollingUp();        mCanScrollDown = canScrollingDown();        //表示子View要自己消費這次事件,告訴父View不攔截這次的事件。        getParent().requestDisallowInterceptTouchEvent(true);        break;      case MotionEvent.ACTION_MOVE:        float xDis = Math.abs(mRawX - ev.getRawX());        float yDis = Math.abs(mRawY - ev.getRawY());        if (yDis > xDis && yDis > mTouchSlop) {          if (mRawY < ev.getRawY() && mCanScrollUp) {            //表示子View不消費這次事件,告訴父View攔截這次的事件。            getParent().requestDisallowInterceptTouchEvent(false);            return false;          }          if (mRawY > ev.getRawY() && mCanScrollDown) {            //表示子View不消費這次事件,告訴父View攔截這次的事件。            getParent().requestDisallowInterceptTouchEvent(false);            return false;          }        }        break;    }    return super.dispatchTouchEvent(ev);  }  /**   * 手指向下滑動(內容向上滑動)   * @return   */  private boolean canScrollingUp() {    if (ViewCompat.canScrollVertically(this, -1)) {      return false;    } else {      return true;    }  }  /**   * 手指向上滑動(內容向下滑動)   * @return   */  private boolean canScrollingDown() {    if (ViewCompat.canScrollVertically(this, 1)) {      return false;    } else {      return true;    }  }}

好了,具體拖拽代碼就是這些了,界面我用的兩個Fragment,相信大家也看出來了。里面大家換成自己的業務UI就可以了。

以上所述是小編給大家介紹的Android ViewDragHelper實現京東、淘寶拖拽詳情功能的實現,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復大家的!


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 册亨县| 枣强县| 和田市| 崇左市| 韩城市| 永吉县| 盐源县| 曲水县| 甘南县| 定陶县| 泸定县| 琼结县| 仙桃市| 登封市| 拜泉县| 贡嘎县| 岳西县| 元氏县| 马尔康县| 鄂托克旗| 杂多县| 肥东县| 清涧县| 孝义市| 东平县| 鹤庆县| 南和县| 温州市| 株洲县| 乌鲁木齐市| 临清市| 河北区| 太谷县| 翁牛特旗| 石阡县| 梅河口市| 康保县| 泌阳县| 江阴市| 民丰县| 清徐县|