View的基础与滑动

news2024/9/29 3:35:08

View的基础与滑动

1.View的基础知识

1.1View是什么

View是一种界面层的控件的一种抽象

,我们知道的大多数控件都是直接或间接继承自View

EditText,TextView等等

注意:

EditText在compose中并没有相关控件,而是通过TextField来进行组合

Android中View本身就可以是单个控件也可以是由多个控件组合成的一组控件

如下面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P09FNiCp-1684507503967)(../../assets/QQ图片20230518203409.png)]

1.2View的位置参数

这个分为两种情况,一种是相对于ViewGroup的,一种相对于Screen的

先说相对于ViewGroup的

1.2.1ViewGroup中的位置参数

getLeftview的最左边相对于viewGroup最左边的距离
getRightview的最右边相对于ViewGroup最左边的距离
getTopview的最上面相对于ViewGroup最上面的距离
getBottomview的最下面相对于ViewGroup最上面的距离
getX你触碰的那个点相对于view的X距离
getY你触碰的那个点相对于view的Y距离

1.2.2Screen中的位置参数

getRawX你触碰的那个点相对于Screen的x距离
getRawY你触碰的那个点相对于Screen的y的距离

1.2.3图解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F6NrhMaO-1684507503968)(../../assets/QQ图片20230518214430.png)]

说一说getX与getLeft的关系

我们要先将一个概念叫做偏移量:

你在屏幕按动的那个到你父容器(即view)的距离,这个图里面我是用touch表示的,

就是偏移量,translation

getX = getLeft+translationX,正值表示向右平移,负值表示向左平移。

getY = getTop+translationY,正值表示向下平移,负值表示向上平移。

1.3MotionEvent

当你手指接触到屏幕的时候,MotionEvent有4个典型事件如下:

  1. ACTION_DOWN ,这个是手指刚接触到屏幕的时候
  2. ACTION_MOVE,这个是手指在屏幕上移动
  3. ACTION_UP,这个是手指从屏幕上松开
  4. ACTION_CANCEL,这个是触摸事件被取消或中断的动作类型。

前面的还好理解,那么后面两个怎么区分呢?

chatPGT中说遇到如下事件,会执行后者

  1. 手指移出了视图范围:当用户在触摸一个视图时,如果手指移动到视图范围之外,系统会生成一个 ACTION_CANCEL 的触摸事件,表示触摸事件被取消。这种情况下,ACTION_CANCEL 会被执行,以便你可以在代码中相应地处理触摸事件的取消。
  2. 系统事件中断触摸:当触摸事件正在进行时,如果系统发生某些中断事件,例如电话呼入、弹出对话框等,系统会生成一个 ACTION_CANCEL 的触摸事件,表示触摸事件被中断。这样可以确保用户在触摸过程中不会发生意外的操作。在这种情况下,你可以通过处理 ACTION_CANCEL 事件来恢复到触摸事件之前的状态或进行必要的清理工作。

虽然我没实现出来

ACTION_UP这个就是指头一离开,就会触发

1.4TouchSlop

这个是系统能识别出来的滑动的最小距离,如果两次滑动的距离小于它便不会被识别出来

ViewConfiguration.get(getContext().getScaledTouchSlop());

获得

2.View的滑动

《Android开发艺术探索》中只有3种滑动,分别是

1.动画

2.scrollTo/scrollBy

3.LayoutParams

艺术开发探索把后面的这种称为改变布局参数

而《进阶之光》在以上的基础上还说了

1.layout

2.offsetLeftAndRight/offsetTopAndBottom

而这两种其实也就属于改变布局参数

所以就分成3个部分讲

2.1动画

《进阶之光》讲了2种动画,

一种是属性动画,一种是View动画

先讲视图动画

2.1.1View动画

我们在res中创建anim文件,在这里面创建translate.xml文件

注意是set类型哦

以下是里面的一些属性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5bAywKm9-1684507503970)(../../assets/QQ图片20230518230859.png)]

set不用说了,translate是进行移动的,可以进行x,y轴的移动。alpha是控件的透明度,rotate是实现旋转的,scale是扩大多少倍或者缩小至几分1

比如我用translate

<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
    android:fromXDelta="0"
    android:duration="1000"
    android:toXDelta="200"/>
