Android自定义控件_让每一个Activity UI都具有弹性

Android自定义控件之扫描动画UI 前言最近有一个需求,就是做一个扫描的UI,看了很多扫描动画,发现酷狗的扫描动画挺漂亮的,所以就做了一个相似的扫描动画,废话不多说,先看一下最终的效果吧。 最终效果图介绍首先我们看一下这个效果,它由以下几部分组成: 1.中间一个音符图片 2.在音符图片外面画了三个圆环 3.一个旋转的扇形动画 既然知道它的结构那就来一步一步实现它吧。准备 @Override protected 阅读详情

前面我们已经介绍了如何让你的ScrollView,ListView具有弹性,

今天,我们在前面的基础上,做一下适当的修改,让那些既不是ScrollView,也不是ListView的Activity页面,也能具有弹性。

先上图:


图中是最简单的一个Android测试程序。默认的效果TextView是无法划动的。

进过我们小小的改造,就能让整个UI具有弹性效果。

改动如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. protected void onCreate(Bundle savedInstanceState) {  
  2.         super.onCreate(savedInstanceState);  
  3.         View view = getLayoutInflater().inflate(R.layout.activity_main, null);  
  4.         view.setOnTouchListener(new ElasticTouchListener());  
  5.         setContentView(view);  
  6.     }  
我们仅仅只需要在需要弹性的Root VIew 上加上监听。就能达到如果的效果了。

