二、简单控件
1、文本显示
(1)文本内容
💬 Tip:文本内容设置共有三种方式
- 硬编码到XML布局文件
- 硬编码到代码中
- 编码到strings.xml,然后其他文件(如:布局文件、代码中)引用即可
硬编码到XML文件:
-
Layout布局文件:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".TextContent"> <TextView android:id="@+id/m1" android:layout_width="wrap_content" android:layout_height="wrap_content" tools:ignore="MissingConstraints" android:text="XML硬编码" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toTopOf="@+id/m2" /> <TextView android:id="@+id/m2" android:layout_width="wrap_content" android:layout_height="wrap_content" tools:ignore="MissingConstraints" android:text="@string/tc_m2" app:layout_constraintTop_toBottomOf="@+id/m1" app:layout_constraintBottom_toTopOf="@+id/m3" /> <TextView android:id="@+id/m3" android:layout_width="wrap_content" android:layout_height="wrap_content" tools:ignore="MissingConstraints" app:layout_constraintTop_toBottomOf="@+id/m2" app:layout_constraintBottom_toTopOf="@+id/m4" /> <TextView android:id="@+id/m4" android:layout_width="wrap_content" android:layout_height="wrap_content" tools:ignore="MissingConstraints" app:layout_constraintTop_toBottomOf="@+id/m3" app:layout_constraintBottom_toBottomOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
-
字符串文件:
<resources> <string name="app_name">My Application</string> <string name="song">My Song</string> <string name="tc_m2">xml引用</string> <string name="tc_m4">代码引用</string> </resources>
-
代码文件:
public class TextContent extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_text_content); TextView textView = findViewById(R.id.m3); textView.setText("代码硬编码"); TextView textView4 = findViewById(R.id.m4); textView4.setText(R.string.tc_m4); } }
总结:常用两种引用方式
- 在XML文件中引用:
@string/***
- 在Java代码中引用:
R.string.***
(2)文本大小
文本大小的三个单位:
- px:也称为图像元素(Pixel),构成图像的基本单位,与设备显示屏相关,单个像素大小不固定,跟随屏幕大小和像素数量的关系变化
-
分辨率(Resolution):指屏幕的垂直和水平方向的像素速率,如果分辨率是
1920*1080
,则垂直方向有1920个像素,水平反向1080个像素- 如果不同尺寸的屏幕,如15.6英寸和17英寸的分辨率都是
1920*1080
,因为单个像素大小不固定,那么17英寸的屏幕的单个像素更大
- 如果不同尺寸的屏幕,如15.6英寸和17英寸的分辨率都是
-
像素密度(dpi):每英寸距离中有多少个像素点
- 像素密度 = c / 屏幕尺寸
-
密度:每平方英尺中有多少像素点
-
- dp/dip:也称独立设备像素,与屏幕尺寸相关,与设备无关,是一种长度的单位,本质还是px
- 特点:相同屏幕尺寸的设备,如果dp相同,则显示效果相同
- sp:与系统设置相关,系统设置中调整文字大小,则其也会相对应变化,是dp的增强版
示例:
-
布局代码:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".TextSize"> <LinearLayout android:layout_width="409dp" android:layout_height="83dp" android:orientation="horizontal" tools:layout_editor_absoluteX="1dp" tools:layout_editor_absoluteY="1dp" tools:ignore="MissingConstraints"> <TextView android:id="@+id/tsPx" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/tsPx" android:textSize="20px" tools:ignore="MissingConstraints" /> <TextView android:id="@+id/tsDp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/tsDp" android:textSize="20dp" tools:ignore="MissingConstraints" /> <TextView android:id="@+id/tsSp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/tsSp" tools:ignore="MissingConstraints" /> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout>
-
Java代码:
public class TextSize extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_text_size); TextView sp = findViewById(R.id.tsSp); //默认sp大小单位 sp.setTextSize(20); } }
-
手机 —> 设置 —> 调整文字大小:
(3)文本颜色
文本颜色包括:背景颜色、文字颜色
-
布局代码:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".TextColor"> <LinearLayout android:layout_width="409dp" android:layout_height="729dp" android:orientation="vertical" tools:layout_editor_absoluteX="1dp" tools:layout_editor_absoluteY="1dp" tools:ignore="MissingConstraints"> <TextView android:id="@+id/tcRed" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/tcRed" /> <TextView android:id="@+id/tcBlue" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/tcBlue" android:textColor="#3ECEF6" android:background="#FBC118"/> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout>
-
Java代码:
public class TextColor extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_text_color); TextView tcRed = findViewById(R.id.tcRed); tcRed.setTextColor(Color.RED); tcRed.setBackgroundColor(Color.GRAY); } }
-
效果图:
2、视图基础
(1)视图宽高
视图宽高:
- 通过属性
android:layout width
和属性android:layout height
表达 - 宽高的取值主要有下列三种:
match_parent/fill_parent
:表示与上级视图保持一致。wrap_content
:表示与内容自适应。- 以
dp
为单位的具体尺寸。
代码设置:
- 首先确保XML中的宽高属性值为
wrap_content
- 接着打开该页面对应的ava代码,依序执行以下三个步骤:
- 调用控件对象的
getLayoutParams
方法,获取该控件的布局参数。 - 布局参数的width属性表示宽度,height属性表示高度,修改这两个属性值。
- 调用控件对象的
setLayoutParams
方法,填入修改后的布局参数使之生效。
- 调用控件对象的
(2)视图间距
视图间距分为内间距和外间距两种:
-
外间距:采用
layout_margin
属性,指定
当前视图和周围平级视图之间的距离
- layout_margin/marginLeft/marginRight/marginTop/marginBottom
-
内间距:采用
layout_padding
属性,指定
当前视图和内部下级视图之间的距离
- layout_padding/paddingLeft/paddingRight/paddingTop/paddingBottom
(3)视图对齐
视图的对齐方式有两种设置:
- 采用layout_gravity属性,它指定了当前视图相对于上级视图的对齐方式。
- 采用gravity属性,它指定了下级视图相对于当前视图的对齐方式。
💬 layout_gravity与gravity的取值包括:left、top、right、bottom,还可以用竖线连接各 取值,例如left|top
表示即靠左又靠上,也就是朝左上角对齐。
3、常用布局
(1)线性布局
线性布局 - LinearLayout:
-
在XML文件中,LinearLayout通过属性
android:orientation
区分两种方向。
- 从左到右排列叫作水平方向,属性值为horizontal,系统默认布局
- 从上到下排列叫作垂直方向,属性值为vertical
-
源码:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="<http://schemas.android.com/apk/res/android>" xmlns:app="<http://schemas.android.com/apk/res-auto>" xmlns:tools="<http://schemas.android.com/tools>" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".LinearLayout"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="200dp" android:background="#5AB7E3" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="水平布局1"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="水平布局2"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="200dp" android:background="#81D662" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="垂直布局1"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="垂直布局2"/> </LinearLayout> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout>
(2)相对布局
相对布局 - RelativeLayout:
- 在XML文件中,RelativeLayout通过属性
android:layout_xxx
设置,默认是相对于父容器,也可以指定相对的同级布局,只需设置对应ID即可。
-
源码:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="<http://schemas.android.com/apk/res/android>" xmlns:app="<http://schemas.android.com/apk/res-auto>" xmlns:tools="<http://schemas.android.com/tools>" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".RelativeLayout"> <RelativeLayout android:layout_width="match_parent" android:layout_height="400dp" tools:ignore="MissingConstraints" android:background="#F3D0D0"> <TextView android:id="@+id/tv_center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:background="#ffffff" android:text="我在中间" android:textSize="11sp" android:textColor="#000000" /> <TextView android:id="@+id/tv_center_horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:background="#eeeeee" android:text="我在水平中间" android:textSize="11sp" android:textColor="#000000" /> <TextView android:id="@+id/tv_center_vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:background="#eeeeee" android:text="我在垂直中间" android:textSize="11sp" android:textColor="#000000" /> <TextView android:id="@+id/tv_parent_left" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:background="#eeeeee" android:text="我跟上级左边对齐" android:textSize="11sp" android:textColor="#000000" /> <TextView android:id="@+id/tv_parent_right" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:background="#eeeeee" android:text="我跟上级右边对齐" android:textSize="11sp" android:textColor="#000000" /> <TextView android:id="@+id/tv_parent_top" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:background="#eeeeee" android:text="我跟上级顶部对齐" android:textSize="11sp" android:textColor="#000000" /> <TextView android:id="@+id/tv_parent_bottom" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:background="#eeeeee" android:text="我跟上级底部对齐" android:textSize="11sp" android:textColor="#000000" /> <TextView android:id="@+id/tv_left_center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toLeftOf="@+id/tv_center" android:layout_alignTop="@+id/tv_center" android:background="#eeeeee" android:text="我在中间左边" android:textSize="11sp" android:textColor="#000000" /> <TextView android:id="@+id/tv_right_center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@+id/tv_center" android:layout_alignBottom="@+id/tv_center" android:background="#eeeeee" android:text="我在中间右边" android:textSize="11sp" android:textColor="#000000" /> <TextView android:id="@+id/tv_above_center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@+id/tv_center" android:layout_alignLeft="@+id/tv_center" android:background="#eeeeee" android:text="我在中间上面" android:textSize="11sp" android:textColor="#000000" /> <TextView android:id="@+id/tv_below_center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/tv_center" android:layout_alignRight="@+id/tv_center" android:background="#eeeeee" android:text="我在中间下面" android:textSize="11sp" android:textColor="#000000" /> </RelativeLayout> </androidx.constraintlayout.widget.ConstraintLayout>
常见设置:
相对位置属性值 | 说明 |
---|---|
layout_toLeftOf | 当前视图在指定视图的左边 |
layout_toRightOf | 当前视图在指定视图的右边 |
layout_above | 当前视图在指定视图的上方 |
layout_below | 当前视图在指定视图的下方 |
layout_alignLeft | 当前视图与指定视图的左侧对齐 |
layout_alignRight | 当前视图与指定视图的右侧对齐 |
layout_alignTop | 当前视图与指定视图的顶部对齐 |
layout_alignBottom | 当前视图与指定视图的底部对齐 |
layout_centerInParent | 当前视图在上级视图中间 |
layout_centerHorizontal | 当前视图在上级视图的水平方向居中 |
layout_centerVertical | 当前视图在上级视图的垂直方向居中 |
layout_alignParentLeft | 当前视图与上级视图的左侧对齐 |
layout_alignParentRight | 当前视图与上级视图的右侧对齐 |
layout_alignParentTop | 当前视图与上级视图的顶部对齐 |
layout_alignParentBottom | 当前视图与上级视图的底部对齐 |
(3)网格布局
网格布局 - GridLayout:
- 是支持多行多列的布局方式
- 网格布局默认从左往右、从上到下排列,它先从第一行从左往右放置下级视图,塞满之后另起一行放置
- 其余的下级视图,如此循环往复直至所有下级视图都放置完毕。为了判断能够容纳几行几列,网格布局
- 采用
android:columnCount
与android:rowCount
两个属性,指定了网格的列数和行数
-
源码:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="<http://schemas.android.com/apk/res/android>" xmlns:app="<http://schemas.android.com/apk/res-auto>" xmlns:tools="<http://schemas.android.com/tools>" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".GridLayout"> <GridLayout android:layout_width="360dp" android:layout_height="120dp" android:background="#F4C2C2" tools:ignore="MissingConstraints" android:rowCount="2" android:columnCount="2"> <TextView android:layout_width="180dp" android:layout_height="60dp" android:gravity="center" android:background="#E84F4F" android:text="红色" android:textColor="#000000" android:textSize="17sp" /> <TextView android:layout_width="180dp" android:layout_height="60dp" android:gravity="center" android:background="#ffaa00" android:text="橙色" android:textColor="#000000" android:textSize="17sp" /> <TextView android:layout_width="180dp" android:layout_height="60dp" android:gravity="center" android:background="#00ff00" android:text="绿色" android:textColor="#000000" android:textSize="17sp" /> <TextView android:layout_width="180dp" android:layout_height="60dp" android:gravity="center" android:background="#660066" android:text="深紫色" android:textColor="#000000" android:textSize="17sp" /> </GridLayout> </androidx.constraintlayout.widget.ConstraintLayout>
(4)滚动视图
滚动视图 - ScrollView:
- 由来:因为手机屏幕的显示空间有限,常常需要上下滑动或左右滑动才能拉出其余页面内容,可惜一般的布局节点都不支持自行滚动,这时就要借助滚动视图了。
- 滚动视图也分为垂直方向和水平方向两类
- 垂直滚动视图名为
ScrollView
- 水平滚动视图名为
HorizontalScrollView
- 垂直滚动视图名为
这两个滚动视图的使用并不复杂,主要注意以下3点:
- 垂直方向滚动时设置:
layout_width=match_parent,layout_height=wrap_content
。 - 水平方向滚动时设置:
layout_width=wrap_content,layout_height=match_parent
。 - 滚动视图节点下面必须且只能挂着一个子布局节点,否则会在运行时报错
Caused by: java.lang.IllegalStateException:ScrollView can host only one direct child
。
源码:
-
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="<http://schemas.android.com/apk/res/android>" xmlns:app="<http://schemas.android.com/apk/res-auto>" xmlns:tools="<http://schemas.android.com/tools>" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".ScrollViewLayout"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!-- HorizontalScrollView是水平方向的滚动视图,当前高度为200dp --> <HorizontalScrollView android:layout_width="wrap_content" android:layout_height="200dp" tools:ignore="MissingConstraints"> <!-- 水平方向的线性布局,两个子视图的颜色分别为青色和黄色 --> <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="horizontal"> <TextView android:layout_width="300dp" android:layout_height="match_parent" android:background="#aaffff" android:text="往右滑"/> <TextView android:layout_width="300dp" android:layout_height="match_parent" android:background="#ffff00" android:text="往右滑"/> </LinearLayout> </HorizontalScrollView> <!-- ScrollView是垂直方向的滚动视图,当前高度为自适应 --> <ScrollView android:layout_width="match_parent" android:layout_height="wrap_content" tools:ignore="MissingConstraints"> <!-- 垂直方向的线性布局,两个子视图的颜色分别为绿色和橙色 --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="400dp" android:background="#00ff00" android:text="往下滑" /> <TextView android:layout_width="match_parent" android:layout_height="400dp" android:background="#ffffaa" android:text="往下滑" /> </LinearLayout> </ScrollView> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout>
4、按钮触控
💬 按钮Button也是一种基础控件,因为Button是由TextView派生而来,所以文本视图拥有的属性和方法,包括文本内容、文本大小、文本颜色等,按钮控件均能使用。不同的是,Button拥有默认的按钮背景,而TextView默认无背景;Button的内部文本默认居中对齐,而TextView的内部文本默认靠左对齐。
(1)按钮控件
按钮Button特别属性:
- textAllCaps:用于设置是否转换为大写 -
true(default) / false
- onClick:用于设置点击动作触发的事件
- enabled:用于设置启用按钮和禁用按钮,
true(default) / false
(2)事件处理
点击事件:
- 通过
findById
获取组件对象 - 给对象添加点击事件
setOnClickListener
,重写实现方法
-
Java代码:
public class MyButton extends AppCompatActivity { private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_button); textView = findViewById(R.id.tv_time); Button myBtn = findViewById(R.id.btn_mybtn); Button btn_enable = findViewById(R.id.btn_enable); Button btn_disable = findViewById(R.id.btn_disable); btn_enable.setOnClickListener(v -> myBtn.setEnabled(true)); btn_disable.setOnClickListener(v -> myBtn.setEnabled(false)); myBtn.setOnClickListener(v -> doGetTime()); } public void doGetTime() { String time = LocalDateTime.now().toString(); textView.setText(time); } }
-
XML:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="<http://schemas.android.com/apk/res/android>" xmlns:tools="<http://schemas.android.com/tools>" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MyButton"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" tools:ignore="MissingConstraints"> <Button android:id="@+id/btn_enable" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="启用按钮" android:textColor="#000000" android:textSize="17sp" /> <Button android:id="@+id/btn_disable" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="禁用按钮" android:textColor="#000000" android:textSize="17sp" /> </LinearLayout> <Button android:id="@+id/btn_mybtn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="获取当前时间" android:textColor="#888888" android:textSize="17sp" tools:ignore="MissingConstraints" /> <TextView android:id="@+id/tv_time" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="5dp" android:text="请点击按钮获取当前时间" android:textColor="#000000" android:textSize="17sp" tools:ignore="MissingConstraints" /> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout>
一次性给组件所有按钮添加事件:
- 实现对应功能行为的接口:
View.OnClickListener
/View.OnLongClickListener
,重写onClick
方法 - 给子组件添加事件:
setxxxxxClickListener(),传入this
5、图像显示
(1)图像视图
图像视图 - ImageView:
- 先把图片放到
res/drawable
目录 - XML设置 - 引用该图片的资源名称:比如现在有张图片名为
snow.jpg
,那么XML文件通过属性android:src
设置图片资源,属性值格式形如"@drawable/不含扩展名的图片名称"
。 - 代码设置- 引用该图片的资源名称:用ImageView控件的
setImageResource
方法,方法参 数格式形如"R.drawable.不含扩展名的图片名称"
。
可以通过XML文件中通过属性android:scaleType定义缩放类型:
XML设置 | Java代码 - ScaleType类 | 说明 |
---|---|---|
fitCenter | FIT_CENTER | 保持宽高比例,缩放图片使其位于视图中间,超出部分被裁剪 |
centerCrop | CENTER_CROP | 保持宽高比例,缩小图片使之位于视图中间(只缩小不放大) |
centerInside | CENTER_INSIDE | 保持宽高比例,缩小图片使之位于视图中间(不放大) |
center | CENTER | 保持图片原尺寸,并使其位于视图中间 |
fitXY | FIT_XY | 缩放图片使其正好填满视图,可能导致变形 |
fitStart | FIT_START | 保持宽高比例,缩放图片使其位于视图上方或左侧 |
fitEnd | FIT_END | 保持宽高比例,缩放图片使其位于视图下方或右侧 |
(2)图像按钮
图像按钮 - ImageButton:
- 是显示图片的图像按钮。
- 虽然ImageButton号称图像按钮,但它并非继承Button,而是继承了ImageView,所以凡是ImageView拥有的属性和方法,ImageButton也有,区别在于ImageButton有个按钮背景。
(3)文本和图像按钮
- 可以同时展示文本与图像
- 使用按钮控件Button就能实现。原来Button,通过下列属性即可指定文字旁边的图标
- drawableTop:指定文字上方的图片。
- drawableBottom:指定文字下方的图片。
- drawableLeft:指定文字左边的图片。
- drawableRight:指定文字右边的图片。
- drawablePadding:指定图片与文字的间距。
- 通过
"@drawable/不含扩展名的图片名称"
设置