ViewDragHelper简单使用

首先扯点别的:感觉保护好身体真的很重要,前几天膝盖又拉伤了,今天跑了会步感觉有点疼,看样最近一个月是不能跑步了。

今天看了看鸿洋大神的ViewDrawHelper感觉写的不错,学习一下。

ViewDragHelper类定义:

ViewDragHelper对于重写ViewGroup来说是一个有用的类。它提供了许多有用的操作和状态跟踪,允许用户在ViewGroup中拖动和重新放置view。

自定义一个VDHLayout类继承自LinearLayout

public class VDHLayout extends LinearLayout
{
//定义一个ViewDragHelper 
    private ViewDragHelper mDragger;

    public VDHLayout(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        //实例化一个ViewDragHelper,第一个参数表示当前的VDHLayout
        //第二个参数表示拖动的敏感度,第三个参数是回调接口(相当有用)
        mDragger = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback()
        {
			
			//在这个方法里决定哪些子view可以被拖动,返回true表示所有的子view都可以被拖动
            @Override
            public boolean tryCaptureView(View child, int pointerId)
            {
                return true;
            }
			//决定被拖动的子view横向移动范围,直接返回left表示无显示
            @Override
            public int clampViewPositionHorizontal(View child, int left, int dx)
            {
                return left;
            }
			//决定被拖动子view的纵向移动返回,直接返回top表示无限制
            @Override
            public int clampViewPositionVertical(View child, int top, int dy)
            {
                return top;
            }
        });
    }

//重写拦截事件
   @Override
    public boolean onInterceptTouchEvent(MotionEvent event)
    {
        return mDragger.shouldInterceptTouchEvent(event);
    }

//重写触摸事件
    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        mDragger.processTouchEvent(event);
        return true;
    }
}

如果我们只让子view在ViewGroup内部移动,回调方法要做修改如下

  @Override
            public int clampViewPositionVertical(View child, int top, int dy) {
                //top表示child最上边的移动范围
                int topBound = getPaddingTop();//上边界为VHDLayout的topPadding
                //下边界为VDHLayout的高度减去bottomPadding再减去child的高度
                int bottomBound = getHeight() - getPaddingBottom() - child.getHeight();
                top = Math.min(Math.max(top, topBound), bottomBound);
                return top;
            }

            @Override
            public int clampViewPositionHorizontal(View child, int left, int dx) {
                //left 表示被拖动的子view的最左边可移动范围
                int leftBound = getPaddingLeft();//左边界为VDHLayout的leftPadding
                //右边界为VDHLayout的宽度减去rightPadding再减去子view的宽度
                int rightBound = getWidth() - getPaddingRight() - child.getWidth();
                Log.e("tag", "leftBound" + leftBound + ",left" + left + ",rightBound" + rightBound);
                left = Math.min(Math.max(left, leftBound), rightBound);
                return left;
            }

使用自定义VDHLayout很简单,直接在xml文件里面当做一个LinearLayout就可以,在里面放几个TextView,就可以愉快的拖动了。(要注意这时候TextView的android:clickable=“false”).这时候如果TextView是可以点击的,会出现子view不能拖动的情况,后面再说。

ViewDragHelper的其他功能

1.边界检测
2.拖动子view松开手后,子view回到原来的位置

修改代码,把完整的代码写出来

/**
 * Created by Administrator on 2016/9/4.
 */
public class VDHLayout extends LinearLayout {

    private ViewDragHelper mDragger;
    //定义三个View
    private View mDragView;
    private View mAutoBackView;
    private View mEdgeTrackerView;
    //定义一个点,用来记录mAutoBackView的初始位置
    private Point mAutoBackOriginPos = new Point();

    public VDHLayout(Context context) {
        this(context, null);
    }

