Android:ViewDragHelper学习

android v4包中的视图拖拽的帮助类。

参考博客:
2、http://blog.csdn.net/pi9nc/article/details/39583377

1、创建方法:
ViewDragHelper.create(ViewGroup forParent, float sensitivity, Callback cb)

第一个参数是当前要拖拽的ViewGroup对象,
第二个参数是拖拽的灵敏度,
第三个参数是拖拽的监听回调。

代码如下:
      
      
private ViewDragHelper mDragger;
mDragger = ViewDragHelper.create(this, 1.0f, callBack);
2、事件分发
ViewGroup的事件分发都是从dispatchTouchEvent开始的,当dispatch返回true时,则事件下发到ViewGroup的onInterceptTouchEvent,该方法进行判断是否对事件进行拦截,当返回true时,表示拦截事件,则事件传递到ViewGroup中的onTouchEvent处理;返回false时,表示不拦截事件,则事件分发到子View。

原理懂了之后,再处理ViewGroup的拖拽事件,我们在onInterceptTouchEvent进行拦截,然后再onTouchEvent中进行处理,代码如下:
      
      
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
final int action = MotionEventCompat.getActionMasked(event);
if (action == MotionEvent.ACTION_CANCEL
|| action == MotionEvent.ACTION_UP) {
return false;
}
return mDragger.shouldInterceptTouchEvent(event);
}
      
      
@Override
public boolean onTouchEvent(MotionEvent event) {
mDragger.processTouchEvent(event);
return true;
}
3、事件回调
在创建ViewDragHelper对象实例的时候,传入了一个callback回调,作为view与手势动作的一个桥梁。下面是回调覆写的一些相关的方法。
(1)clampViewPositionHorizontal(View child,int left ,int dx),这个方法用来处理横向的拖动,返回一个int值就可以实现横向的拖动效果,其中left是当前View拖动到达的x坐标,理论上这个方法返回第二个参数left的值,当然,还可以对返回的left值做处理。比如,设置拖动过程遇到左右边界就不让其拖动。代码如下:
      
      
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
Log.d("DragLayout", "clampViewPositionHorizontal " + left + ","
+ dx);
final int leftBound = getPaddingLeft();
final int rightBound = getWidth() - mView1.getWidth();
final int newLeft = Math.min(Math.max(left, leftBound), rightBound);
return newLeft;
}
(2)clampViewPositionVertical(View child,int top , int dy),该回调方法跟第一个clampViewPositionHorizontal类似,主要是处理垂直拖动。这里就不多做介绍。这两个方法默认返回值是0,设置拖动过程遇到上下边界就不让其拖动,代码如下:
      
      
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
final int topBound = getPaddingTop();
final int BottomBound = getHeight() - mView1.getHeight();
final int newTop = Math.min(Math.max(top, topBound), BottomBound);
return newTop;
}
(3)tryCaptureView(View child, int pointerId)这个方法主要是决定改ViewGroup中有哪几个子View可以进行移动,先看下面的代码:
       
       
private View mView1;
private View mView2;
private View mView3;
 
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mView1= getChildAt(0);
mView2= getChildAt(1);
mView3= getChildAt(2);
}
 
@Override
public boolean tryCaptureView(View child, int pointerId) {
// mView3禁止直接移动
return child == mView1|| child == mView2;
}
从代码中可以发现,在当前的ViewGroup中,取得了3个子View:mView1,mView2,mView3,而我们在tryCaptureView中,传入了参数child,当child为mView1或者mView2时,返回true,否则返回false。所以,只有mView1和mView2可以拖动,mView3不能拖动。而当返回直接写 return true 时,则表示所有的child都可以拖动。

(4)onViewRelease(View releasedChild, float xvel,float yvel),这个方法是拖动结束后手指放开的回调,这里有一个用法是,让view拖动完回到原来的位置,代码如下:
       
       
//用来存放要拖动view的起始位置
private Point mAutoBackOriginPos = new Point();
//获取起始坐标
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
mAutoBackOriginPos.x = mView2.getLeft();
mAutoBackOriginPos.y = mView2.getTop();
}
//一定要覆写
@Override
public void computeScroll() {
if (mDragger.continueSettling(true)) {
    invalidate();
}
}
// 手指释放的时候回调
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
    // mView2手指释放时可以自动回去
    if (releasedChild == mView2) {
    mDragger.settleCapturedViewAt(mAutoBackOriginPos.x,
    mAutoBackOriginPos.y);
    //一定要invalidate
    invalidate();
}
}
(5)onEdgeDragStarted(int edgeFlags , int pointerId) ,ViewDragHelper有边缘检测的功能,其回调方法就是这个方法,当我们在边界拖动的时候,可以指定view进行移动。代码如下:
       
       
mDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
 
// 在边界拖动时回调
@Override
public void onEdgeDragStarted(int edgeFlags, int pointerId) {
mDragger.captureChildView(mView3, pointerId);
}
第一行代码表示,检测的是左边缘,当我们的手指在屏幕左边缘滑动时,指定的mView3会根据滑动的方向及距离做出相应的移动。我们在onEdgeDragStarted回调方法中,主动通过captureChildView对其捕获,该方法可以绕过tryCaptureView,所以,即使我们在tryCaptureView中没有让mView3返回true,但不影响。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使鱼香肉丝与图片居中对齐,可以对LinearLayout进行一些调整。请使用以下代码替换你提供的代码: ```xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:paddingLeft="5dp" android:paddingRight="5dp" android:paddingTop="-90dp" android:paddingBottom="10dp" android:weightSum="1" > <!-- 菜品布局 --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_marginLeft="10dp" android:gravity="center" > <ImageView android:id="@+id/image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="centerCrop" android:src="@drawable/recipe_defult_img" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:gravity="center_horizontal" > <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="50dp" android:singleLine="false" android:text="鱼香肉丝" android:textColor="@color/black" android:textSize="12sp" /> </LinearLayout> </LinearLayout> ``` 在内部的LinearLayout中,我们添加了一个`android:gravity="center"`属性来使ImageView居中对齐。同时,在外层的LinearLayout中,我们添加了`android:gravity="center_horizontal"`属性来使TextView水平居中对齐。这样,鱼香肉丝与图片就会居中对齐了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值