【Android】view的基础知识

news2024/10/28 4:09:30

文章目录

  • View与ViewGroup
  • View位置参数
  • View的滑动
    • 1. scrollTo与scrollBy
    • 2. 属性动画
      • ObjectAnimator
      • ViewPropertyAnimator
    • 3. LayoutParams(布局参数)
    • layout方法
    • offsetLeftAndRight
  • View的弹性滑动
    • 1. Scroller 类
    • 2. 动画(ObjectAnimator)
    • 3. 延时

View与ViewGroup

View 是 Android 中的 UI 组件的基类,代表了用户界面上的一个可视元素。所有的 UI 组件(例如 ButtonTextViewImageView 等)都直接或间接继承自 View 类。

ViewGroupView的一个子类,作为一个容器,能够包含多个子View或其他ViewGroup。它定义了子视图的布局规则和排列方式。

  • ViewGroup常见子类:LinearLayoutRelativeLayoutFrameLayoutConstraintLayout等,都是ViewGroup的子类,提供了不同的布局策略。
  • ViewGroup是一个容器,可以嵌套子View和其他ViewGroup

image-20241027224413737

View位置参数

image-20241027153742783

  • getX()getY()

    • getX() :获得点击事件距离控件左边的距离
    • getY() :获得点击事件距离控件顶边的距离
  • getRawX()getRawY()

    getRawX():返回点击事件在屏幕上的 X 坐标值。

    getRawY():返回点击事件在屏幕上的 Y 坐标值。

  • getLeft()getTop()getRight()getBottom()

    • getLeft():返回 View 左边缘相对于父布局的距离。
    • getTop():返回 View 上边缘相对于父布局的距离。
    • getRight():返回 View 右边缘相对于父布局的距离。
    • getBottom():返回 View 下边缘相对于父布局的距离。
    • 可以用来计算 View 的宽高:
      int width = view.getRight() - view.getLeft();
      int height = view.getBottom() - view.getTop();
      

View的滑动

第一种:通过View本身提供的scrollTo/scrollBy方法来实现滑动

第二种:通过动画给View施加平移效果来实现滑动

第三种:通过改变ViewLayoutParams使得View重新布局从而实现滑动

1. scrollTo与scrollBy

image-20241027161439784

  • 这两个方法用于View内容的滚动,改变View内容的相对位置
  • scrollTo(x,y)表示移动到一个具体的坐标点, scrollBy(dx,dy)则表示移动的增量为 dxdy
  • 在 ViewGroup 中使用,则是移动其所有的子 View。
  • mScrollX:记录的是View左边缘与View内容左边缘在水平方向的距离。

  • 视图的水平偏移量。

    mScrollX正值 时,表示View的内容向左滚动,内容的左边缘比View的左边缘要靠右。

  • mScrollY:记录的是View上边缘与View内容上边缘在竖直方向的距离。

  • 视图的垂直偏移量。

    mScrollY正值 时,表示View的内容向上滚动,内容的上边缘比View的上边缘要更低。

scrollTo(x, y)mScrollXmScrollY 会被设置为 (x, y),表示视图内容直接滚动到指定的位置。

scrollBy(dx, dy):会在现有的 mScrollXmScrollY 基础上增加或减少 dxdy,表示基于当前的位置进行相对滚动。

比如把一个按钮移动到当前位置右下角:

scrollBy(-20, -20);

2. 属性动画

通过动画来实现 View 的平移滑动效果,是一种较为灵活且常用的方式。这种方法不仅可以控制滑动的距离和方向,还能够调整滑动的速度、加速度等效果,让动画更流畅和自然。

ObjectAnimator

ObjectAnimator 可以对 ViewtranslationXtranslationY 属性进行动画设置,从而实现水平方向和垂直方向的平移效果。translationXtranslationY 是相对于 View 的初始位置的偏移量,单位是像素。

// 水平方向平移动画,向右平移100像素,动画时长500毫秒
ObjectAnimator animatorX = ObjectAnimator.ofFloat(view, "translationX", 0f, 100f).setDuration(500);; 
animatorX.start();