    public VDHLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public VDHLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mDragger = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() {
            @Override
            public boolean tryCaptureView(View child, int pointerId) {
                //mEdgeTrackerView禁止直接移动,mDragView ,mAutoBackView可以正常被拖动
                return child == mDragView || child == mAutoBackView;
            }

            @Override
            public int clampViewPositionVertical(View child, int top, int dy) {
                //top表示child最上边的移动范围
                int topBound = getPaddingTop();//上边界为VHDLayout的topPadding
                //下边界为VDHLayout的高度减去bottomPadding再减去child的高度
                int bottomBound = getHeight() - getPaddingBottom() - child.getHeight();
                top = Math.min(Math.max(top, topBound), bottomBound);
                return top;
            }

            @Override
            public int clampViewPositionHorizontal(View child, int left, int dx) {
                //left 表示被拖动的子view的最左边可移动范围
                int leftBound = getPaddingLeft();//左边界为VDHLayout的leftPadding
                //右边界为VDHLayout的宽度减去rightPadding再减去子view的宽度
                int rightBound = getWidth() - getPaddingRight() - child.getWidth();
                left = Math.min(Math.max(left, leftBound), rightBound);
                return left;
            }

           //如果子view是可点击的,这个方法要重写
            @Override
            public int getViewHorizontalDragRange(View child) {
                return getMeasuredWidth()-child.getMeasuredWidth();
            }

           //如果子view是可点击的,这个方法要重写
            @Override
            public int getViewVerticalDragRange(View child) {
                return getMeasuredHeight()-child.getMeasuredHeight();
            }

            //手指释放的时候回调
            @Override
            public void onViewReleased(View releasedChild, float xvel, float yvel) {
                //mAutoBackView手指释放时可以自动回去
                if (releasedChild == mAutoBackView)
                {
                    mDragger.settleCapturedViewAt(mAutoBackOriginPos.x, mAutoBackOriginPos.y);
                    invalidate();
                }
            }

//边界开始拖动时候的回调
            @Override
            public void onEdgeDragStarted(int edgeFlags, int pointerId) {
                mDragger.captureChildView(mEdgeTrackerView, pointerId);
            }
        });
        //允许拖动左边界
        mDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return mDragger.shouldInterceptTouchEvent(ev);
    }

//重写计算滚动的方法
    @Override
    public void computeScroll() {
        if(mDragger.continueSettling(true))
        {
            invalidate();
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mDragger.processTouchEvent(event);
        return true;
    }

//确定子view的位置后,得到mAutoBackView的初始位置
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
       mAutoBackOriginPos.x=mAutoBackView.getLeft();
        mAutoBackOriginPos.y=mAutoBackView.getTop();
    }

//再加载完ziview以后,给定义的三个view赋值
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mDragView = getChildAt(0);
        mAutoBackView = getChildAt(1);
        mEdgeTrackerView = getChildAt(2);
    }
}

在onLayout之后保存了mAutoBackView的开始位置信息,最主要还是重写了Callback中
的onViewReleased,我们在onViewReleased中判断如果是mAutoBackView则调用
settleCapturedViewAt回到初始的位置。大家可以看到紧随其后的代码是invalidate();
因为其内部使用的是mScroller.startScroll,所以别忘了需要invalidate()以及结合
computeScroll方法一起。

mEdgeTrackerView,我们在onEdgeDragStarted回调方法中,主动通过
captureChildView对其进行捕获,该方法可以绕过tryCaptureView,所以我们的
tryCaptureView虽然并为返回true,但却不影响。注意如果需要使用边界检测需要添加上
mDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);

###子view的点击事件影响拖动 ##
如果子view默认是可点击的比如button,或者你给子view添加了clickable=“true”的属性,在回调接口里面,要添加下面的两个方法,只有这两个方法返回大于0的值才能正常的捕获,方法的返回值应当是该childView横向或者纵向的移动的范围

@Override
public int getViewHorizontalDragRange(View child){
     return getMeasuredWidth()-child.getMeasuredWidth();
}

@Override
public int getViewVerticalDragRange(View child){
     return getMeasuredHeight()-child.getMeasuredHeight();
}

如果只需要一个方向移动,可以只复写一个。

##实现网易新闻图集新闻底部文字介绍布局

先看看效果

这里写图片描述

代码参考自:https://github.com/Rukey7/DragSlopLayout。我只是在这个代码基础上删掉了其他无关的代码。强烈建议看看完整的代码,人家那个代码写的叫一个666。
中间的ImageView是TouchImageView,使用Glide加载图片的时候要有占位图,不然这个TouchImageView加载不出图像来。

删减后的代码

public class DragSlopLayout extends FrameLayout {