ElasticTouchListener源码:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class ElasticTouchListener implements OnTouchListener {  
  2.     private View inner;  
  3.     View[] children;  
  4.     private float y;  
  5.     private Rect normal = new Rect();  
  6.     private boolean animationFinish = true;  
  7.     private int[] tops;  
  8.     private int[] bottoms;  
  9.   
  10.     @Override  
  11.     public boolean onTouch(View v, MotionEvent ev) {  
  12.         if (inner == null && children == null) {  
  13.             if (v instanceof ViewGroup) {  
  14.                 ViewGroup group = (ViewGroup) v;  
  15.                 int count = group.getChildCount();  
  16.                 if (count > 0) {  
  17.                     children = new View[count];  
  18.                     tops = new int[count];  
  19.                     bottoms = new int[count];  
  20.                     for (int i = 0; i < count; i++) {  
  21.                         children[i] = group.getChildAt(i);  
  22.                         tops[i] = children[i].getTop();  
  23.                         bottoms[i] = children[i].getBottom();  
  24.                     }  
  25.                 }  
  26.             }  
  27.             inner = v;  
  28.         }  
  29.         if (animationFinish && (inner != null || children != null)) {  
  30.             int action = ev.getAction();  
  31.             switch (action) {  
  32.             case MotionEvent.ACTION_DOWN:  
  33. //              System.out.println("ACTION_DOWN");  
  34.                 y = ev.getY();  
  35.                 break;  
  36.             case MotionEvent.ACTION_UP:  
  37. //              System.out.println("ACTION_UP");  
  38.                 y = 0;  
  39.                 if (isNeedAnimation()) {  
  40.                     animation();  
  41.                 }  
  42.                 inner.invalidate();  
  43.                 break;  
  44.             case MotionEvent.ACTION_MOVE:  
  45. //              System.out.println("ACTION_MOVE");  
  46.                 final float preY = y == 0 ? ev.getY() : y;  
  47.                 float nowY = ev.getY();  
  48.                 int deltaY = (int) (preY - nowY);  
  49.                 y = nowY;  
  50.                 // 当滚动到最上或者最下时就不会再滚动,这时移动布局  
  51.                 if (isNeedMove()) {  
  52.                     if (normal.isEmpty()) {  
  53.                         // 保存正常的布局位置  
  54.                         normal.set(inner.getLeft(), inner.getTop(), inner.getRight(), inner.getBottom());  
  55.                     }  
  56.                     if (children != null) {  
  57.                         View view = null;  
  58.                         for (int i = 0; i < children.length; i++) {  
  59.                             view = children[i];  
  60.                             view.layout(view.getLeft(), view.getTop() - deltaY / 2, view.getRight(), view.getBottom() - deltaY / 2);  
  61.                         }  
  62.                     } else {  
  63.                         // 移动布局  
  64.                         inner.layout(inner.getLeft(), inner.getTop() - deltaY / 2, inner.getRight(), inner.getBottom() - deltaY / 2);  
  65.                     }  
  66.                 }  
  67.                 inner.invalidate();  
  68.                 break;  
  69.             default:  
  70.                 break;  
  71.             }  
  72.         } else {  
  73.             return false;  
  74.         }  
  75.         return true;  
  76.     }  
  77.   
  78.     // 开启动画移动  
  79.   
  80.     public void animation() {  
  81.         if (children == null) {  
  82.             // 开启移动动画  
  83.             TranslateAnimation trans = new TranslateAnimation(0, 0, 0, normal.top - inner.getTop());  
  84.             trans.setDuration(200);  
  85.             trans.setAnimationListener(new AnimationListener() {  
  86.                 @Override  
  87.                 public void onAnimationStart(Animation animation) {  
  88.                     animationFinish = false;  
  89.                 }  
  90.                 @Override  
  91.                 public void onAnimationRepeat(Animation animation) {  
  92.                 }  
  93.                 @Override  
  94.                 public void onAnimationEnd(Animation animation) {  
  95.                     inner.clearAnimation();  
  96.                     // 设置回到正常的布局位置  
  97.                     inner.layout(normal.left, normal.top, normal.right, normal.bottom);  
  98.                     normal.setEmpty();  
  99.                     animationFinish = true;  
  100.                 }  
  101.             });  
  102.             inner.startAnimation(trans);  
  103.         } else {  
  104.             for (int i = 0; i < children.length; i++) {  
  105.                 final View view = children[i];  
  106.                 if (view.getVisibility() == View.VISIBLE) {  
  107.                     final int index = i;  
  108.                     // 开启移动动画  
  109.                     TranslateAnimation trans = new TranslateAnimation(0, 0, 0, tops[i] - view.getTop());  
  110.                     trans.setDuration(200);  
  111.                     trans.setAnimationListener(new AnimationListener() {  
  112.                         @Override  
  113.                         public void onAnimationStart(Animation animation) {  
  114.                             animationFinish = false;  
  115.                         }  
  116.                         @Override  
  117.                         public void onAnimationRepeat(Animation animation) {  
  118.   
  119.                         }  
  120.                         @Override  
  121.                         public void onAnimationEnd(Animation animation) {  
  122.                             view.clearAnimation();  
  123.                             // 设置回到正常的布局位置  
  124.                             view.layout(view.getLeft(), tops[index], view.getRight(), bottoms[index]);  
  125.                             normal.setEmpty();  
  126.                             animationFinish = true;  
  127.                         }  
  128.                     });  
  129.                     view.startAnimation(trans);  
  130.                 }  
  131.             }  
  132.         }  
  133.   
  134.     }  
  135.   
  136.     // 是否需要开启动画  
  137.     public boolean isNeedAnimation() {  
  138.         return !normal.isEmpty();  
  139.     }  
  140.   
  141.     // 是否需要移动布局  
  142.     public boolean isNeedMove() {  
  143. //      int offset = inner.getMeasuredHeight() - getHeight();  
  144. //      int scrollY = getScrollY();  
  145. //      if (scrollY == 0 || scrollY == offset) {  
  146. //          return true;  
  147. //      }  
  148. //      return false;  
  149.           
  150. //      if (children != null && children.length > 0  
  151. //              && (children[children.length - 1].getBottom() <= inner.getPaddingTop()/*inner.getTop()*/  
  152. //              || children[0].getTop() >= inner.getHeight()  
  153. //              )) {  
  154. //          return false;  
  155. //      }  
  156.           
  157.         return true;  
  158.     }  
  159. }  

