Android 自定义View基础(五)--DragView

接着前面几篇文章,我们这篇文章实现拖动控件的效果:

实现如上的效果有以下几种方法:

  • layout()

  • offsetLeftAndRight(dx)和offsetTopAndBottom(dy)

  • LayoutParams

  • scrollTo和scrollBy


首先实现这样的一个效果,我们需要重写控件DragView继承自View,然后在控件中监听手势动作,就是需要重写onTouchEvent();


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //记录初始位置
                lastX = x;
                lastY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                int dx = x - lastX;
                int dy = y - lastY;
                //*****在这里实现控件的拖动*****
                 //  放入下面的代码
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        return true;
    }

实现控件的拖动,事实上就是根据手势不断的重新绘制控件。在视觉上就是跟着手势进行移动。

layout()

我们都知道控件中有一个layout,作用就是让绘制控件显示到屏幕上。

  layout(getLeft() + dx, getTop() + dy, getRight() + dx, getBottom() + dy);//重新绘制

让我们的控件也更加手势来重新绘制到,移动后的位置。

offsetLeftAndRight(dx)和offsetTopAndBottom(dy)

这个方法相当于系统提供的一个对左右上下移动的API的封装,当计算出偏移量后,只需要将参数分别给到方法中,就可以实现控件的重新布局,效果与上面的Layout方法一样。

//同时对left和right进行偏移
// offsetLeftAndRight(dx);
//同时对top和buttom进行偏移
//offsetTopAndBottom(dy);

LayoutParams

我们知道动态设置控件的位置等参数可以通过LayoutParams,那么这个方法当然也可以实现动态的设置布局的绘制。
代码如下:

 // 使用LayoutParams进行设置,这里除了父布局的LayoutParams,也可以使用ViewGroup.MarginLayoutParams来实现这一功能。
              LinearLayout.LayoutParams params = ( LinearLayout.LayoutParams) getLayoutParams();
              params.leftMargin = getLeft() + dx;
             params.topMargin = getTop() + dy;
                setLayoutParams(params);

当然LayoutParams是我们控件的父布局对应的Params.当然我们也可以使用ViewGroup.MarginLayoutParams来实现,代码一样。很简单,不做详解。

scrollTo和scrollBy

在View中为我们提供了scrollTo和scrollBy两种方式来改变一个View的位置,scroolTo(x,y)表示从移动到一个具体的位置,而scrollBy(dx,dy)表示移动量为d x,dy.
代码如下:

  //如果使用就需要对ViewGroup,对于View,就是父布局
                ((View) getParent()).scrollBy(-dx, -dy);//这里移动的不是控件而是坐标系,所以参数为负,同理,scrollTo()是绝对坐标

scrollBy(-dx, -dy)其实这里移动的并不是控件本身,从代码中我们可以看出实际上是移动的父控件中的content,还是该控件,呀?这不相当于没说么?这里再重点解释一下。

不妨这样想象我们的手机屏幕是一块中间被挖掉的纸板,纸板下面是一个巨大的画布,也就是我们想要展示的视图,当我们把这个纸板盖在画布上时,透过中间的部分可以看到画布上的视图,画布其余部分我们是看不到的。我们的scrollBy方法实际相当于你移动外面的纸板,当你移动移动,也相当于移动视图的坐标,那么我们相当于控件的移动正好相反,所以使用的是负值。

以上四种实现可拖动的控件的方法特别简单,其实还有其他的方法来实现。例如动画,ViewDragHelper等。这个以后有时间再加上。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值