ViewDragHelper是google新出的,可以帮助我们快速实现组件的拖动,今天我与大家分享我对它的学习,demo地址:https://github.com/luoshixin/TestViewDrag。
以下是布局的主要代码:
<com.drag.MyDragLayout android:layout_width="match_parent" android:layout_height="match_parent"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="#8f000000"> <ImageView android:id="@+id/icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/ic_launcher" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="150dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="100dp" android:text="上拉更精彩" android:textColor="@android:color/white" android:textSize="20sp" /> </RelativeLayout> </com.drag.MyDragLayout>
自定义一个MyDragLayout类,该类继承ViewGroup, 包含一个child布局(即RelativeLayout那部分), 在MyDragLayout中我们利用ViewDragHelper移动的也是这个child,下面来贴出MyDragLayout的代码:
public class MyDragLayout extends ViewGroup { private int VEL_TO_TOP = 2000;//松手后每秒移动速度大于此则mChild向上移动 private View mChild; private ViewDragHelper mDragHelper; public MyDragLayout(Context context) { super(context); } public MyDragLayout(Context context, AttributeSet attrs) { super(context, attrs); } public MyDragLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onFinishInflate() { super.onFinishInflate(); mChild = getChildAt(0); Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.animation); mChild.findViewById(R.id.icon).startAnimation(animation); mDragHelper = ViewDragHelper.create(this, 1f, new ViewDragHelper.Callback() { @Override public boolean tryCaptureView(View child, int pointerId) { return child == mChild; } @Override public int clampViewPositionVertical(View child, int top, int dy) { int finalTop = top; if (top > 0){ finalTop = 0; } return finalTop; } @Override public void onViewReleased(View releasedChild, float xvel, float yvel) { animToTopOrBottom(releasedChild, yvel); invalidate(); } }); } private void animToTopOrBottom(View v, float yvel){ if (yvel > VEL_TO_TOP || -v.getTop() > v.getMeasuredHeight()/4){ mDragHelper.smoothSlideViewTo(v, 0, -v.getMeasuredHeight()); }else { mDragHelper.smoothSlideViewTo(v, 0, 0); } } @Override public void computeScroll() { if (mDragHelper.continueSettling(true)){ postInvalidateOnAnimation(); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); setMeasuredDimension(width, height); mChild.measure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { mChild.layout(0, 0, mChild.getMeasuredWidth(), mChild.getMeasuredHeight()); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return mDragHelper.shouldInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { try { mDragHelper.processTouchEvent(event); }catch (Exception e){} return true; } }