ViewDragHelper的延伸操作

转载请注明出处王亟亟的大牛之路
最近都在看帖子学习之类的度过,然后一直对可拖拽的试图这一些不是太了解,然后正好看到大牛的博文,然后敲了敲他的例子,对这一类型的实现,有了一个初步的了解。具体实现和理念还是看大牛的帖子吧hongyang。
言归正传,那既然事例和大体内容都是大牛分析出来的那我干什么呢?
在敲的过程当中自己犯二的一个点,就当记录下吧。
先上效果图:
ViewDragHelper的延伸操作_第1张图片
运动方式啊,实现啊,跟大牛的没什么区别,只是多一个个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.

你可能感兴趣的:(android,拖拽,效果)