本次教程就到此,

经过有弹性的ScrollView,有弹性的ListView,以及本文的介绍,就可以让你的Android应用在每一个角落都拥有弹性啦。

自动驾驶仿真(五)—— 基于Carsim、Prescan、Simulink的联合仿真 自动驾驶仿真五——基于Carsim、Prescan、Simulink的联合仿真1. 联合仿真流程2. CarSim联合仿真配置要点3. Prescan联合仿真配置要点4. Carsim、Prescan、Simulink联合仿真结果5. 参考学习的书目教材 博主前面的博文已经介绍了Carsim和Prescan各自与Matlab/Simulink的相关联合仿真应用实例,并且论述过几款软件各自的优势及用法,CarSim适合动力学模型的建立,PreScan适合行车场景的搭建,Simulink适合控制算法的设计及信号 阅读详情

相关推荐

ESP32搭配FT6236触摸屏:从芯片手册到完整I2C驱动代码的保姆级解析

本文详细解析了ESP32搭配FT6236触摸屏的I2C驱动开发过程,从芯片手册解读到完整代码实现。通过硬件架构分析、寄存器配置、I2C通信封装及触摸数据处理等步骤,提供了一套完整的驱动解决方案,帮助开发者快速掌握ESP32与触摸屏的交互技术。

weixin_29174385的博客 291

让每一个Activity UI都具有弹性

前面我们已经介绍了如何让你的ScrollView,ListView具有弹性, 今天,我们在前面的基础上,做一下适当的修改,让那些既不是ScrollView,也不是ListView的Activity页面,也能具有弹性。 先上图: 图中是最简单的一个Android测试程序。默认的效果TextView是无法划动的。 进过我们小小的改造,就能让整个UI具有弹性效果。

Enbiting的专栏 615

S32K3基于EB配置GPT触发WDG的实战解析

本文详细解析了S32K3 MCU基于EB tresos工具配置GPT定时器触发看门狗(WDG)的实战方法。通过分析协同工作机制、MCAL配置步骤及代码实现,帮助开发者构建可靠的硬件监控系统,提升汽车电子系统的安全性与实时性。

f9g0h的博客 204

Android 自定义控件和动画

优快云启舰大神的Android自定义控件三部曲

随风的博客 1062

使用LSTM(长短期记忆)模型处理文本数据的典型流程

对于序列到序列的任务(如机器翻译),可以使用LSTM的隐状态来生成目标序列。这些向量捕获了词之间的语义关系,每个词都被表示为一个高维空间中的点,语义上相似的词在向量空间中彼此靠近。这通常是通过创建一个词汇表(vocabulary)来实现的,词汇表中的每个词都会被分配一个唯一的数字ID。:由于LSTM等循环神经网络(RNN)需要固定长度的输入,所以需要将不同长度的句子填充到相同的长度。由于计算机不能直接理解连续的文本,第一步是将文本分割成独立的词或标记(token)。:将词嵌入作为输入传递给LSTM模型。

YHKKun的博客 2500

秋叶ComfyUI整合包:一键部署AI绘画工作流,解决环境配置难题

在AI绘画和生成式AI领域,Stable Diffusion作为开源的扩散模型,为图像生成提供了强大的技术基础。其核心原理是通过学习数据分布,对随机噪声进行逐步去噪,最终生成高质量的图像。这项技术的价值在于极大地降低了专业图像创作的门槛,并推动了AIGC(人工智能生成内容)在艺术设计、游戏开发、广告营销等场景的广泛应用。然而,其典型工作流实现工具ComfyUI,在实际部署中常因Python环境、PyTorch版本与CUDA驱动之间的复杂依赖关系而受阻,尤其是面对NVIDIA 30系、40系及未来50系等不同

优快云头条 668

Android自定义控件与动画的使用

