开始
Android 中的组件都是由 View 和 ViewGroup 组成,是一个树形结构,View 就代表了一个界面控件,ViewGroup 是存放多个 View 对象的布局容器
布局
LinearLayout 线性布局
表示一个横向或纵向的布局
-
orientation
: 设置布局的排列方式,有 horizontal(水平)、vertical(垂直,默认) 两种方式 -
gravity
: 控制子元素中内容对齐方式,可多种组合 (left|bottom) -
layout_gravity
: 控制组件的显示内容在父容器中的对齐方式线性布局中以排列方向上最大的组件的内容位置决定对齐标准
线性布局水平排列,button2 最大,layout_gravity=bottom,则该组件的内容所在的位置为 bottom,button3 随之与 button2 的内容平行
-
layout_width
: 通常用 wrap_content(匹配内容),match_parent(填满父容器) -
layout_height
-
id
: 为组件设置一个资源 ID -
background
: 设置组件的背景或背景颜色 -
weight
: 用于等比例划分区域,该属性设置后排列方向上的长度/宽度设置为 0dp在多个组件中设置该属性,使得设置的组件按比例设置大小,比例为 weight 值在所有组件的 weight 值之和的占比
需要一个组件的大小依据另一组件的大小而定时,将该组件的大小设为 0,weight 设为 1,该组件会依据另一组件的大小占满剩余的屏幕
-
divider 分割线
divider
: 设置分割线的图片showDividers
: 设置分割线所在位置,可选 none,middle,beginning,enddividerPadding
: 设置分割线的 padding
RelativeLayout 相对布局
表示一个控件相对于其他控件设置位置的布局
-
gravity
: 设置容器内组件内容的对齐方式 -
IgnoreGravity
:设置该属性为 true 的组件不受 gravity 属性的影响 -
根据父容器定位
layout_centerHrizontal
: 水平居中layout_centerVertical
: 垂直居中layout_centerInparent
: 相对于父元素完全居中layout_alignParentLeft
: 左对齐layout_alignParentRight
: 右对齐layout_alignParentTop
: 顶部对齐layout_alignParentBottom
: 底部对齐
-
根据兄弟组件 (处于同一布局的组件) 定位,指定组件 ID 来定位
layout_toLeftOf
:参考组件的内容layout_toRightOf
layout_above
layout_below
layout_alignTop
: 参考组件的上边界layout_alignBottom
: 参考组件的下边界layout_alignLeft
: 同上layout_alignRight
: 同上
FrameLayout 帧布局
所有控件默认摆放在左上角,控件之间可覆盖,通过 layout_gravity
设置在布局中的对齐方式
UI 控件
TextView
表示一个简单文本
常用属性
id
layout_width
layout_height
gravity
: 设置控件中文字的对齐方向text
: 设置文本显示的内容,一般将字符串写到 string.xml 中textColor
: 设置文本的颜色,一般将颜色写到 colors.xml 中textStyle
: 设置文字的风格,可选 normal,bold,italictextSize
: 设置字体大小,单位使用 spbackground
: 设置控件的背景
设置字体阴影
shadowColor
: 设置阴影颜色,需要与 shadowRadius 配合使用shadowRadius
: 设置阴影的模糊程度,通常为 3.0shadowDx
: 设置阴影水平方向的偏移shadowDy
: 设置阴影竖直方向的偏移
带边框的 TextView
需要编写一个 shapeDrawable,将 TextView 的 background 属性设置为该 shapeDrawable 资源
shapeDrawable 资源的节点及属性
<solid android:color = "xxx">
这个是设置背景颜色的<stroke android:width = "xdp" android:color="xxx">
这个是设置边框的粗细,以及边框颜色的<padding androidLbottom = "xdp"...>
这个是设置边距的<corners android:topLeftRadius="10px"...>
这个是设置圆角的<gradient>
这个是设置渐变色的,可选属性有startColor
: 起始颜色endColor
: 结束颜色centerColor
: 中间颜色angle
: 方向角度,等于 0 时,从左到右,然后逆时针方向转,当 angle = 90 度时从下往上type
: 设置渐变的类型
带图片的 TextView
在文字的上下左右添加图片,传入 drawable 资源 ID
drawableLeft
drawableRight
drawableBottom
drawableTop
若需要改变图片大小,在 java 代码中修改
autoLink 链接:当文字是一个链接或一段电话号码,可使文字链接到对应网址或应用
EditView
表示一个文本编辑框
-
设置默认提示文本
-
hint
: 默认提示文本 -
textColorHint
: 提示文本颜色
-
-
获得焦点后全选组件内的文本
selectAllOnFocus
-
限制 EditText 输入类型:inputType
- 文本:text,textUri,textPassword,textVisiblePassword,textMultiLine,textEmailAddress
- 数值:number,phone,date,time, datetime,numberSigned
-
限制输入行数:默认为多行显示,能够自动换行
-
minLines
: 设置最小行数 -
maxLines
: 设置最大行数,超过最大行数时会自动向上滚动 -
singleLine
: 只允许单行输入,且不能滚动
-
-
设置文字间隔,设置英文字母大写类型
-
textScaleX
: 设置水平间隔 -
textScaleY
: 设置数之间各竖直间隔 -
capitalize
: 设置英文字母大写类型sentences
: 第一个字母大写words
: 每个单词首字母大写,用空格分隔characters
: 每个字母都大写
-
-
获取输入文本:
editText.getText().toString()
获取的值不会为 null,但可能为空字符串
StateListDrawable
StateListDrawable 可根据不同的状态设置不同的图片效果,根节点为 <selector>
drawable
: 引用的 Drawable 位图,我们可以把他放到最前面,就表示组件的正常状态~state_focused
: 是否获得焦点state_window_focused
: 是否获得窗口焦点state_enabled
: 控件是否可用state_checkable
: 控件可否被勾选,eg:checkboxstate_checked
: 控件是否被勾选state_selected
: 控件是否被选择,针对有滚轮的情况state_pressed
: 控件是否被按下state_active
: 控件是否处于活动状态,eg:slidingTabstate_single
: 控件包含多个子控件时,确定是否只显示一个子控件state_first
: 控件包含多个子控件时,确定第一个子控件是否处于显示状态state_middle
: 控件包含多个子控件时,确定中间一个子控件是否处于显示状态state_last
: 控件包含多个子控件时,确定最后一个子控件是否处于显示状态
Button
表示一个按钮
继承了 TextView,属性基本同 TextView,text 属性的文字会默认转换为大写,可设置 textAllCaps=false
取消
注册监听器:调用 button.setOnClickListener()
,传入一个 lambda 表达式
ImageView
表示一张图片,src 指定 drawable 中的图片资源,图片一般放在 xxhdpi 分辨率下
在代码中可以动态的更改图片,调用 imageView.setImageResource(R.drawable.pic)
ProgressBar
用于显示一个进度条,表示程序正在加载数据
-
style 属性设置进度条的样式
水平进度条:
style="?android:attr/progressBarStyleHorizontal"
-
max 属性设置进度条最大值
在代码中
progressBar.progress
属性可动态设置进度条进度
通过 visibility 属性设置控件可见或不可见,可选 visible,invisible,gone
visible 和 invisible 表示控件可见或不可见,控件还占据原来的位置,gone 表示控件消失,不占据空间,Android 控件均有这一属性
在代码中调用控件的
setVisibility()
可动态控制控件的可见状态,getVisibility()
返回控件可见状态
AlertDialog
在当前界面弹出一个提示框,能够屏蔽所有控件,置顶于所有界面元素之上
- 对话框类型为 AlertDialog,创建对象类型为
AlertDialog.Builder
- 创建
AlertDialog.Builder
对象 - 调用
setIcon()
设置图标,setTitle()
或setCustomTitle()
设置标题 - 设置对话框的内容:
setMessage()
还有其他方法来指定显示的内容 - 调用 setPositive/Negative/NeutralButton() 设置:确定,取消,中立按钮
- 调用
create()
方法创建这个对象,再调用show()
方法将对话框显示出来
2.5.9 AlertDialog(对话框)详解 | 菜鸟教程 (runoob.com)
自定义控件
引入布局
编写一个自定义的局部布局,如标题栏布局,在主布局中使用 include 标签引入
1 | <include layout="@layout/title"/> |
自定义控件
为布局中的控件注册事件,使其封装为一个控件
-
新建布局类,继承小布局使用的布局 (线性布局等)
-
类中构造器传入
Context
和AttributeSet
两个参数,动态加载布局类1
2
3
4
5
6
7public class TitleLayout extends LinearLayout {
public TitleLayout(Context context, { AttributeSet attrs)
super(context, attrs);
// inflate()的第一个参数为要加载的布局文件id,第二个参数为加载的布局添加一个父布局
LayoutInflater.from(context).inflate(R.layout.title,TitleLayout.this);
}
} -
为布局中的控件注册事件
ListView
允许用户上下滑动浏览列表
将 data 传入 ListView:使用适配器 (常用 ArrayAdapter),构造一个适配器,指定泛型,传入 Activity 实例,ListView 子项的布局 id 和数据源 data,最后将 ListView 控件的适配器设置为构造的适配器
自定义 ListView 子项
自定义 ListView 子项的界面
-
编写子项的实体类存储显示的信息
-
编写子项布局
-
自定义实例类的适配器,继承
ArrayAdapter
,指定泛型适配器的构造器传入 Activity 的实例,ListView 子项布局 id 和数据源
-
重写
getView()
,该方法在子项被滚动到屏幕中时调用-
getView 方法中使用
LayoutInflator
动态加载布局,设置 inflate 第三个参数为 false,表示只让父布局的 layout 属性生效,而不添加父布局,通过调用getItem(position)
获取当前项的 Fruit 实例,findViewById
获取控件,设置当前子项的显示内容 -
convertView
参数用于将加载好的布局进行缓存,在上下滚动时可以重用判断
convertView
是否为空,为空则动态加载,不为空令view=convertView
-
ViewHolder
可用于对获取控件进行优化在 Adapter 类中定义一个 ViewHolder 内部类,类中存储布局中的控件,构造 ViewHolder 类对象,对加载的控件进行缓存,传入构造器中,再调用 view 的
setTag()
将 ViewHolder 存储在 view 中,convertView 不为空时,调用getTag()
获取 ViewHolder 对象
-
点击事件
调用 listView.setOnItemClickListener()
注册监听器,传入 parent,view,position,通过 position 获取子项的实例
RecyclerView
RecyclerView 为新增库,用于表示一个列表,可以替代 ListView,在老版本 Android 运行需要在 build.gradle 添加 RecyclerView 的依赖
- 自定义适配器使用 RecyclerView,继承
RecyclerView.Adapter
,指定泛型为 class.ViewHolder,class 为自定义的适配器类,重写其中的方法,ViewHolder 内部类需要继承RecyclerView.ViewHolder
- 重写的方法
-
onCreateViewHolder()
:用于创建 ViewHolder 实例,加载子项布局(子项的布局高度需要调整为自适应),将布局传入构造器中,返回 ViewHolder 实例 -
onBindViewHolder()
:用于对 RecyclerView 子项赋值 -
getItemCount()
:返回数据源长度
-
- 重写的方法
- 在
onCreate()
中构造一个布局管理器对象 (线性布局 LinearLayoutManager),传入 RecyclerView 的setLayoutManager()
中
onBindViewHolder 中 position 不准的问题
调用 notifyItemXXX 方法时不会调用 onBindViewHolder
重新绑定,因此修改后每个 holder 的 position 不会改变
例:数据项 0,1,2 对应列表项 0,1,2
数据索引:[0]0,[1]1,[2]2
列表索引:[0]0,[1]1,[2]2
修改后
数据索引:[0]1,[1]2
列表索引:[1]1,[2]2
点击 1 时,position 依然是 1,数据中下标 1 的数据是 2,数据与列表不对应
调用 holder.getAbsoluteAdapterPosition
获取绝对位置
横向滚动和瀑布流布局
- 横向滚动
- 修改子项布局的排列方式为 vertical,固定宽度,设置控件的对齐方式
- 设置
LinearLayoutManager
对象的orientation
为HORIZONTAL
- 瀑布流布局
- RecyclerView 内置
GridLayoutManager
网格布局和StaggeredGridLayoutManager
瀑布流布局 - 构造
StaggeredGridLayoutManager
对象,传入显示的列数和排列方向 - 子项布局的宽度根据列数自动适配,设为
match_parent
即可
- RecyclerView 内置
点击事件
需要为每个子项 View 注册点击事件
在适配器的 onCreateViewHolder
() 中使用 ViewHolder 可以为最外层布局 (itemView) 或者布局内控件注册事件
调用 getAdapterPosition()
获取 position,进而获取对象
9-patch 图片
9-patch 图片可以指定那些区域可以被拉伸,哪些区域填充内容
在 Android Studio 中可以从.png 图片创建.9.png 图片,创建后将原图片删除或重命名,在边框填充小黑点指定区域
左边框和上边框的黑点区域表示拉伸的区域,右边框和下边框的黑点区域表示内容允许放置的位置