学习记录:自定义View(仿汽车之家下拉选择页面 继承自FrameLayout)

    目前现在的状态还是对于常用的类所包装的函数不是太了解的状态。

    一个重要的辅助类: ViewDragHelper;

    新建ViewDragHelper对象时,需要传入callback回调函数对象:

 private ViewDragHelper.Callback mCallBack = new ViewDragHelper.Callback(){}

回调函数中需要复写的几个重要方法:

@Override
        public boolean tryCaptureView(View child, int pointerId) {
            return false;
        }

简单地说,直接返回true,其view可以拖动

 @Override
        public int clampViewPositionVertical(View child, int top, int dy) {
            return top;
        }

复写tryCaptureView后复写上面函数能实现竖直方向的拖动,水平方向同理

 @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
            int forViewTop = forView.getTop();
            if(forViewTop > backHeight/2){
              
  mViewDragHelper.settleCapturedViewAt(0,backHeight);
backViewIsOpen = true; }else { mViewDragHelper.settleCapturedViewAt(0,0); backViewIsOpen = false; } invalidate(); }

        不是太明白的地方是最后的invalidate,实际操作中,如果没有这个函数,好像settlelcaptureViewAt()函数没有用。只能理解为只有invalidate之后 这个函数才能用吧


这又是一个很重要的方法:当手指不再拖动时会执行这个方法,其中:

settleCapturedViewAt
 /**
     * Settle the captured view at the given (left, top) position.
     * The appropriate velocity from prior motion will be taken into account.
     * If this method returns true, the caller should invoke {@link #continueSettling(boolean)}
     * on each subsequent frame to continue the motion until it returns false. If this method
     * returns false there is no further work to do to complete the movement.
     *
     * @param finalLeft Settled left edge position for the captured view
     * @param finalTop Settled top edge position for the captured view
     * @return true if animation should continue through {@link #continueSettling(boolean)} calls
     */
    public boolean settleCapturedViewAt(int finalLeft, int finalTop) {
        if (!mReleaseInProgress) {
            throw new IllegalStateException("Cannot settleCapturedViewAt outside of a call to "
                    + "Callback#onViewReleased");
        }

        return forceSettleCapturedViewAt(finalLeft, finalTop,
                (int) mVelocityTracker.getXVelocity(mActivePointerId),
                (int) mVelocityTracker.getYVelocity(mActivePointerId));
    }


源码解释:


需要配套一个响应滑动的函数才能实现效果;

@Override
    public void computeScroll() {
        if (mViewDragHelper.continueSettling(true)) {
            invalidate();
        }
    }
源码解释是这样的:
/**
     * Called by a parent to request that a child update its values for mScrollX
     * and mScrollY if necessary. This will typically be done if the child is
     * animating a scroll using a {@link android.widget.Scroller Scroller}
     * object.
     */
    public void computeScroll() {
    }

continueSetting()的源码解释:

/**
     * Move the captured settling view by the appropriate amount for the current time.
     * If continueSettling returns true, the caller should call it again
     * on the next frame to continue.
     *
     * @param deferCallbacks true if state callbacks should be deferred via posted message.
     *                       Set this to true if you are calling this method from
     *                       {@link android.view.View#computeScroll()} or similar methods
     *                       invoked as part of layout or drawing.
     * @return true if settle is still in progress
     */
 public boolean continueSettling(boolean deferCallbacks) 

还有一个检测listview还能不能 向上向下滑动,

forView.canScrollVertically(-1);
官方解释:
/**
     * Check if this view can be scrolled vertically in a certain direction.
     *
     * @param direction Negative to check scrolling up, positive to check scrolling down.
     * @return true if this view can be scrolled in the specified direction, false otherwise.
     */
    public boolean canScrollVertically(int direction) 





你可能感兴趣的:(学习记录:自定义View(仿汽车之家下拉选择页面 继承自FrameLayout))