控件是android开发过程中必不可少的部分,官方本身也给我们提供了许多的控件以供我们使用。但是有的时候已有控件并不能满足我们的需求,所以这个时候就需要我们自己来自定义控件。如果我们要学习自定义控件的话,我们需要去学习view的绘制过程这方面的知识,如果你需要为你的控件加上动画的话,你还需要学习android动画方面的知识,在这个过程中你可能还要学习一下android分发机制。

qq_35700731的博客 3984

Node-Red系列教程——NodeRed通过OPC UA读取数据并写入mysql

NodeRed通opcua读取西门子数据并存入mysql

鲸鱼姐的专栏 1万+

Android 控件Button属性方法

#ANDROID控件 Button属性方法 Bunttond是在人机交互是使用较多的组件,当用户进行某些选择的时候,可以通过Button的操作来接受用户的选择。 Button的组件层次关系如下: java.lang.Object android.view.View android.widget.TextView android.widget.Button ##Button组...

zt336611的博客 767

FOC高频注入量产级C语言实现方案

高频注入技术是无传感器FOC实现零速和低速控制的关键方法,解决了传统反电动势观测器在低速失效的问题。该技术通过向电机注入高频电压信号,利用永磁同步电机凸极性特性,从高频电流响应中解调出转子位置信息。文章详细介绍了三种主流高频注入方法(旋转电压注入、脉振电压注入和脉振电流注入)的原理及实现流程,重点分析了脉振电压注入的信号处理步骤和位置观测器设计。同时提供了完整的C语言实现代码,包括硬件抽象层、核心算法模块(坐标变换、电流环、SVPWM等)和系统集成方案,并给出量产优化建议和安全保护机制。这套方案适用于要求高

汽车软件开发 793

【专栏目录】

🌟 深度学习工程师的终极武器库!本专栏深度解析近3年CV领域最前沿的YoloV8改进方案,每一种方法都经过实战验证,性能显著提升!🌟。

m0_47867638的博客 1万+

Android自定义控件(四)——让每一个Activity UI都具有弹性

前面我们已经介绍了如何让你的ScrollView,ListView具有弹性, 今天,我们在前面的基础上,做一下适当的修改,让那些既不是ScrollView,也不是ListView的Activity页面,也能具有弹性。 先上图: 图中是最简单的一个Android测试程序。默认的效果TextView是无法划动的。 进过我们小小的改造,就能让整个UI具有弹性效果。 改动如下: pro

简单随心的Android之旅 3652

WPF高级 | WPF 与数据库交互:连接、查询与数据更新

WPF高级 | WPF 与数据库交互:连接、查询与数据更新,在现代应用程序开发中,数据的存储和管理至关重要。Windows Presentation Foundation(WPF)作为一款强大的图形界面开发框架,常常需要与数据库进行交互,以实现数据的持久化存储、读取和更新。本文将深入探讨 WPF 与数据库交互的各个方面,包括数据库连接的建立、数据查询的执行以及数据更新的操作,并通过丰富的代码示例和详细的概念解释,帮助读者掌握这一关键技术。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 6万+

让Activity UI普通控件具有弹性效果(一)

一、定义监听器 package test.xzy.com.test1.listener; import android.graphics.Rect; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.animation.Ani

记录移动开发相关的知识 781

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

让Activity UI普通控件具有弹性效果(二)

在这篇文章中,使用了自定义的一个类来实现弹性UI的效果,我测试发现效果在屏幕控件比较多的情况下还是不尽如人意,因此,有了这一篇文章的产生。这个文章中的代码借鉴了网络上的大神代码,来更加灵活的实现弹性效果,甚至不需要修改任何java代码,只需要自定义一个类继承自ScrollView,并且在布局文件中引用该标签即可。 下面给出实现步骤和使用步骤: 1.定义一个类,并继承自ScrollVie

记录移动开发相关的知识 787

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Android UI布局与控件开发实战指南