    private static final String TAG = "DragSlopLayout";
    // 固定高度
    private int mFixHeight;
    // 最大高度
    private int mMaxHeight;
    // 拖拽模式的展开状态Top值
    private int mExpandedTop;
    // 拖拽模式的收缩状态Top值
    private int mCollapsedTop;
    // 是否处于拖拽状态
    private boolean mIsDrag = false;
    // 可拖拽的视图,为布局的第2个子视图
    private View mDragView;
    // 拖拽帮助类
    private ViewDragHelper mDragHelper;
    // 关联的 ScrollView,实现垂直方向的平滑滚动
    private View mAttachScrollView;
    // DragView的Top属性值
    private int mDragViewTop = 0;
    // 回升滚动辅助类
    private ObjectAnimator dragOutAnimator;
    private ObjectAnimator dragInAnimator;

    public DragSlopLayout(Context context) {
        this(context, null);
    }

    public DragSlopLayout(Context context, AttributeSet attrs) {
        this(context, attrs, -1);
    }

    public DragSlopLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs, defStyleAttr);
    }

    private void init(Context context, AttributeSet attrs, int defStyleAttr) {
        mDragHelper = ViewDragHelper.create(this, 1.0f, callback);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DragSlopLayout, defStyleAttr, 0);
        mFixHeight = a.getDimensionPixelOffset(R.styleable.DragSlopLayout_fix_height, ScreenUtil.dpToPx(context, 180));
        mMaxHeight = a.getDimensionPixelOffset(R.styleable.DragSlopLayout_max_height, ScreenUtil.dpToPx(context, 260));
        a.recycle();
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        int childCount = getChildCount();
        if (childCount < 2) {
            throw new IllegalArgumentException("DragLayout must contains two sub-views.");
        }
        mDragView = getChildAt(1);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        Log.e(TAG, "onMeasure");
        if (mMaxHeight > getMeasuredHeight()) {
            //最大高度不超过布局高度
            mMaxHeight = getMeasuredHeight();
        }
        View childView = getChildAt(1);
        MarginLayoutParams lp = (MarginLayoutParams) childView.getLayoutParams();
        int childWidth = childView.getMeasuredWidth();
        int childHeight = childView.getMeasuredHeight();
        // 限定视图的最大高度
        if (childHeight > mMaxHeight) {
            childView.measure(MeasureSpec.makeMeasureSpec(childWidth - lp.leftMargin - lp.rightMargin, MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec(mMaxHeight - lp.topMargin - lp.bottomMargin, MeasureSpec.EXACTLY));
        }
        //限定视图最小高度
        if (childHeight < mFixHeight) {
            childView.measure(MeasureSpec.makeMeasureSpec(childWidth - lp.leftMargin - lp.rightMargin, MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec(mFixHeight - lp.topMargin - lp.bottomMargin, MeasureSpec.EXACTLY));
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        View childView = getChildAt(1);
        MarginLayoutParams lp = (MarginLayoutParams) childView.getLayoutParams();
        int childWidth = childView.getMeasuredWidth();
        int childHeight = childView.getMeasuredHeight();
        mExpandedTop = b - childHeight;
        //向下滑动时最小高度为固定高度
        mCollapsedTop = b - mFixHeight;
        //可拖拽view的top属性设为固定高度
        mDragViewTop = b - mFixHeight;
        if (mAttachScrollView != null)
            mAttachScrollView.scrollTo(0, 0);
        childView.layout(lp.leftMargin, mDragViewTop, lp.leftMargin + childWidth, mDragViewTop + childHeight);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (MotionEventCompat.getActionMasked(ev)) {
            //手抬起mIsDrag置为false
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                mIsDrag = false;
                break;
        }
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // 调用父类的方法,避免可能出现的 IllegalArgumentException: pointerIndex out of range
        super.onInterceptTouchEvent(ev);
        boolean isIntercept = mDragHelper.shouldInterceptTouchEvent(ev);
        if (isNeedIntercept(ev)) {
            isIntercept = true;
        }
        return isIntercept;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getActionMasked() == MotionEvent.ACTION_DOWN && (
                mDragHelper.isViewUnder(mDragView, (int) event.getX(), (int) event.getY()))) {
            //当触摸点在dragView范围之内,把mIsDrag置为true
            Log.e(TAG, "onTouchEvent MotionEvent.ACTION_DOWN");
            mIsDrag = true;
        } else {
            mDragHelper.processTouchEvent(event);
        }
        return mIsDrag;
    }

    /**
     * 可拖拽布局滚出屏幕
     *
     * @param duration 时间
     */
    public void scrollOutScreen(int duration) {
        Log.e(TAG, "scrollOutScreen");
        if (dragOutAnimator == null) {
            dragOutAnimator = ObjectAnimator.ofFloat(mDragView, "translationY", 0, mMaxHeight)
                    .setDuration(duration);
        }
        dragOutAnimator.start();
    }

    /**
     * 可拖拽布局滚进屏幕
     *
     * @param duration 时间
     */
    public void scrollInScreen(int duration) {
        Log.e(TAG, "scrollInScreen");
        if (dragInAnimator == null) {
            dragInAnimator = ObjectAnimator.ofFloat(mDragView, "translationY", mMaxHeight, 0)
                    .setDuration(duration);
        }
        dragInAnimator.start();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (dragOutAnimator != null && dragOutAnimator.isRunning())
            dragOutAnimator.cancel();
        if (dragInAnimator != null && dragInAnimator.isRunning())
            dragInAnimator.cancel();
    }

    private ViewDragHelper.Callback callback = new ViewDragHelper.Callback() {

        @Override
        public boolean tryCaptureView(View child, int pointerId) {
            //只有mDragView才可以拖动
            return child == mDragView;
        }

        @Override
        public int clampViewPositionVertical(View child, int top, int dy) {
            if (mAttachScrollView != null) {
                /**
                 * mAttachScrollView.getScrollY() > 0 : 如果mAttachScrollView向上滚动了,那么向下拖动的时候,先让mAttachScrollView滚动到初始位置
                 * (mDragView.getTop() == mExpandedTop && dy < 0) :当向上拖动mDragView到了最高的高度后继续向上拖动,就让ScrollView向上滚动,
                 */
                if (mAttachScrollView.getScrollY() > 0 || (mDragView.getTop() == mExpandedTop && dy < 0)) {
                    mAttachScrollView.scrollBy(0, -dy);
                    return mExpandedTop;
                }
            }
            int newTop = Math.max(mExpandedTop, top);
            newTop = Math.min(mCollapsedTop, newTop);
            return newTop;
        }

        @Override
        public int getViewVerticalDragRange(View child) {
            //可拖动范围是mDragView的高度
            return child == mDragView ? child.getHeight() : 0;
        }
    };

    @Override
    public void computeScroll() {
        if (mDragHelper.continueSettling(true)) {
            invalidate();
        }
    }
    
    /**
     * 设置关联的 ScrollView 如果有的话,目前只支持 ScrollView 和 NestedScrollView 及其自视图
     *
     * @param attachScrollView ScrollView or NestedScrollView
     */
    public void setAttachScrollView(View attachScrollView) {
        if (!isScrollView(attachScrollView)) {
            throw new IllegalArgumentException("The view must be ScrollView or NestedScrollView.");
        }
        mAttachScrollView = attachScrollView;
    }

    private boolean isNeedIntercept(MotionEvent ev) {
        if (mAttachScrollView == null) {
            return false;
        }
        int y = (int) ev.getY() - mDragView.getTop();
        //如果拖拽的区域是关联的ScrollView的区域,拦截事件
        if (mDragHelper.isViewUnder(mAttachScrollView, (int) ev.getX(), y)) {
            return true;
        }
        return false;
    }

    /**
     * 判断视图是否为 ScrollView or NestedScrollView 或它的子类
     *
     * @param view View
     * @return
     */
    private boolean isScrollView(View view) {
        boolean isScrollView = false;
        if (view instanceof ScrollView || view instanceof NestedScrollView) {
            isScrollView = true;
        } else {
            ViewParent parent = view.getParent();
            while (parent != null) {
                if (parent instanceof ScrollView || parent instanceof NestedScrollView) {
                    isScrollView = true;
                    break;
                }
            }
        }
        return isScrollView;
    }
}

