ViewDragHelper的延伸操作

转载请注明出处王亟亟的大牛之路

最近都在看帖子学习之类的度过,然后一直对可拖拽的试图这一些不是太了解,然后正好看到大牛的博文,然后敲了敲他的例子,对这一类型的实现,有了一个初步的了解。具体实现和理念还是看大牛的帖子吧hongyang

言归正传,那既然事例和大体内容都是大牛分析出来的那我干什么呢?

在敲的过程当中自己犯二的一个点,就当记录下吧。

先上效果图:

运动方式啊,实现啊,跟大牛的没什么区别,只是多一个个Toast,记录下这个错误。

VDHLayout

public class VDHLayout extends LinearLayout
{
    private ViewDragHelper mDragger;

    private View mDragView;
    private View mAutoBackView;
    private View mEdgeTrackerView;

    private Point mAutoBackOriginPos = new Point();

    public VDHLayout(Context context, AttributeSet attrs)
    {

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

            @Override
            public int clampViewPositionHorizontal(View child, int left, int dx)
            {
                return left;
            }

            @Override
            public int clampViewPositionVertical(View child, int top, int dy)
            {
                return top;
            }

            //手指释放的时候回调
            @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);
            }

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

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

    }

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

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

    @Override
    public void computeScroll()
    {
        if(mDragger.continueSettling(true))
        {
            invalidate();
        }
    }

    @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();
    }

    @Override
    protected void onFinishInflate()
    {
        super.onFinishInflate();
        mDragView=getChildAt(0);
        mAutoBackView = getChildAt(1);
        mEdgeTrackerView = getChildAt(2);
    }

}

补充下,要让他动,必须要有getViewVerticalDragRange()getViewHorizontalDragRange() 已经亲测过了,确实如此不然的话你的Button或者TextView是不会动的。

然后说下问题所在,初以为接收子View的点击事件什么的可以在这个自定义的LinearLayout里完成。

也就是

private View mDragView;

private View mAutoBackView;

private View mEdgeTrackerView;

变成