// 垂直方向平移动画,向下平移100像素
ObjectAnimator animatorY = ObjectAnimator.ofFloat(view, "translationY", 0f, 100f).setDuration(500); 
animatorY.start();

ViewPropertyAnimator

view.animate()
    .translationX(100f) // 向右平移100像素
    .translationY(100f) // 向下平移100像素
    .setDuration(500)   // 动画时长500毫秒
    .start();

3. LayoutParams(布局参数)

LayoutParams用于保存一个view的布局参数,我们可以通过改变view的布局参数来改变位置

步骤:

  1. 获取当前 View 的 LayoutParams:

    getLayoutParams() 方法获取当前 View 的布局参数。

  2. 修改 LayoutParams:

    根据需要改变布局参数的属性,比如位置、宽高等。

  3. 请求重新布局:

    修改完布局参数后,调用 requestLayout() 方法,重新布局该 View。

// 假设这是一个 Button,我们要让它向右滑动
Button myButton = findViewById(R.id.my_button);
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) myButton.getLayoutParams();

// 修改左边距,向右滑动
layoutParams.leftMargin += 50; // 每次滑动 50 像素
myButton.setLayoutParams(layoutParams); // 设置新的 LayoutParams
myButton.requestLayout(); // 请求重新布局

父控件是 LinearLayout,使用LinearLayout.LayoutParams

父控件是RelativeLayout,使用 RelativeLayout.LayoutParams

除了使用布局的 LayoutParams 外还可以用 ViewGroup.MarginLayoutParams :

layout方法

实现一个可以随触摸移动的view

public class CustomeView extends View {
    private int lastX; // 上一个 X 坐标
    private int lastY; // 上一个 Y 坐标

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

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

    public CustomeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public CustomeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX(); // 获取当前触摸点的 X 坐标
        int y = (int) event.getY(); // 获取当前触摸点的 Y 坐标

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN: // 触摸开始
                lastX = x; // 记录当前 X 坐标
                lastY = y; // 记录当前 Y 坐标
                break;
            case MotionEvent.ACTION_MOVE: // 触摸移动
                // 计算移动的偏移量
                int offsetX = x - lastX; 
                int offsetY = y - lastY; 
                // 更新视图的位置
                layout(getLeft() + offsetX, getTop() + offsetY, getRight() + offsetX, getBottom() + offsetY);
                break;
        }
        return true; // 返回 true 表示事件已被处理
    }
}

offsetLeftAndRight

也能实现4的效果

case MotionEvent.ACTION_MOVE:
	int offsetX = x - lastX;
	int offsetY = y - lastY;
	offsetLeftAndRight(offsetX);
	offsetTopAndBottom(offsetY);
	break;

View的弹性滑动

1. Scroller 类

Scroller 是 Android 提供的一个辅助类,用于实现 View 的平滑滑动。Scroller 并不直接负责滑动,而是通过计算出一系列中间值(如位置)来协助 View 实现平滑的滑动效果。

  1. 初始化 Scroller

    private Scroller scroller;
    
    public MyView(Context context) {
        super(context);
        scroller = new Scroller(context);
    }
    
  2. 调用 startScroll() 方法:用于开始一个平滑滚动。

    public void smoothScrollTo(int destX, int destY) {
        int scrollX = getScrollX();
        int delta = destX - scrollX;
        scroller.startScroll(scrollX, 0, delta, 0, 1000); // 1000ms 内滑动
        invalidate(); // 触发重绘
    }
    
  3. 重写 computeScroll() 方法:在绘制期间不断调用 computeScroll() 来更新 View 的位置。

    @Override
    public void computeScroll() {
        if (scroller.computeScrollOffset()) { // 计算滑动偏移量
            scrollTo(scroller.getCurrX(), scroller.getCurrY());
            postInvalidate(); // 再次触发重绘
        }
    }
    
  4. activity或者fragment调用