实现思想:

  1. 在onMeasure( )方法中限定可拖动布局mDragView最小高度为为固定高度mFixHeight和mDragView最大高度不超过向上拖动时的最大高度mMaxHeight。
  2. 在onLayout( )方法中把mDragView向下偏移一定的高度。
  3. 使用ViewDragHelper来使mDragView可以被拖动。当向上拖动的时候,不超过mDragView的高度不超过最大高度mMaxHeight;当向下拖动的时候,mDragView的高度不小于mFixHeight。
  4. 不让mDragView中的ScrollView或者NestedScrollView处理事件,而是在ViewDragHelper的回调接口的clampViewPositionVertical( )方法中,决定ScrollView或者NestedScrollView是否可以滚动。

###使用DragSlopLayout

布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/black">

    <com.hm.viewdemo.widget.DragSlopLayout
        android:id="@+id/drag_slop_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentBottom="true"
        android:background="@android:color/transparent"
        app:fix_height="180dp">

        <android.support.v4.view.ViewPager
            android:id="@+id/view_pager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#99000000">

            <TextView
                android:id="@+id/text_title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="12dp"
                android:layout_toLeftOf="@+id/text_number_now"
                android:textColor="#ffffff"/>

            <TextView
                android:id="@+id/text_number_now"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="12dp"
                android:layout_toLeftOf="@+id/text_number_sum"
                android:textColor="#ffffff"
                android:textSize="12sp"/>

            <TextView
                android:id="@+id/text_number_sum"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_marginRight="12dp"
                android:layout_marginTop="12dp"
                android:textColor="#ffffff"
                android:textSize="12sp"/>

            <android.support.v4.widget.NestedScrollView
                android:id="@+id/nested_scroll_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/text_title"
                android:layout_marginLeft="12dp"
                android:layout_marginRight="12dp">

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

                    <TextView
                        android:id="@+id/text_content"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="@string/TomHardy"
                        android:textColor="#ffffff"/>

                    <TextView
                        android:id="@+id/text_press"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_below="@+id/text_content"
                        android:layout_marginBottom="12dp"
                        android:layout_marginTop="12dp"
                        android:text="网易新闻"
                        android:textColor="#ffffff"/>

                    <TextView
                        android:id="@+id/text_date"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_below="@+id/text_content"
                        android:layout_margin="12dp"
                        android:layout_toRightOf="@+id/text_press"
                        android:text="2017-6-23"
                        android:textColor="#ffffff"/>

                </RelativeLayout>

            </android.support.v4.widget.NestedScrollView>

        </RelativeLayout>

    </com.hm.viewdemo.widget.DragSlopLayout>

    <RelativeLayout
        android:id="@+id/rl_top"
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:background="@drawable/bg_album_top">

        <ImageView
            android:id="@+id/img_back"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:paddingBottom="12dp"
            android:paddingTop="12dp"
            app:srcCompat="@drawable/ic_back"/>

        <ImageView
            android:id="@+id/img_share"
            android:layout_width="22dp"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_marginRight="12dp"
            android:layout_marginTop="12dp"
            app:srcCompat="@drawable/ic_share_white"/>

    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/rl_hide"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_alignParentBottom="true"
        android:background="#99000000"
        android:paddingLeft="16dp"
        android:paddingRight="10dp"
        android:visibility="invisible">

        <TextView
            android:id="@+id/text_hide_number_now"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:textColor="@android:color/white"
            android:textSize="16sp"/>

        <TextView
            android:id="@+id/text_hide_number_sum"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginRight="10dp"
            android:layout_toRightOf="@+id/text_hide_number_now"
            android:paddingTop="2dp"
            android:textColor="@android:color/white"
            android:textSize="14sp"/>

    </RelativeLayout>