</set>
ima = findViewById(R.id.what);
ima.setAnimation(AnimationUtils.loadAnimation(this,R.anim.translate));

这时候我的ima会在1000ms内从x = 0移动到x = 200,但是执行完后又会退回去

我们只需要在set里面加一句

android:fillAfter = "true"

就行了

但是还是有一个问题,比如你移动的是一个button,你让它移动到x = 200的位置后,你再点击它,它并不会有相应,你必须点击x = 0的时候它才会有响应

View动画并不能改变View的位置参数

ima = findViewById(R.id.what);
Log.d("TAG",""+ima.getLeft());
ima.setAnimation(AnimationUtils.loadAnimation(this,R.anim.translate));
ima.getX();
Log.d("TAG",""+ima.getLeft());

打印出来

D/TAG: 0.0
D/TAG: 0.0

另一种讲的是

2.1.2属性动画

ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(mButton,"translationX",200);
objectAnimator.setDuration(2000);
objectAnimator.start();

这样之后mButton便会在x轴上移动移动2000ms移动200处

并且运行完之后没有返回

这时候,我们点击button发现它可以跳转到第二个Activity中,成功。

这时候我们打印以下getLeft()

发现也全是

TAG: 0
TAG: 0

View动画最后打印出来的一模一样

这是因为start();为异步方法

在start方法后写上

 Handler handler = new Handler();
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            Log.d("TAG",""+ima.getLeft());
        }
    };
    handler.postDelayed(runnable, 2000);

打印出来结果了

TAG: 492

或者

objectAnimator.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        Log.d("TAG",""+mButton.getTranslationX());
        Log.d("TAG",""+mButton.getLeft());
    }
});

也会发现getLeft改变了

但是你延迟2s打印view动画的getLeft它不会改变

2.2scrollTo/scrollBy

这个主要就是滑动,其中scrollTo是移动到某个坐标

而scrollBy是移动了多少坐标

scrollBy内部调用的就是scrollTo

看看二者的源码

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

scrollBy就是调用了个scrollTo就没了

所以看源码就直接就看scrollTo的源码

if语句判断的是:滑动的位置是否和原位置相同,不相同才会滑动

用两个新变量保存原来的位置,再把新位置赋值给mScrollXmScrollY

通过

 invalidateParentCaches();

来清除之前父布局的缓存

onScrollChanged(mScrollX, mScrollY, oldX, oldY);

用于监听与回调

最后再第二个if语句中

 if (!awakenScrollBars()) {
                postInvalidateOnAnimation();
            }

这段代码的目的是在滚动条没有被唤醒(显示)时,请求视图在下一帧进行刷新。这样做的目的是在需要显示滚动条时,确保滚动条能够正确地显示在视图上。

如果你要使用scrollTo/scrollBy有点需要

注意

在ACTION_MOVE

中,你想让它移动到(x,y)

正常情况下是

((View)getParent()),scrollTo(x,y)

但是你会发现它移动的位置不太对劲,移动到了(-x,-y)了

把代码改成

((View)getParent()),scrollTo(-x,-y)

便成功移动到(x,y)

因为scrollTo(-x, -y)方法中的参数是负值。scrollTo()方法中的参数表示要滚动到的目标位置相对于视图左上角的偏移量。通过传入负值,实际上是在将视图向相反的方向滚动,从而实现了将视图移动到目标位置的效果。

2.3 改变布局参数

2.3.1layout

 case MotionEvent.ACTION_MOVE:
                Log.d("TAG","MOVE");
                int x1 = x - lastX;
                int y1 = y - lastY;
                // 处理移动事件
                layout(getLeft() + x1,getTop() + y1,getRight() + x1,getBottom() + y1);
                break;

2.3.2setLeftAndRight

case MotionEvent.ACTION_MOVE:    
			Log.d("TAG", "MOVE");    
			int x1 = x - lastX;    // 处理移动事件  
			int left = view.getLeft() + x1;    
			int right = view.getRight() + x1;    
			view.setLeftAndRight(left, right);    
			break;

setTopAndBottom差不多

2.3.3LayoutParams

