<code>public class ViewDragHelper extends Object
java.lang.Object
?
android.support.v4.widget.ViewDragHelper</code>
ViewDragHelper是什么?
官方的解釋:
ViewDragHelper is a utility class for writing custom ViewGroups. It offers a number of useful operations and state tracking for allowing a user to drag and reposition views within their parent ViewGroup.
ViewDragHelper是編寫自定義ViewGroups一個實用工具類。
它定義了一組有用的操作和狀態(tài)追蹤,允許用戶在父ViewGroup中拖動并且重新定位子View(child view)。
<ol>
<li>ViewDragHelper.Callback是連接ViewDragHelper與view之間的橋梁(這個view一般是指擁子view的容器即parentView);</li>
<li> ViewDragHelper的實例是通過靜態(tài)工廠方法創(chuàng)建的;</li>
<li>能夠指定拖動的方向;</li>
<li> ViewDragHelper可以檢測到是否觸及到邊緣;</li>
<li> ViewDragHelper并不是直接作用于要被拖動的View,而是使其控制的視圖容器中的子View可以被拖動,如果要指定某個子view的行為,需要在Callback中想辦法;</li>
<li> ViewDragHelper的本質(zhì)其實是分析onInterceptTouchEvent和onTouchEvent的MotionEvent參數(shù),然后根據(jù)分析的結(jié)果去改變一個容器中被拖動子View的位置( 通過offsetTopAndBottom(int offset)和offsetLeftAndRight(int offset)方法 ),他能在觸摸的時候判斷當前拖動的是哪個子View;</li>
<li>ViewDragHelper的實例方法 ViewDragHelper create(ViewGroup forParent, Callback cb) 可以指定一個被ViewDragHelper處理拖動事件的對象 。</li>
</ol>
ViewDragHelper.Callback(ViewDragHelper與View之間的橋梁)
<code>public static abstract class ViewDragHelper.Callback
extends Object
java.lang.Object
?
android.support.v4.widget.ViewDragHelper.Callback</code>
官網(wǎng)簡介:
A Callback is used as a communication channel with the ViewDragHelper back to the parent view using it. on*
methods are invoked on significant events and several accessor methods are expected to provide the ViewDragHelper with more information about the state of the parent view upon request. The callback also makes decisions governing the range and draggability of child views.
Callback是連接ViewDragHelper與parentView之間的橋梁。
方法在重要的事件中被調(diào)用,幾個訪問方法會提供給ViewDragHelper更多關(guān)于parentView的狀態(tài)信息。
Callback同時也決定了拖動的范圍和子view的拖動能力。
<br />
為什么要使用ViewDragHelper
ViewDragHelper解決了android中手勢處理過于復雜的問題,在DrawerLayout出現(xiàn)之前,側(cè)滑菜單都是由第三方開源代碼實現(xiàn)的,其中著名的當屬 MenuDrawer ,MenuDrawer重寫onTouchEvent方法來實現(xiàn)側(cè)滑效果,代碼量很大,實現(xiàn)邏輯也需要很大的耐心才能看懂。如果每個開發(fā)人員都從這么原始的步奏開始做起,那對于安卓生態(tài)是相當不利的。所以說ViewDragHelper等的出現(xiàn)反映了安卓開發(fā)框架已經(jīng)開始向成熟的方向邁進。
ViewDragHelper實例
根據(jù)開源項目android-card-slide-panel 簡化
創(chuàng)建自定義的ViewGroup
public class CardSlidePanel extends ViewGroup {
private ViewDragHelper mViewDragHelper;
public CardSlidePanel(Context context) {
this(context, null);
}
public CardSlidePanel(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CardSlidePanel(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// 滑動相關(guān)類
mViewDragHelper = ViewDragHelper
.create(this, 10f, new DragHelperCallback());
mViewDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
}
@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));
}
@Override
protected void onLayout(boolean changed, int left, int t, int right, int b) {
int mTotalHeight = 0;
// 遍歷所有子視圖
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
// 獲取在onMeasure中計算的視圖尺寸
int measureHeight = childView.getMeasuredHeight();
int measuredWidth = childView.getMeasuredWidth();
childView.layout(left, mTotalHeight, measuredWidth, mTotalHeight + measureHeight);
mTotalHeight += measureHeight;
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return mViewDragHelper.shouldInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mViewDragHelper.processTouchEvent(event);
return true;
}
/**
* 這是viewdraghelper拖拽效果的主要邏輯
*/
private class DragHelperCallback extends ViewDragHelper.Callback {
@Override
public void onViewPositionChanged(View changedView, int left, int top,
int dx, int dy) {
}
@Override
public boolean tryCaptureView(View child, int pointerId) {
return true;
}
@Override
public int getViewHorizontalDragRange(View child) {
return 256;
}
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
}
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
return left;
}
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
return top;
}
}
}
創(chuàng)建布局文件layout_drag.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff"
android:orientation="vertical">
<org.lethisis.weather.weatherl.ui.widget.cardslide.CardSlidePanel
android:id="@+id/image_slide_panel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimaryDark">
<LinearLayout
android:id="@+id/card_bottom_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<Button
android:id="@+id/card_left_btn"
android:layout_width="70dp"
android:layout_height="70dp" />
<Button
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="10dp" />
<Button
android:id="@+id/card_right_btn"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_marginLeft="10dp" />
</LinearLayout>
<org.lethisis.weather.weatherl.ui.widget.cardslide.CardItemView
android:layout_width="@dimen/card_image_width"
android:layout_height="100dp" />
<org.lethisis.weather.weatherl.ui.widget.cardslide.CardItemView
android:layout_width="@dimen/card_image_width"
android:layout_height="100dp" />
<org.lethisis.weather.weatherl.ui.widget.cardslide.CardItemView
android:layout_width="@dimen/card_image_width"
android:layout_height="wrap_content" />
<org.lethisis.weather.weatherl.ui.widget.cardslide.CardItemView
android:layout_width="@dimen/card_image_width"
android:layout_height="wrap_content" />
</org.lethisis.weather.weatherl.ui.widget.cardslide.CardSlidePanel>
</LinearLayout>
【待續(xù)】
參考:
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/0911/1680.html