</RelativeLayout>

Activity代码

public class DragSlopLayoutActivity extends BaseActivity {

    private static final String TAG = "DragSlopLayoutActivity";

    @BindView(R.id.view_pager)
    ViewPager viewPager;
    @BindView(R.id.drag_slop_layout)
    DragSlopLayout dragSlopLayout;
    @BindView(R.id.text_title)
    TextView textDragTitle;
    @BindView(R.id.text_content)
    TextView textDragContent;
    @BindView(R.id.text_press)
    TextView textDragPress;
    @BindView(R.id.text_date)
    TextView textDragDate;
    @BindView(R.id.nested_scroll_view)
    NestedScrollView scrollViewDragContent;
    @BindView(R.id.rl_top)
    RelativeLayout rlTop;
    @BindView(R.id.text_hide_number_now)
    TextView textHideNumberNow;
    @BindView(R.id.text_hide_number_sum)
    TextView textHideNumberSum;
    @BindView(R.id.rl_hide)
    RelativeLayout rlHide;
    @BindView(R.id.text_number_now)
    TextView textNowNumber;
    @BindView(R.id.text_number_sum)
    TextView textTotalNumber;

    private List<String> imageList;
    private List<String> contentList;
    private AlbumAdapter adapter;

    private ObjectAnimator rlTopOutAnimator;
    private ObjectAnimator rlTopInAnimator;
    private ObjectAnimator rlHideOutAnimator;
    private ObjectAnimator rlHideInAnimator;

