android---滑动

本文围绕实现活动效果的核心展开,介绍了View滑动效果的多种实现方法。包括通过记录触摸点坐标获取偏移量修改View坐标;利用layout方法、offSetLeftAndRight()等方法;借助layoutParams动态修改布局位置参数;还讲解了scrollTo与scrollBy的区别及使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 实现活动效果的核心

当触碰View时,系统记下当前触摸点的坐标,当手指移动时,系统记下移动后的触摸点的坐标,

从而获取 到相对于前一次坐标点的偏移量,并通过偏移量来修改View的坐标,这样不断重复

从而实现滑动的过程

 

二layout分法

在View 进行绘制时,会调用onLayout方法来设置显示的位置,同样可以通过修改View

的left,top,right,bottom四个属性来控制View的坐标,通过onTouchEvent()获取触摸点的坐标

计算偏移量

通过视图坐标系来获取偏移量

getX()

getY()

通过绝对坐标来获取偏移量

getRawY()

getRawY()

 

三 offSetLeftAndRight() 分法与offSetTobAndBottom()

相当于系统提供的一个对左右,上下移动的API的封装,当计算出偏移量后

四 layoutParams  要通过父容器获取到,如果没有放在这个父容器中是无法获取到的

Layoutparams 保存了一个View的布局参数,因此可以在程序中,通过改变LayoutParams

来动态的修改一个布局的位置参数.   当然,计算偏移量的方法与在Layout方法中计算offset也是一样 的.

当获取到偏移量之后,就可以通过setLayoutParams 来改变其LayoutParams.

五 scrollTo 与scollBy

1 scrollTo 与scrollBy 区别

在一个View中,系统提供了scrollTo ,scrollBy 两种方式来改变一个View的位置

这两个方法的区别非常好理解,与英文中的To和By的区别类似,

scrollTo(x,y) 表示移动到一个具体的坐标点(x,y)

而scrollBy(dx,dy)表示移动的增量为dx,dy

获取偏移量后使用scrollBy 来移动View 如下

int offsetX = x-lastX;

int offsetY = x - lastY;

scrollBy(offsetX,offsetY)

package com.yifei.myapplication;

import android.content.Context;
import android.graphics.Color;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class MyScrollView extends View {
    private int lastX;
    private int lastY;

    public MyScrollView(Context context) {
        super(context);
        initView();
    }

    public MyScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initView();
    }

    private void initView() {
        setBackgroundColor(Color.RED);
    }

    @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 offsetX = x - lastX;
                int offsetY = y - lastY;
                //在当前left top right botton  的基础上加上偏移量
                layout(getLeft() + offsetX, getTop() + offsetY, getRight() + offsetX, getBottom() + offsetY);
                break;
            case MotionEvent.ACTION_UP://抬起

                break;
            default:
                return false;
        }

        return true;
    }
}

使用getRawX(),  getRawY()

package com.yifei.myapplication;

import android.content.Context;
import android.graphics.Color;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class MyRawScrollView extends View {
    private int lastX;
    private int lastY;
    public MyRawScrollView(Context context) {
        super(context);
        initView();
    }

    public MyRawScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public MyRawScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public MyRawScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initView();
    }

    public void initView() {
        setBackgroundColor(Color.BLUE);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int rawX = (int) event.getRawX();//获取触摸点坐标
        int rawY= (int) event.getRawY(); //
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN://按下
                //记录启始点坐标
                lastX = rawX;
                lastY = rawY;
                break;
            case MotionEvent.ACTION_MOVE://移动
                int offsetX= rawX - lastX;
                int offsetY = rawY - lastY;
                //
                layout(getLeft()+offsetX,getTop()+offsetY,getRight()+offsetX,getBottom()+offsetY);
               //重新设置初始坐标
                lastX = rawX;
                lastY  = rawY;
                break;
            case MotionEvent.ACTION_UP://抬起
                break;
            default:
                return false;
        }


        return true;
    }
}
  offsetLeftAndRight(offsetX);
  offsetTopAndBottom(offsetY);
在两句话是对
layout(getLeft()+offsetX,getTop()+offsetY,getRight()+offsetX,getBottom()+offsetY);
的简写

通过setLayoutParams()移动View

package com.yifei.myapplication;

import android.content.Context;
import android.graphics.Color;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;

public class MyLayoutParamsView extends View {

    private int lastX;
    private int lastY;


    public MyLayoutParamsView(Context context) {
        super(context);
        initView();
    }

    public MyLayoutParamsView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public MyLayoutParamsView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();

    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public MyLayoutParamsView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initView();
    }

    private void initView() {
        setBackgroundColor(Color.GREEN);
    }

    @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 offsetX = x-lastX;
                int offsetY = y - lastY;
                //获取布局的具体参数
                RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
                layoutParams.leftMargin = getLeft()+offsetX;
                layoutParams.topMargin  = getTop() +offsetY;
                setLayoutParams(layoutParams);
                break;
            case MotionEvent.ACTION_UP:
                break;
            default:
                return false;
        }


        return true;
    }
}

利用ViewGroup.MarginLayoutParams 来设定子元素的Margin 从而设置子元素的位置

package com.yifei.myapplication;

import android.content.Context;
import android.graphics.Color;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;

public class MyLayoutParamsView extends View {

    private int lastX;
    private int lastY;


    public MyLayoutParamsView(Context context) {
        super(context);
        initView();
    }

    public MyLayoutParamsView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public MyLayoutParamsView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();

    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public MyLayoutParamsView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initView();
    }

    private void initView() {
        setBackgroundColor(Color.GREEN);
    }

    @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 offsetX = x-lastX;
                int offsetY = y - lastY;
                ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams();
                layoutParams.topMargin = offsetY+getTop();
                layoutParams.leftMargin=offsetX+getLeft();
                 setLayoutParams(layoutParams);//把layout参数设置到父容器中
                break;
            case MotionEvent.ACTION_UP:
                break;
            default:
                return false;
        }


        return true;
    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值