myView.smoothScrollTo(100, 100); // 平滑移动到 (100, 100) 的位置

2. 动画(ObjectAnimator)

ObjectAnimator 可以直接对 View 的属性进行动画操作,是另一种实现弹性滑动效果的方式。

示例代码:

ObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationX", 0f, 100f);
animator.setDuration(1000); // 设置动画持续时间
animator.start();

3. 延时

有时需要延迟滑动以增强用户体验,比如在手指抬起后稍作延迟再开始滑动。使用 HandlerpostDelayed() 方法来实现延时:

view.postDelayed(new Runnable() {
    @Override
    public void run() {
        smoothScrollTo(100, 0); 
    }
}, 300);


感谢您的阅读
如有错误烦请指正


参考:

  1. 《Android开发艺术探索》
  2. 《Android进阶之光》

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

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

相关文章

SYN590RL 300MHz至450MHz ASK接收机芯片IC

一般描述 SYN590RL是赛诺克全新开发设计的一款宽电压范围,低功耗,高性能,无需外置AGC电容,灵敏度达到典型-110dBm,300MHz”450MHz 频率范围应用的单芯片ASK或OOK射频接收器。 SYN59ORL是一款典型的即插即用型单片高集成度无线接收器&…

Spring Boot实现的动态化酒店住宿管理系统

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及,互联网成为人们查找信息的重要场所,二十一世纪是信息的时代,所以信息的管理显得特别重要。因此,使用计算机来管理酒店客房管理系统的相关信息成为必然。开发…

pytorch的标签平滑介绍

什么是标签平滑(Label Smoothing)? 标签平滑(Label Smoothing)是一种正则化技术,旨在防止模型过度自信(即输出的概率分布过于“尖锐”)。在分类任务中,标准的目标标签是one-hot编码,也就是正确类别的概率为 1,其他类别的概率为 0。而标签平滑通过将正确类别的概率从…

绝了,这款播放器让发烧友疯狂种草,堪称音乐神器

作为音乐爱好者的不二之选,foobar2000凭借其卓越的音频处理能力,在Windows系统用户中树立了极高的声誉。这款轻量级播放器的设计理念是将极致的性能与个性化完美结合。用户可以根据自己的使用习惯,打造出独具特色的播放界面和操作流程。在音频…

【redis】初识非关系型数据库——redis

W...Y的主页 😊 代码仓库分享💕 初识 Redis Redis是⼀种基于键值对(key-value)的NoSQL数据库,与很多键值对数据库不同的是,Redis 中的值可以是由string(字符串)、hash&#xff0…

html 登入界面,用户注册界面相关的标签及案例

案例效果图 以上界面的完整代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</titl…

Python浪漫之画星星

效果图&#xff08;动态的哦&#xff01;&#xff09;&#xff1a; 完整代码&#xff08;上教程&#xff09;&#xff1a; import turtle import random import time # 导入time模块# 创建一个画布 screen turtle.Screen() screen.bgcolor("red")# 创建一个海龟&a…

【学术论文投稿】Windows11开发指南:打造卓越应用的必备攻略

【IEEE出版南方科技大学】第十一届电气工程与自动化国际会议&#xff08;IFEEA 2024)_艾思科蓝_学术一站式服务平台 更多学术会议论文投稿请看&#xff1a;https://ais.cn/u/nuyAF3 目录 引言 一、Windows11开发环境搭建 二、Windows11关键新特性 三、Windows11设计指南 …

Android 自定义 Dialog 实现列表 单选,多选,搜索

前言 在Android开发中&#xff0c;通过对话框让用户选择&#xff0c;筛选信息是很方便也很常见的操作。本文详细介绍了如何使用自定义 Dialog、RecyclerView 以及自定义搜索框 来实现选中状态和用户交互&#xff0c;文中大本分代码都有明确注释&#xff0c;主打一个简单明了&a…

springboot 同时上传文件和JSON对象