    private float rlTopHeight;

    private int rlHideHeight;

    //点击隐藏顶部和文字介绍
    private boolean clickToHide = true;

    public static void launch(Context context) {
        Intent starter = new Intent(context, DragSlopLayoutActivity.class);
        context.startActivity(starter);
    }

    @Override
    protected int bindLayout() {
        return R.layout.activity_drag_slop_layout;
    }

    @Override
    protected void initData() {
        imageList = new ArrayList<>();
        contentList = new ArrayList<>();
        for (int i = 0; i < 6; i++) {
            imageList.add(Images.imageUrls[i]);
        }
        contentList.add(getString(R.string.news_content));
        contentList.add(getString(R.string.TomHardy));
        contentList.add(getString(R.string.ChristianBale));
        contentList.add(getString(R.string.MarkWahlberg));
        contentList.add(getString(R.string.WillSmith));
        contentList.add(getString(R.string.DenzelWashington));
        textTotalNumber.setText("/" + String.valueOf(contentList.size()));
        textHideNumberSum.setText("/" + String.valueOf(contentList.size()));
        textNowNumber.setText("1");
        textHideNumberNow.setText("1");
        rlTop.post(new Runnable() {
            @Override
            public void run() {
                rlTopHeight = rlTop.getHeight();
                rlTopOutAnimator = ObjectAnimator.ofFloat(rlTop, "translationY", 0, -rlTopHeight)
                        .setDuration(400);
                rlTopInAnimator = ObjectAnimator.ofFloat(rlTop, "translationY", -rlTopHeight, 0)
                        .setDuration(400);
            }
        });
        rlHide.post(new Runnable() {
            @Override
            public void run() {
                rlHideHeight = rlHide.getHeight();
                rlHide.setTranslationY(rlHideHeight);
                rlHideInAnimator = ObjectAnimator.ofFloat(rlHide, "translationY", rlHideHeight, 0)
                        .setDuration(400);
                rlHideOutAnimator = ObjectAnimator.ofFloat(rlHide, "translationY", 0, rlHideHeight)
                        .setDuration(400);
            }
        });
		//AlbumAdapter就是一个继承自PagerAdapter的适配器,源码就不贴了。
        adapter = new AlbumAdapter(this, imageList);
        adapter.setAlbumClickListener(new AlbumAdapter.AlbumClickListener() {
            @Override
            public void onAlbumClick() {
                if (clickToHide) {
                    clickToHide = false;
                    rlTopOutAnimator.start();
                    rlHideInAnimator.start();
                    dragSlopLayout.scrollOutScreen(400);
                    rlHide.setVisibility(View.VISIBLE);
                } else {
                    clickToHide = true;
                    rlTopInAnimator.start();
                    rlHideOutAnimator.start();
                    dragSlopLayout.scrollInScreen(400);
                    rlHide.setVisibility(View.INVISIBLE);
                }
            }
        });
        viewPager.setAdapter(adapter);
        textDragContent.setText(contentList.get(0));
        viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                textDragContent.setText(contentList.get(position));
                textNowNumber.setText(String.valueOf(position + 1));
                textHideNumberNow.setText(String.valueOf(position + 1));
            }
        });
        dragSlopLayout.setAttachScrollView(scrollViewDragContent);
        scrollViewDragContent.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
            @Override
            public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                //向上滑动scrollY是正值
                Log.e(TAG, "scrollY=" + scrollY);
            }
        });
    }
}

参考文章链接
【1】http://blog.csdn.net/lmj623565791/article/details/46858663
结尾:以前写东西的时候,是想能自己总结的时候,也能给别人一些帮助,但我发现自己的水平还不行,现阶段写的东西只能是自己学习的总结,只能自己看的懂。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值