case MotionEvent.ACTION_MOVE:
    Log.d("TAG", "MOVE");
    int x1 = x - lastX;
    int y1 = y - lastY;
    // 处理移动事件
    ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
    layoutParams.leftMargin = layoutParams.leftMargin + x1;
    layoutParams.topMargin = layoutParams.topMargin + y1;
    view.setLayoutParams(layoutParams);
    break;
case MotionEvent.ACTION_MOVE:
    Log.d("TAG", "MOVE");
    int x1 = x - lastX;
    int y1 = y - lastY;
    // 处理移动事件
    ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
    layoutParams.leftMargin = layoutParams.leftMargin + x1;
    layoutParams.topMargin = layoutParams.topMargin + y1;
    view.setLayoutParams(layoutParams);
    break;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/546030.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

rt-thread启动流程(最详细教程)

资料下载 RT-Thread Simulator 例程 操作流程 将上面的仿真例程下载并解压&#xff0c;通过MDK打开&#xff0c;编译&#xff0c;调试&#xff0c;并打开串口点击运行&#xff0c;就可以看到如下输出了&#xff1a; 添加自己的 thread&#xff1a;在main()函数中添加即可&am…

【5.19】四、性能测试—流程

4.4 性能测试的流程 性能测试也遵循测试需求分析→测试计划制订→测试用例设计→测试执行→编写测试报告的基本过程&#xff0c;但在实现细节上&#xff0c;性能测试有单独一套流程&#xff1a; 1. 分析性能测试需求 在性能测试需求分析阶段&#xff0c;测试人员需要收集有关…

【AI Earth试玩】权限配置与openAPI调用工具库

前言 AI earth是阿里达摩院出的遥感云计算平台&#xff0c;我简单体验下来感觉像是GEE的python版本遥感深度学习计算平台&#xff0c;整体体验还是挺不错的&#xff0c;尤其是多分类的结果还是挺惊艳的。 平台提供工具箱和notebook两种模式&#xff0c;工具箱整个交互简单易用…

DJ 5-4 以太网 Ethernet

目录 一、以太网的物理拓扑结构 二、以太网物理层标准 1、以太网技术&#xff1a;10Base-T 和 100Base-T 2、以太网技术&#xff1a;1000Base 系列 3、曼彻斯特编码* 4、差分曼彻斯特编码机制* 三、以太网链路层控制技术 四、以太网的帧结构 1、前同步码 2、MAC 地址…

Spring Boot 项目【前后端分离】之后端实现加 LambdaQueryWrapper实现源码分析和手动模拟

目录 Spring Boot 项目【前后端分离】 之架子搭建 技术栈 实现功能03-创建Spring Boot 后端项目 需求分析/图解 思路分析 代码实现 1. 创建springboot_furn 项目 2. 修改pom.xml , 引入mybatis-plus 等相关依赖 3. 创建application.yml 配置port & 配置DB 连接信息…

【数据结构】KMP算法:计算next与nextval函数值(图解)

例&#xff1a;计算模式串"abaabcac"的KMP算法中next函数值 由函数定义 n e x t [ j ] { 0 , j 1 M a x { k ∣ 1 < k < j 且 " t 1 t 2 ⋅ ⋅ ⋅ t k − 1 " " t j − k 1 t j − k 2 ⋅ ⋅ ⋅ t j − 1 " } 1 , k 1 next[j]\left…

asp.net高校运动会管理系统的设计与实现

本高校运动会管理系统是针对我院当前运动会工作需要而开发的B/S模式的网络系统&#xff0c;涉及到运动会赛前的报名录入准备与分组编排、赛中的成绩处理、赛后的成绩汇总与团体总分的统计。它将是一个完整统一、技术先进、高效稳定、安全可靠的基于Internet/Intranet的高校运动…

一、Git安装(Git+TortoiseGit图形化)

Git 是一个开源的分布式版本控制系统&#xff0c;用于敏捷高效地处理任何或小或大的项目。 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。 Git 与常用的版本控制工具 CVS, Subversion 等不同&#xff0c;它采用了分布式版本库的方式…

《计算机网络—自顶向下方法》 Wireshark实验(八):ICMP 协议分析

ICMP&#xff08;Internet Control Message Protocol&#xff09;网络控制报文协议。它是 TCP/IP 协议簇的一个子协议&#xff0c;用于在 IP 主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户…