`private Button mDragView;

private View mAutoBackView;

然后在构造函数中处理相应的业务逻辑,只要在布局的XML里添加ID即可

 <Button
        android:layout_margin="10dp"
        android:gravity="center"
        android:layout_gravity="center"
        android:background="#44ff00"
        android:text="button"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:id="@+id/mDragView"/>

像这样,然后 正常的findViewById来操作,因为想当然的以为Button继承TextView,TextView继承View所以想当然的觉得捕捉View的回调函数也会调用Button,实则是一对的空指针。

所以Button的一系列点击事件要抽离到那个主Activity中去实现。

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button  mDragView=(Button)findViewById(R.id.mDragView);
        mDragView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity.this, "123", Toast.LENGTH_SHORT).show();
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

然后在他 自定义布局的那部分还是让他以View的形式存在着

记录下自己的2B…

Demo地址:http://yunpan.cn/ccuVURC7RpsUu 访问密码 4dfe

Gradle是2.2.1的如果没有那么高版本的小伙伴可以下载Gradle去找自己所需要的版本!!

Thanks for watch.

时间: 2024-10-07 01:27:16

ViewDragHelper的延伸操作的相关文章

Android【布局管理器语法】之四大布局【LinearLayout,TableLayout,FrameLayout,RelativeLayout】

LinearLayout 线性布局是将放入其中的组件按照垂直(vertical)或者水平(horizontal)方向来布局, 也就是控制其中组件横向排列或者纵向排列.在线性布局中 每一行[针对垂直排列]或每一列[针对水平排列]只能放一个组件 . 注意:Android线性布局不会换行,当组件一个挨着一个排列到窗体边缘后 剩下的组件将不会显示出来 排列方式由android:orientation属性控制,对齐方式由android:gravity属性来控制 (1)常见属性: android:orien

Android——自定义镂空遮盖控件

刚学完ViewDragHelper和PorterDuffXferMode的我,突然想做一个这样效果的自定义控件:点击ListView的列表项,通过ViewDragHelper用动画方式上下各弹出一个控件遮盖住ListView,这两个控件在遮盖listView的过程中有一部分是镂空的.先上效果图: 首先是进行页面的布局,让自定义控件PlayLayout继承自Franlayout,在最底层放的就是listView所在的子FramLayout(Id:midContent),然后依次在上面加上下两个看起

知识点延伸(2)markdown简单操作

两个在线的Markdown编辑器: http://mahua.jser.me/ http://maxiang.info/ 或者选择在简书上书写 一篇很好的认识与入门:http://sspai.com/25137 查看全部的语法,参考:http://wowubuntu.com/markdown/index.html windows下的markdown工具:一款叫 MarkdownPad ,另一款叫 MarkPad. 1.标题 如果一段文字被定义为标题,只要在这段文字前加#号即可 # 一级标题 ##

采用MiniProfiler监控EF与.NET MVC项目(Entity Framework 延伸系列1)

小分享:我有几张阿里云优惠券,用券购买或者升级阿里云相应产品最多可以优惠五折!领券地址:https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=ohmepe03 前言 Entity Framework 延伸系列目录 今天来说说EF与MVC项目的性能检测和监控 首先,先介绍一下今天我们使用的工具吧. MiniProfiler~ 这个东西的介绍如下: MVC MiniProfiler是Stack Overf

Swift 运算符操作

在Swift中延伸了一种和C++类似的新特性,Swift的运算符提供了良好的可拓展性,我们可以对运算符进行操作,对运算符的操作其实就是对运算函数的重写或者重载.注意运算符操作一般被操做的参数往往要加上In-Out模式. +.-(运算符重载) 我们在实际开发中,Swift可自定义运算符,并不限于预设的运算符,我们可以对+进行重载,使其完成Int与Double或者Flaot相加. Swift提供了如下的函数,使得Int与Int可以相加: func + (left:Int,right:Int)->In

[Android L]SEAndroid开放设备文件结点权限(读或写)方法(涵盖常用操作:sys/xxx、proc/xxx、SystemProperties)

温馨提示 建议你先了解一下上一篇博文([Android L]SEAndroid增强Androd安全性背景概要及带来的影响)所讲的内容,先对SEAndroid窥个全貌,然后再继续本节内容. 1 现象描述 基于Android L版本源码环境进行开发时,根据项目需求,APP层需要操作sys/xxx 或 proc/xxx下面的文件结点,但是会报出以下权限异常,无法直接操作这些结点 LedLightFileUtil( 4671): java.io.FileNotFoundException: /sys/c

Linux命令简单操作

一. awk 命令格式: awk 'BEGIN{commands} pattern {commands} END{commands}'file 工作方式: 1.执行BEGIN{commands}语句块中语句,可选的语句块 2.从文件或者stdin中读取一行,然后执行{commands},重复这个过程,直到文件全部被读取完 3.当读至输入流末尾是,执行END{commands}语句块 特殊变量: FILENAME:awk浏览的文件名 NR:记录数量,执行过程中对应于当前行号 NF:字段数量,执行过

深入浅出数据结构C语言版(5)——链表的操作

上一次我们从什么是表一直讲到了链表该怎么实现的想法上:http://www.cnblogs.com/mm93/p/6574912.html 而这一次我们就要实现所说的承诺,即实现链表应有的操作(至于游标数组--我决定还是给它单独写个博文比较好~). 那么,我们的过程应该是怎么样的呢?首先当然是分析需要什么操作,然后再逐一思考该如何实现,最后再以代码的形式写出来. 不难发现,我们希望链表能支持的(基础,可以由此延伸)操作就是: 1.给出第n个元素 2.在第n个元素的后面插入一个元素(包含在最后一个

请列出你在从事IT生涯中,最难以忘怀的一次误操作

IT系统最怕什么,我觉得就两点: 1.不可靠的软硬件. 2.误操作. 第一点就不用解释了,第二点是该文的内容,主要摘选自ITPUB的精华贴——[精华] 请列出你在从事DBA生涯中,最难以忘怀的一次误操作 中摘录各位网友的经验和教训,常看看以警惕自己. #2 一次一个session占用内存很大,这个session id比较大,所以以为是用户进程,kill, 则库立刻down了,查日志后,才知道是一个后台进程,但详细是哪个进程,现在忘记了. 好的是库起来了,这个故障,我一直牢记于心. 现在做任何操作