转载博客地址:http://www.cnblogs.com/flyme2012/p/4076674.html

这个Demo是用来练习VIewDragHelper的,也是仿照网上一个大神的代码。我通过他的代码学会的ViewDragHelper,然后仿照效果写的同样的效果。
原文连接:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/0911/1680.html
效果图:
 
主要代码就是一个继承VIewGroup的类。写了注释,就不再解释了。
我写的主要代码如下:
 
public class YouLayout extends RelativeLayout {
 
private View topView;
private View bottomView;
private ViewDragHelper mDragHelper;
 
 
public YouLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
init(context);
}
public YouLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
// TODO Auto-generated constructor stub
}
public YouLayout(Context context) {
super(context);
init(context);
}
 
private void init(Context context){
mDragHelper = ViewDragHelper.create(this, 1.0f, new DragHelperCallBack());
}
 
@Override
protected void onFinishInflate() {
super.onFinishInflate();
topView = getTopView();
bottomView = getBottomView();
}
 
private View getTopView(){
return getChildAt(0);
}
private View getBottomView(){
return getChildAt(1);
}
 
 
 
 
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
 
if (ev.getAction() == MotionEvent.ACTION_CANCEL || ev.getAction() == MotionEvent.ACTION_UP) {
mDragHelper.cancel();
return false;
}
return mDragHelper.shouldInterceptTouchEvent(ev); //将事件传递给ViewDragHelper,让它自己处理是否需要打断。
}
 
 
private int downX ;
private int downY ;
 
@Override
public boolean onTouchEvent(MotionEvent event) {
mDragHelper.processTouchEvent(event); //同样是传递事件给ViewdragHelper
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = x ;
downY = y ;
break;
case MotionEvent.ACTION_UP:
int dx = x - downX;
int dy = y - downY;
int slop = mDragHelper.getTouchSlop();
if ((Math.pow(dx, 2) + Math.pow(dy, 2)) < Math.pow(slop, 2)) {
//说明是点击事件
if (mDragOffset == 0 ) {
moveTo(1f);
}else {
moveTo(0);
}
}
break;
}//收拾的放下,抬起的处理,是为了针对点击事件做的处理
 
 
 
return  isMyView(topView, x, y) || isMyView(bottomView, x, y); //判断当前的点击事件是在TopView或者是在BottomView上,如果在其上,则返回true
//如果是在TopView上,事件则传递给ViewDragHelper处理,如果是在BottomView上,则自然的传递下去。如果是在其他地方,则返回false,将事件传递下去。
}
 
 
 
@Override
public void computeScroll() {
 
//这个是为了将事件执行到底
if (mDragHelper.continueSettling(true)) {
ViewCompat.postInvalidateOnAnimation(this);
}
}
 
 
//判断点击事件是否在View上
private boolean isMyView(View view, int x, int y) {
       int[] viewLocation = new int[2];
       view.getLocationOnScreen(viewLocation);
       int[] parentLocation = new int[2];
       this.getLocationOnScreen(parentLocation);
       int screenX = parentLocation[0] + x;
       int screenY = parentLocation[1] + y;
       return screenX >= viewLocation[0] && screenX < viewLocation[0] + view.getWidth() &&  screenY >= viewLocation[1] && screenY < viewLocation[1] + view.getHeight();
 }
 
 
 
//移动到指定的位置
boolean moveTo(float slideRatio) {
        final int topBound = getPaddingTop();
        int y = (int) (topBound + slideRatio * mHeight);
        if (mDragHelper.smoothSlideViewTo(topView, topView.getLeft(), y)) {
            ViewCompat.postInvalidateOnAnimation(this);
            return true;
        }
        return false;
    }
 
 
class DragHelperCallBack extends Callback{
 
 
/**
* 这个是为了判断力要ViewDragHelper处理的是哪个View,很明显,这里处理的是TopView
*/
@Override
public boolean tryCaptureView(View child, int arg1) {
  return child == topView;
}
 
//时时回调。提供的是TopView时时更改的状态
@Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
mTop = top;
 
mDragOffset = (float) top / mHeight;
 
           topView.setPivotX(topView.getWidth());
           topView.setPivotY(topView.getHeight());
           topView.setScaleX(1 - mDragOffset / 2);
           topView.setScaleY(1 - mDragOffset / 2);
 
           bottomView.setAlpha(1 - mDragOffset);
           requestLayout();
           System.out.println("onviewpositionChhanged");
}
 
 
 
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
int top = getPaddingTop();
if (yvel > 0 || (yvel == 0 && mDragOffset > 0.5f)) {
top += mHeight;
}
mDragHelper.settleCapturedViewAt(releasedChild.getLeft(), top);
invalidate();
}
 
@Override
public int getViewVerticalDragRange(View child) {
return mHeight;
}
 
/**
* 如果手指是竖向滑动,事件则是在这个方法中处理的
*/
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
int topBound = getPaddingTop();
int bottomBound = getHeight() - topView.getHeight() - topView.getPaddingBottom();
int newTop = Math.min(Math.max(top, topBound), bottomBound);
return newTop;
}
}
 
 
 
/**
* 重新的测量View
*/
@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));
   }
 
 
 
private int mTop = 0 ;
private int mHeight;
private float mDragOffset;
 
