Android进阶之路读书笔记-view滑动的方法


源码地址

view滑动的6种方法

layout(), offsetLeftAndRight()与offsetTopAndBottom(), LayoutParams, 动画, scollTo 与 scollBy以及Scroller。

layout()

在这里插入图片描述
自定义view

/**
 * Created by ck on 2019/3/21.
 */

public class MyCustomView extends View {
    private float x;
    private float y;

    public MyCustomView(Context context) {
        super(context);
    }

    public MyCustomView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                //获取触摸点的横纵坐标
                x = event.getX();
                y = event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                float x1 = event.getX();
                float y1 = event.getY();
                int dx = (int) (x1 - x);
                int dy = (int) (y1 - y);
                layout(getLeft() + dx,getTop() + dy,getRight() + dx,getBottom() + dy);
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        return true;
    }
}

xml中使用

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.test.ck.viewslide.MainActivity">

   <com.test.ck.viewslide.MyCustomView
       android:layout_width="100dp"
       android:layout_height="80dp"
       android:background="@color/colorAccent"/>

</LinearLayout>

offsetLeftAndRight()与offsetTopAndBottom()

offsetLeftAndRight()与offsetTopAndBottom()的使用和layout()方法几乎没有区别,用这2个方法取代layout方法即可

   @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                //获取触摸点的横纵坐标
                x = event.getX();
                y = event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                float x1 = event.getX();
                float y1 = event.getY();
                int dx = (int) (x1 - x);
                int dy = (int) (y1 - y);
                offsetLeftAndRight(dx);
                offsetTopAndBottom(dy);
//                layout(getLeft() + dx,getTop() + dy,getRight() + dx,getBottom() + dy);
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        return true;
    }

LayoutParams

将onTouchEvent方法下 case MotionEvent.ACTION_MOVE内的代码替换如下

           case MotionEvent.ACTION_MOVE:
                float x1 = event.getX();
                float y1 = event.getY();
                int dx = (int) (x1 - x);
                int dy = (int) (y1 - y);
                LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();
                layoutParams.leftMargin = getLeft() + dx;
                layoutParams.topMargin = getTop() + dy;
                setLayoutParams(layoutParams);
                break;

此处使用LinearLayout.LayoutParams是因为其父布局是LinearLayout.除此之外还可使用ViewGroup.MarginLayoutParams

ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams();
                layoutParams.leftMargin = getLeft() + dx;
                layoutParams.topMargin = getTop() + dy;
                setLayoutParams(layoutParams);

动画(此次不做说明,会在以后再写)

scollTo 与 scollBy

scrollTo(x,y)表示移动到一个具体的坐标点,而scrollBy(dx,dy)则表示移动的增量为dx、dy.scrollBy(dx,dy)方法最终还是调用的scrollTo(x,y)
scrollTo(x,y)和scrollBy(dx,dy)方法源码:

public void scrollBy(int x, int y) {
        scrollTo(mScrollX + x, mScrollY + y);
    }
 public void scrollTo(int x, int y) {
        if (mScrollX != x || mScrollY != y) {
            int oldX = mScrollX;
            int oldY = mScrollY;
            mScrollX = x;
            mScrollY = y;
            invalidateParentCaches();
            onScrollChanged(mScrollX, mScrollY, oldX, oldY);
            if (!awakenScrollBars()) {
                postInvalidateOnAnimation();
            }
        }
    }

scollTo 与 scollBy的使用

            case MotionEvent.ACTION_MOVE:
                float x1 = event.getX();
                float y1 = event.getY();
                int dx = (int) (x1 - x);
                int dy = (int) (y1 - y);
//                scollTo和scollBy移动的是View的内容,如果在ViewGroup中使用,则是移动其所有的子View
//                dx,dy必须是负的
                ((View)getParent()).scrollBy(-dx,-dy);
                break;

Scroller

Scroller本身是不能实现View的滑动的,它需要与View的computeScroll()方法配合才能实现弹性滑动的效果
点击button实现滑动效果(scollTo和scollBy移动的是View的内容,如果在ViewGroup中使用,则是移动其所有的子View)
在这里插入图片描述
自定义view

/**
 * Created by ck on 2019/3/21.
 */
public class MyCustomView extends View {
    private float x;
    private float y;
    private Scroller scroller;

    public MyCustomView(Context context) {
        super(context);
    }

    public MyCustomView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        //初始化Scroller
        scroller = new Scroller(context);
    }

    public void smoothTo(int x1,int y1) {
        int scrollX = getScrollX();
        int scrollY = getScrollY();
        int disX = x1 - scrollX;
        int disY = y1 - scrollY;
        scroller.startScroll(scrollX,scrollY,disX,disY,2000);
        invalidate();
    }

    /**
     * 此方法会在onDraw()方法中调用
     */
    @Override
    public void computeScroll() {
        super.computeScroll();
        if (scroller.computeScrollOffset()){
            //scollTo和scollBy移动的是View的内容,如果在ViewGroup中使用,则是移动其所有的子View
            ((View)getParent()).scrollTo(scroller.getCurrX(),scroller.getCurrY());
            invalidate();
        }
    }
}

activity内的调用

public class MainActivity extends AppCompatActivity {
   
    private MyCustomView myCustomView;
    private Button btn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myCustomView = (MyCustomView) findViewById(R.id.myCustomView);
        btn = (Button) findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            //x轴向右移动100,y轴向下移动100
                myCustomView.smoothTo(-100,-100);
            }
        });
    }
}

Scroller解析

解析Scroller

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值