控制器代码 PostMapping("/upload") public ResponseEntity<String> handleFileUpload(RequestPart("file") MultipartFile file,RequestPart("user") User user) {// 处理文件和用户信息return ResponseEntity.ok("File and user i…

tomcat部署war包部署运行,IDEA一键运行启动tomacat服务,maven打包为war包并部署到tomecat

tomcat部署war包前端访问 在Java Web开发中&#xff0c;Tomcat是一个非常流行的开源Web服务器和Servlet容器。它实现了Java Servlet和JavaServer Pages (JSP) 技术&#xff0c;提供了一个纯Java的Web应用环境。本文将介绍如何在Tomcat中部署运行WAR包&#xff0c;让你的应用快…

SpringBoot实现mysql多数据源配置(Springboot+Mybatis)

最近在学习SpringBoot的一些知识&#xff0c;主要是参考了纯洁的微笑的一些博客作为练手&#xff0c;想着他已经把入门的教程写的很详细了,如果再简单的把他的教程拷贝到自己的简书&#xff0c;这是是赤裸裸的剽窃&#xff0c;很不地道&#xff0c;作为一个技术人员&#xff0c…

通过页面添加国际化数据,实现vue的国际化

element ui 写在前面1. 原有的vue的国际化处理1.1 语言文件1.2 lang的index.js1.3 入口文件导入1.3 应用 2. 通过页面添加国际化数据2.1 做法2.2 lang的index.js文件修改2.3 需要注意的点 总结写在最后 写在前面 需求&#xff1a;在系统的国际化管理页面添加国际化数据&#x…

机器视觉-相机、镜头、光源(总结)

目录 1、机器视觉光源概述 2、光源的作用 3、光谱 4、工业场景常见光源 4.1、白炽灯 4.2、卤素灯 4.3、 荧光灯 4.4、LED灯 4.5、激光灯 5、光源的基本性能 5.1、光通量 5.2、光效率 5.3、发光强度 5.4、光照度 5.5、均匀性 5.6、色温 5.7、显色性 6、基本光学…

嵌入式软开项目——电子手环开发——学习引导和资料网址

文末附所有资料下载链接 1、需要将该文件夹放置到英文路径下&#xff0c;否则无法运行 2、目录下总共四个文件夹 2.1 第一个文件夹“0、OV-Watch-main(原版)”&#xff0c;为开源代码的原版资料 2.2第二个文件夹” OV-Watch-main”&#xff0c;为本人对开源代码的学习&…

Java-I/O框架02:使用文件字节流复制文件

package com.yundait.Demo03;import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream;/*** 使用文件字节流实现文件的复制* author zhang*/ public class FileInputStreamDemo03 {public static void main(String[] args) th…

多线程——线程的状态

线程状态的意义 ‌线程状态的意义在于描述线程在执行过程中的不同阶段和条件&#xff0c;帮助开发者更好地管理和调度线程资源。 线程的多种状态 线程的状态是一个枚举类型&#xff08;Thread.State&#xff09;&#xff0c;可以通过线程名.getState&#xff08;&#xff09…

基于Springboot+Vue 高考志愿咨询管理系统(源码+LW+部署讲解+数据库+ppt)

&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 会持续一直更新下去 有问必答 一键收藏关注不迷路 源码获取&#xff1a;https://pan.baidu.com/s/1aRpOv3f2sdtVYOogQjb8jg?pwdjf1d 提取码: jf1d &#…

react 总结+复习+应用加深

文章目录 一、React生命周期1. 挂载阶段&#xff08;Mounting&#xff09;补充2. 更新阶段&#xff08;Updating&#xff09;补充 static getDerivedStateFromProps 更新阶段应用补充 getSnapshotBeforeUpdate3. 卸载阶段&#xff08;Unmounting&#xff09; 二、React组件间的…

智能合约分享

智能合约练习 一、solidity初学者经典示例代码&#xff1a; 1.存储和检索数据&#xff1a; // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // 声明 Solidity 编译器版本// 定义一个名为 SimpleStorage 的合约 contract SimpleStorage {// 声明一个公共状态变量 d…