/**
* 重新的布局子View   ,不重新布局也是可以的如果只是简单的移动一个topView的时候。在这个Demo中,需要让BottomView与TopView一起的移送,
* ViewdragHelper不能控制两个View,这里自己布局,然后使得在onViewPositionChanged的方法中,重新调用,重新布局,实现两个VIew的联动
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
mHeight = getHeight() - topView.getHeight();
topView.layout(0, mTop, r, mTop + topView.getMeasuredHeight());
bottomView.layout(0, mTop + topView.getMeasuredHeight(), r, mTop +b);
}
 
}
 
 
我的github地址:https://github.com/flyme2012
我的博客地址:http://www.cnblogs.com/flyme2012/

ViewDragHelper练习使用的更多相关文章

  1. Android -- ViewDragHelper

    ViewDragHelper SlidingPaneLayout和DrawerLayout,现在这俩个类被广泛的运用,其实研究他们的源码你会发现这两个类都运用了ViewDragHelper来处理拖动. ...

  2. Viewdraghelper解析

    2013年谷歌i/o大会上介绍了两个新的layout: SlidingPaneLayout和DrawerLayout,现在这俩个类被广泛的运用, 其实研究他们的源码你会发现这两个类都运用了ViewDr ...

  3. Android之ViewDragHelper

    在自定义ViewGroup中,很多效果都包含用户手指去拖动其内部的某个View(eg:侧滑菜单等),针对具体的需要去写好onInterceptTouchEvent和onTouchEvent这两个方法是 ...

  4. Android 一步一步教你使用ViewDragHelper

    在自定义viewgroup的时候 要重写onInterceptTouchEvent和onTouchEvent 这2个方法 是非常麻烦的事情,好在谷歌后来 推出了ViewDragHelper这个类.可以 ...

  5. Android ViewDragHelper源码解析

    在自定义ViewGroup的过程中,如果涉及到View的拖动滑动,ViewDragHelper的使用应该是少不了的,它提供了一系列用于用户拖动子View的辅助方法和相关的状态记录,像Navigatio ...

  6. Android 中 View移动总结:ViewDragHelper学习及用法详解

    如上图简单呈现出两个方块后,提出一个需求: 1.拖动方块时,方块(即子View)可以跟随手指移动. 2.一个方块移动时,另一个方块可以跟随移动. 3.将方块移动到左边区域(右边区域)后放开(即手指离开 ...

  7. ViewDragHelper详解

    2013年谷歌i/o大会上介绍了两个新的layout: SlidingPaneLayout和DrawerLayout,现在这俩个类被广泛的运用,其实研究他们的源码你会发现这两个类都运用了ViewDra ...

  8. ViewDragHelper的使用

    一.ViewDragHelper的原理 是一个能够自用移动ViewGroup内部View的控件. 通过获取ViewGroup的点击事件,之后通过Scroller滑动来进行对ViewGroup内部控件的 ...

  9. Android ViewDragHelper完全解析 自定义ViewGroup神器

    Android ViewDragHelper完全解析 自定义ViewGroup神器   转载请标明出处: http://blog.csdn.net/lmj623565791/article/detai ...

随机推荐

  1. haproxy hdr和path

    path : string This extracts the request's URL path, which starts at the first slash and ends before ...

  2. Table XXX is marked as crashed and should be repaired问题

    数据表出错了,查询数据获取不到了. 尝试一 重启mysql service mysqld restart 没用,重启并没有把表修复掉 尝试二 check table vicidial_list;rep ...

  3. https://pta.patest.cn/pta/test/15/exam/3/question/724

    List Reverse( List L ){ if(L==NULL) return; List head=(List)malloc(sizeof(struct Node)); head->Ne ...

  4. Android UI 使用HTML布局(直接打开server网页)

    非常多时候我们用HTML布局会更方便直接,记录一下. 我如今主要是直接调用server的网页(实际上是jsp的,仅仅是返回的是html).所以须要联网,第一步加入权限. <uses-permis ...

  5. OAuth2.0基本流程

    用户请求客户端>客户端通过在授权服务器上申请的apikey和apisceret>登录访问资源服务器

  6. [DevExpress]图表开发工具类 ChartUtils

    /// <summary> /// 基于.NET 3.5的Chart工具类;对应的DevExpress版本:12.1.7; /// </summary> public stat ...

  7. RDLC报表系列(二) 行分组

    接上一篇文章的内容,今天来说的是行分组.还是打开demo1.rdlc界面,拖入一个文本框和表 1.在表中随便选择一个字段,不然在添加行组的时候不会自动提示.我这里是选择的Dept 2.在下面的行组中右 ...

  8. sql从某不连续的数字中将其分段并找出缺失的数字并分段

    首先做准备数据 )) ') ') ') ') ') ') ') ') ') ') ') ') ') ') ') ') 将数据转换成应该处理的数据格式 ),colValue INT ) ) ,LEN(c ...

  9. BZOJ 3648: 寝室管理( 点分治 + 树状数组 )

    1棵树的话, 点分治+你喜欢的数据结构(树状数组/线段树/平衡树)就可以秒掉, O(N log^2 N). 假如是环套树, 先去掉环上1条边, 然后O(N log^2 N)处理树(同上); 然后再O( ...

  10. 使用微信 SDK 上传图片到七牛

    总体思路是:在微信下选好图片后将图片上传到微信服务器,在后端使用微信服务器返回的图片 serverId 加上调用接口的 ApiTicket 通过七牛的 fetch 接口向微信服务器下载多媒体文件的接口 ...