进程概念

目录 冯诺依曼体系结构 操作系统OS 系统调用和库函数概念 进程 task_struct内容分类 组织进程 初识fork 进程状态 Z(zombie)-僵尸进程 孤儿进程 进程优先级 环境变量 和环境变量相关的命令 环境变量的组织方式 程序地址空间 冯诺依曼体系结构 关于冯诺依曼&…

Linux 防火墙 iptables

iptables概述 Linux 系统的防火墙 &#xff1a;IP信息包过滤系统&#xff0c;它实际上由两个组件netfilter 和 iptables组成。 主要工作在网络层&#xff0c;针对IP数据包。体现在对包内的IP地址、端口、协议等信息的处理上。 iptables是Linux系统防火墙的一种&#xff0c;是Ce…

SpringBoot【开发实用篇】---- 整合第三方技术(消息)

SpringBoot【开发实用篇】---- 整合第三方技术&#xff08;消息&#xff09; 消息的概念Java处理消息的标准规范JMSAMQPMQTTKafka 购物订单发送手机短信案例订单业务短息处理业务 SpringBoot整合ActiveMQ安装整合 SpringBoot整合RabbitMQ安装整合&#xff08;direct模型&#x…

【操作系统复习】第7章 输入/输出系统1

I/O系统管理的主要对象 ➢ I/O设备和对应的设备控制器 I/O系统的主要任务 ➢ 完成用户提出的I/O请求 ➢ 提高I/O速率 ➢ 改善I/O设备的利用率 I/O系统的上、下接口 ➢ I/O系统接口&#xff08;上接口&#xff09; ➢ 软件/硬件接口&#xff08;下接口&#xff09…

实验三 传感器目标识别

【实验目的】 1、了解环境感知传感器目标识别的目的和方法&#xff0c; 掌握MATLAB中的目标检测方法。 2、了解MATLAB的目标检测器和检测函数&#xff0c;掌握车辆识别、行人识别、交通标志识别和道路识别等目标识别方法。 【实验性质】 验证性实验。 【实验要求】 MATLAB 202…

Kubernetes实战入门

文章目录 一、组件介绍&#xff08;一&#xff09;master主控节点&#xff08;二&#xff09;node工作节点 二、k8s核心概念&#xff08;一&#xff09;pod&#xff08;二&#xff09;controller&#xff08;三&#xff09;service 三、搭建k8s集群&#xff08;一&#xff09;基…

6.1 Python面向对象设计及应用

1 类和对象 对象是具有某些特性和功能的具体事物的抽象。每个对象都具有描述其特征的属性及附属于它的行为。如&#xff1a;一个人有姓名、性别、身高、体重等特征描述&#xff0c;也有走路、说话、学习、开车等行为。 每个对象都有一个类&#xff0c;类是创建对象实例的模板&…

基于springboot家具商城系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SpringBoot 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 前言 基于springboot家具商…

js数组排序的两种方法

1. 冒泡排序 原理&#xff1a;一次比较两个相邻的数&#xff0c;如果不符合规则互换位置&#xff0c;一次比较就能够将最大或最小的值放在数组最后一位继续对除【最后一位】之外的所有元素重复上述过程。 let arr [22,1,43,12,75,32]; for(let i 0; i < arr.length - 1;…

MySQL一条查询语句是怎么执行的?MySQL 的架构是什么样子?

先谈谈MySQL的架构&#xff0c;这样自然就搞清楚一条语句是怎么执行的了 首先&#xff0c;MySQL分为客户端&#xff0c;服务端&#xff0c;存储引擎 客户端&#xff1a; ● Java程序啊&#xff0c;可视化连接工具 Navicat啊等等&#xff0c;就是客户端&#xff1b; 服务端&…

Vivado 下 IP核 之ROM 读写

目录 Vivado 下 IP核 之ROM 读写 1、实验简介 2、ROM IP 核简介 3、ROM IP 核配置 3.1、创建 ROM 初始化文件 3.2、单端口 ROM 的配置 3.3、双端口 ROM 的配置 3.4、ROM IP 核的调用 &#xff08;1&#xff09;ROM 顶层模块代码 &#xff08;2&#xff09;ROM IP 核仿…