Android UI开发是移动应用构建的核心环节,基于视图(View)和视图组(ViewGroup)的层级结构实现界面布局。系统提供多种布局类型如LinearLayout、ConstraintLayout等,通过XML文件定义控件排列规则,结合测量-布局-绘制流程完成界面渲染。优秀的UI设计需要兼顾代码复用性(include标签)、性能优化(减少嵌套层级)和跨设备适配(多屏幕尺寸支持)。本文以登录界面为例,详解如何使用权重分配、ViewStub延迟加载等实用技巧,并介绍Hierarchy Viewer等工具

weixin_34387468的博客 402

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

让Activity UI普通控件具有弹性效果(三)

SlidingLayout是一种Android平台的View控件,可以帮助你实现类似微信网页浏览的下拉功能,也可以帮助你实现类似iOS中UITableView的下拉上拉弹跳的果冻效果。 SlidingLayout完美兼容Android自带库和兼容库的所有View组件,包括RecyclerView、ListView、ScrollView以及WebView等等。 SlidingLayout

记录移动开发相关的知识 651

如何在Android项目中快速集成ElasticViews?3步实现惊艳交互

ElasticViews是一款专为Android开发者打造的弹性触摸效果库,通过简单的集成步骤就能为你的应用添加流畅自然的弹性交互体验。本文将详细介绍如何在3个步骤内完成集成,让你的按钮、卡片等UI元素拥有令人惊艳的触摸反馈效果。 ## 1. 一键导入项目依赖 首先需要将ElasticViews库添加到你的Android项目中。最直接的方式是通过项目依赖引用本地模块: 在你的app模块下的`

gitblog_00452的博客 954

ElasticViews核心组件全解析:从Button到Layout的5种弹性视图

ElasticViews是一款专为Android开发者打造的弹性触摸效果实现库,通过简单集成即可为应用界面添加生动的按压反馈。本文将详细介绍5种核心弹性视图组件的特性与应用场景,帮助开发者快速掌握弹性交互设计的实现方法。 ## 1. 基础交互组件:ElasticButton 作为最常用的交互控件,ElasticButton为普通按钮添加了细腻的弹性缩放效果。在布局文件中通过自定义属性可轻松配置

gitblog_01039的博客 230

Android高性能编码 - 第四篇 layout加载UI优化

本篇对Android应用的UI渲染加载性能相关项进行阐述,这里的layout既包括使用xml文件定义的layout资源,也包括java代码动态创建的UI资源以及自定义组合资源,其中图片相关的部分已在第三篇进行集中阐述,这里不再细表,而是从一般意义上的UI界面加载层面进行探讨。4.1 Activity基类布局和子类布局的协调根据编码实践,我们通常会为Activity抽取基类,同时在基类中抽取父布局,...

BlueYangDroid的专栏 724

Android View滚动、拉伸到顶/底部弹性回弹复位

 《Android View滚动、拉伸到顶/底部弹性回弹复位》 我在上一篇文章介绍了如何实现一个Android ListView拉到顶/底部后,像橡皮筋一样弹性回弹复位(《Android ListView拉到顶/底部,像橡皮筋一样弹性回弹复位》,文章链接地址: http:/...

weixin_33842304的博客 771

2024最新百度、头条等公司Android社招面试题目,安卓面试基础技能罗列

自我介绍一下,小编13年北京科技大学毕业,曾经在字节跳动待过,也去过vivo、小米等大厂,18年进入华为一直到现在。小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担,能在岗位上再创辉煌,步步高升!!。

2401_84904167的博客 969

安卓翻译(一)Activities—Fragments

一个片段(fragment)代表在一activity种一个行为或者用户界面的一部分。你能在一个单独的activity中混合多个fragment来建立一个多个面板的UI和在多个activity中重用fragment。你能将fragment认为是activity的一个模块化部分,它有着自己的生命周期,接受它自己的输入事件,和能在activity运行的同时添加或移除它(稍稍地想一个子activity,你

jiangxiaoma111的专栏 930
上一篇: Android 自定义组件_开关控件
下一篇: 自定义组件——控件平滑移动的方法
乐由心起
博客等级 码龄16年 61粉丝 295原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值