辉夜的博客

繁花似锦,辉夜如昼

0%

安卓UI设计

Android UI组件

User Interface,用户接口。包括输入框,文本,按钮,播放器,图片,列表等。常规的组件大多由android.widget包中提供,这些组件有通用的属性和方法,也有自己特定的属性和方法。比如所有组件都有id,height,width,margin等属性,而TextView有setText的方法。

常规UI组件

安卓组件以左上角为原点,向下向右为正方向。这也是组件的默认布置为止
带有layout的属性通常是组件相对于父容器的对齐方式,带有padding的则是子元素相对于容器的对齐方式

组件属性

高级UI组件

高级组件通常继承自ViewGroup,可以内含多个View组件,也可以继续嵌套ViewGroup

布局

布局将ui组合成页面,主要控制大小、位置、层级

线性布局

属性 功能描述
android:orientation 布局内组件的排列方向
android:layout_weight 布局内组件大小权重
android:divider 布局内组件间分割线
android:showDividers 布局内组件间分割线位置
android:dividerPadding 布局内分割线padding

linearlayout的分割线功能可以很容易的画出有质感的ui

weight功能是指示分配剩余空间时的权重(剩余空间可正可负),各个组件按照权重加权平均分配剩余的空间。

如果想要在linearlayout里做出垂直于orientation方向的效果,就要再嵌套一个另一方向的linearlayout

相对布局

相对布局提供了根据父容器和兄弟容器进行定位的方法

类别 属性 功能描述
根据父容器定位 android:layout centerInParent 组件位于父容器中央位置
android:layout_centerHorizontal 组件位于父容器水平中央位置
android:layout_centerHorizontal 组件位于父容器水平中央位置
android:layout_centerVertical 组件位于父容器垂直中央位置
android:layout_alignParentTop 组件与父容器顶部对齐
android:layout_alignParentLeft 组件与父容器左部对齐
android:layout_alignParentRight 组件与父容器右部对齐
android:layout_alignParentBottom 组件与父容器底部对齐
根据兄弟组件定位 android:layout_above 组件位于某组件上部
android:layout_below 组件位于某组件下部
android:layout_toLeftOf/toRightOf 组件位于某组件左/右侧
android:layout_alignTop/Left/Right/Below 组件与某组件对齐

层级布局FrameLayout

属性 描述
android:foreground 设置前景图像(永远位于最前)
android:foregroundGravity 设置前景图像Gravity

各个组件从前到后依次在后方作为背景

限制布局ConstraintLayout

属性 功能描述
layout_constraintLeft_toLeftOf 组件左部与某组件左部对齐
layout_constraintLeft_toRightOf 组件左部与某组件右部对齐
layout_constraintRight_toLefOf 组件右部与某组件左部对齐
layout_constraintRight_toRightOf 组件右部与某组件右部对齐
layout_constraintTop_toTopof 组件顶部与某组件顶部对齐
layout_constraintTop_toBottomOf 组件右顶与某组件底部对齐
layout_constraintBotom_toTopof 组件底部与某组件顶部对齐
layout_constraintBottom_toBottomOf 组件底部与某组件底部对齐
layout_constraintBascline_toBasclincO 组件基线与某组件基线对齐
laycut_constraintStart_toEndOf 组件首部与某组件尾部对齐
layout_constraintStart_toStartOf 组件首部与某组件首部对齐
layout_constraintEnd_toStartOf 组件尾部与某组件首部对齐
layout_constraintEnd_toEndOf 组件尾部与某组件尾部对齐

如果限制信息确定了图片某几条边的位置,会覆盖height,width属性

总结:

总结

渲染

布局是用xml中声明,java中实现的。因此布局的渲染需要经过加载、解析和渲染的三个过程,

在activity的onCreate方法中调用setContentView时,它会创建DecorView,最终通过LayoutInflater加载了XML文件

1
LayoutInflater.from(mContext).inflate(resId, contentParent)

在这个加载器中,它会调用一个xml解析器,解析器根据tag生成View,组织ViewGroup并把他们添加到DecorView中…

此时屏幕还没有被绘制,在onResume()中会“借用”ViewRootImpl对象的requestLayout方法来触发配置。

在这之后,由VSync一帧为单位控制界面的刷新。00

交互

查找View

交互最基本的流程是先获取View实例,再添加相应的监听器(比如按钮的onClickListener())

查找的过程中,activity调用DecorView的findViewById方法,每个ViewGroup都会迭代查找自己的孩子,方法是在ViewGroup和View中都实现findViewById,Group会判断自己的id并且调用所有孩子的findViewById。对于View而言,这个方法要么返回自己,要么返回NULL,对于Group而言,他将进行下一轮迭代。这样所有人都只需要知道自己的id,Group再额外记录自己有哪些孩子,就可以从DecorView开始查找到任何被解析过的View了。

监听事件

Android系统中常见的事件监听器有如下几种:

  1. 单击事件(View.OnClickListener):当用户触碰到某个组件或者方向键被按下时产生该事件,该事件的处理方法是onClick().

  2. 焦点事件(View.OnFocusChangeListener):组件得到或者失去焦点时产生该事件,事件处理方法是onFocusChange()。

  3. 按键事件(View.OnKey Listener):用户按下或者释放设备上的某个按键时产生,事件处理方法是 onKey()。

  4. 触碰事件(View.OnTouchListener):设备具有触摸屏功能时,触碰屏幕产生该事件。事件处理方法是onTouch()。

  5. 创建上下文菜单事件(View.OnCreateContextMenu Listener):创建上下文菜单时产生该事件,事件处理方法是 onCreateContextMenu()。

屏幕触摸

所有事件都来自于屏幕触摸,交互事件是对屏幕点击的二次封装!触摸事件MotionEvent包含了触摸的时间、位置等,Activity和View都有onTouchEvent()用于处理触摸事件

接收到一个屏幕事件之后,具体要由哪个UI控件来响应,涉及到时事件的处理流程。触摸一个点很可能同时触摸了多个View,几个Layout还有至少一个Activity。在实践处理中,ViewGroup具有分发、拦截、响应的功能,Activity和View则不具有拦截的功能。
事件处理
出处(https://juejin.cn/post/6844904041487532045)

如何理解onLongClickListener,onClickLisener,onTouchEvent的关系呢?在onTouchEvent在ACTION_DOWN时判断是否达到长按延时,而在ACTION_UP的时候才执行短按延时,此时如果已经出发了了长按执行的监听器,就不再执行短按的监听器,所以说onClickListener是在抬起手指时才触发的,并且不能与onLongClickListener一同触发。

交互总结

从谁发出,经过了谁,到达哪个对象,有何种行为。

动画

帧动画

核心原理就是一帧一帧的播放图片,优点是简单、方便,缺点是功能单一,并且消耗资源。相比于gif,帧动画更可控。

帧动画是通过animation-list声明的,有子标签item,item包含drawable和duration两个属性。

补间动画

补间动画可以控制透明度,旋转,缩放,平移,由系统自动由插值器(Interpolator)

这两种动画都是属于View动画,只能处理View对象,并且无法修改View的属性。(会出现动画无法点击的情况)

属性动画

属性动画可以作用于任何一个对象,并且真实的改变了对象的属性。

总结

真正的动画需要结合各个动画才能做出更好的效果。

自定义UI

自定义View

写四个构造器,对应四种场景。按需复写各方法,并且用各个方法绘制出View,然后再onTouchEvent中处理UI的行为和动画

总结