第3章 简单控件
第 3 章 简单控件
📖3.1 文本显示
✅设置文本的内容
🚩1. 设置的方式
设置文本内容有两种方式
- 在
xml
文件中通过属性android:text
设置文本 - 在
Java
代码中调用文本视图对象的setText
方法设置文本
在xml
文件下的示例:
<TextView
android:id="@+id/tv_hello"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello world!"/>
在activity
下的示例:在activity
下相当于修改了TextView
里面的文本内容。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.tv_hello);
textView.setText("你好,世界~");
}
🚩2. 引用字符串资源
像一些常用的文本内容,我们可以定义在string.xml中,从而达到复用的效果,避免了重复创建。
首先在string.xml
文件中定义字符串
<resources>
<string name="app_name">My Application</string>
<string name="hello">你好,世界~</string>
</resources>
①在Java代码中,通过R.string.***
进行引用
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.tv_hello);//通过id找到对应的TextView
textView.setText(R.string.hello);//填充TextView文本
}
②在xml文件中,通过@string/***
在xml文件中进行引用
<TextView
android:id="@+id/tv_hello"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello"/>
✅设置文本的大小
①在Java代码中,通过setTextSize
方法指定文本大小
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.tv_hello);//通过id找到对应的TextView
textView.setText(R.string.hello);//填充TextView文本
textView.setTextSize(30);
}
在Java代码中默认是sp单位,setTextSize源码如下:
public void setTextSize(float size) {
setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
}
②在xml文件,通过属性Android:textSize
指定文本大小
<TextView
android:id="@+id/tv_hello"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello"
android:textSize="30dp"
/>
单位参考:
单位 | 名称 | 解释 |
---|---|---|
px | 像素(Pixel) | 图像构成的基本单元,一个像素点为1px,是手机屏幕的最小显示单位,与设备的显示屏有关 |
dp | 设备独立像素(Dip) | 一种相对单位,用于在不同的屏幕密度下提供一致的显示效果,与设备无关,只与屏幕的尺寸有关 |
sp | 缩放独立像素 | 它专门用来设置字体大小,在系统设置中可以调整字体大小 |
扩展:
dp
是Density-independent Pixel的缩写,也称为设备独立像素。它是一种相对单位,用于在不同的屏幕密度下提供一致的显示效果。dp的值会根据屏幕密度进行缩放,因此在不同的设备上,相同的dp值会显示为不同的物理像素大小。与dp相似的单位是sp,它是可缩放独立像素,用于指定字体大小。与dp不同的是,sp(缩放独立像素,Scale-independent Pixels)还考虑了用户设置的字体大小偏好。因此,建议使用sp来指定字体大小,以便根据屏幕密度和用户设置进行调整.
density
(像素密度),通常以dpi(每英寸点数)为单位表示。dpi是指在一个英寸的空间内,屏幕上显示的像素点数。例如,如果一个屏幕的分辨率为320x480像素,并且其物理尺寸为2英寸x3英寸,则其dpi为160(320/2=480/3=160)12
计算规则 我们以一个 4.95 英寸 1920 * 1080的 nexus5 手机设备为例:
①Dpi的计算:
- 计算直角边像素数量:
1920^2+1080^2=2202^2
(勾股定理) - 计算 DPl:
2202 / 4.95 = 445.
- 得到这个设备的 DPI为 445 (每英寸的距离中有 445 个像素)
②Density 上面得到每英寸中有 440 像素,那么 density 为每平方英寸中的像素数量,应该为: 445^2=198025
. ③Dip 所有显示到屏幕上的图像都是以 px 为单位,Dip 是我们开发中使用的长度单位,最后他也需要转换成 px,计算这个设备上 1dip 等于多少px:
px = dip x dpi /160
根据换算关系 320 x 480分辨率,3.6寸的手机: dpi为160,1dp=1px
✅设置文本颜色
①在Java代码中,通过setTextColor
方法指定文本大小
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.tv_hello);//通过id找到对应的TextView
textView.setTextColor(Color.RED);//系统自带颜色
textView.setTextColor(Color.parseColor("#8DD63C"));//指定HEX十六进制颜色
textView.setTextColor(Color.rgb(255, 0, 0));//指定RGB三原色格式颜色
}
Java中Color类封装了一些常用的颜色,当然也可以指定我们自定义的颜色
②在xml文件,通过属性Android:textColor
指定文本大小
<TextView
android:id="@+id/tv_hello"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello"
android:textColor="#8DD63C"
/>
③Java和xml还可以通过setBackground()
方法和android:background
来设置背景颜色
扩展:
这里推荐一个在线颜色转换网站,同时还可以找到指定颜色,颜色种类也特别多,市面上有很多类似的网站,这里只推荐一个
千通彩色色彩管理:https://www.qtccolor.com/secaiku/
📖3.2 视图基础
安卓中的所有控件都可以叫做视图,比如TextView、Button等等。
✅设置视图的宽高
①在xml文件中视图宽通过
android:layout_width
属性表达,视图高通过android:layout_height
属性表达
而宽高的取值主要有下列三种:
wrap_content
:表示与内容自适应match_parent
:表示与上级视图保持一致- 以
dp
为单位的具体尺寸
②在Java代码中,设置视图的宽高首先确保xml中的宽高属性值为
wrap_content
,如下步骤:
调用控件对象的
getLayoutParams
方法布局参数的width属性表示宽度,height属性表示高度,修改这两个属性值
调用控件对象的
setLayoutParams
方法,填入修改后的布局参数使之生效
代码如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.tv_hello);//通过id找到对应的TextView
// 获取textView的布局参数(含宽度和高度)
ViewGroup.LayoutParams params = textView.getLayoutParams();
// 修改布局参数中的宽度数值,注意默认px单位,需要把dp数值转成px数值
params.width = Utils.dip2px(this,300);
//设置textView的布局参数
textView.setLayoutParams(params);
}
dp数值转成px数值-Utils
public class Utils {
// 根手机的分辨率从 dp 的单位 转成为 px(像素)
public static int dip2px(Context context, float dpValue){
//获取当前手机的像素密度 (1个dp对应几px)
float scale = context.getResources().getDisplayMetrics().density;
// 四舍五入取整
return (int) (dpValue * scale + 0.5f);
}
}
✅设置视图的间距
设置视图的间距有两种方式:layout_margin
和padding
- 采用layout_margin属性,指定了当前视图与周围平级视图之间的距离,即外边距。还包括
layout_margin
、layout_marginLeft
、layout_marginTop
、layout_marginRight
、layou_marginBottom
- 采用padding属性,指定了当前视图与内部下级视图之间的距离,即内边距。还包括
padding
、paddingLett
、paddingTop
、paddingRight
、paddingBottom
✅设置视图的对齐方式
设置视图的对齐方式有两种方式:
- 采用
layout_gravity
属性,它指定了当前视图相对于上级视图的对齐方式 - 采用
gravity
属性,它指定了下级视图相对于当前视图的对齐方式
layout _gravity
与gravity
的取值包括: left
、top
、right
、bottom
,还可以用竖线连接各取值,例如“left|top
”表示即靠左又靠上,也就是朝左上角对齐。
📖3.3 常用布局
✅LinearLayout-线性布局
线性布局内部的各视图有两种排列方式
orientation
属性值为horizontal
时,内部视图在水平方向从左往右排列。orientation
属性值为vertical
时,内部视图在垂直方向从上往下排列。
如果不指定orientation
属性,则LinearLayout
默认水平方向排列。
📚线性布局的权重
线性布局的权重概念,指的是线性布局的下级视图各自拥有多大比例的宽高。
权重属性名叫
layout weight
,但该属性不在LinearLayout
节点设置,而在线性布局的直接下级视图设置,表示该下级视图占据的宽高比例。layout_width
填0dp
时,layout_weight
表示水平方向的宽度比例。layout_height
填0dp
时,layout_weight
表示垂直方向的高度比例。
✅RelativeLayout-相对布局
相对布局的下级视图位置由其他视图决定。用于确定下级视图位置的参照物分两种:
- 与该视图自身平级的视图
- 该视图的上级视图(也就是它归属的RelativeLayout)
如果不设定下级视图的参照物,那么下级视图默认显示在RelativeLayout内部的左上角
相对位置的取值:
相对位置的属性取值 | 说明 |
---|---|
layout_toLeftOf | 当前视图在指定视图的左边 |
layout_toRightOf | 当前视图在指定视图的右边 |
layout_above | 当前视图在指定视图的上方 |
layout_below | 当前视图在指定视图的下方 |
layout_alignLeft | 当前视图在指定视图的左侧对齐 |
layout_alignRight | 当前视图在指定视图的右侧对齐 |
layout_alignTop | 当前视图在指定视图的顶部对齐 |
layout_alignBotton | 当前视图在指定视图的底部对齐 |
layout_centerInParent | 当前视图在上级视图中间 |
layout_centerHorizontal | 当前视图在上级视图的水平方向居中 |
layout_centerVertical | 当前视图在上级视图的垂直方向居中 |
layout_alignParentLeft | 当前视图与上级视图的左对齐 |
layout_alignParentRight | 当前视图与上级视图的右对齐 |
layout_alignParentTop | 当前视图与上级视图的顶部对齐 |
layout_alignParentBotton | 当前视图与上级视图的底部对齐 |
练习下面布局:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="#D4D6D5">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="#C2F7DC"
android:text="我跟上级顶部对齐"
android:textSize="15dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我跟上级右侧对齐"
android:textSize="15dp"
android:background="#C2F7DC"
android:layout_alignParentRight="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我跟上级底部对齐"
android:textSize="15dp"
android:background="#C2F7DC"
android:layout_alignParentBottom="true"/>
<TextView
android:id="@+id/center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#F3964A"
android:text="中间位置"
android:textSize="15dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:background="#C2F7DC"
android:text="我在水平中间"
android:textSize="15dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="垂直中间"
android:textSize="15dp"
android:background="#C2F7DC"
android:layout_centerVertical="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="中间左"
android:textSize="15dp"
android:background="#C2F7DC"
android:layout_toLeftOf="@+id/center"
android:layout_alignTop="@+id/center"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="中间上面"
android:textSize="15dp"
android:background="#C2F7DC"
android:layout_above="@+id/center"
android:layout_alignLeft="@+id/center"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="中间右边"
android:textSize="15dp"
android:background="#C2F7DC"
android:layout_toRightOf="@+id/center"
android:layout_alignTop="@+id/center"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="中间下面"
android:textSize="15dp"
android:background="#C2F7DC"
android:layout_below="@+id/center"
android:layout_alignLeft="@+id/center"/>
</RelativeLayout>
✅GridLayout- 网格布局
- 网格布局支持多行多列的表格排列
- 网格布局默认从左往右、从上到下排列,它新增了两个属性:
columnCount
属性,它指定了网格的列数,即每行能放多少个视图rowCount
属性,它指定了网格的行数,即每列能放多少个视图
示例代码:
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:rowCount="2"
android:columnCount="2"
>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:background="#fd79a8"
android:gravity="center"
android:text="浅红色"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:background="#ffa502"
android:gravity="center"
android:text="橙色"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:background="#2ed573"
android:gravity="center"
android:text="绿色"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:background="#be2edd"
android:gravity="center"
android:text="紫色"
/>
</GridLayout>
✅ScrollView-滚动试图
滚动视图有两种:
ScrollView
,它默认是垂直方向的滚动视图; 垂直方向滚动时,layout_width属性值设置为match_parent,layout_height属性值设置为wrap_content。HorizontalScrollView
,它是水平方向的滚动视图; 水平方向滚动时,layout width属性值设置为wrap content,layout height属性值设置为match parent。
📖3.4 按钮触控
✅按钮控件Button
按钮控件Button
由TextView
派生而来,它们之间的区别有:
Button
拥有默认的按钮背景,而TextView
默认无背景Button
的内部文本默认居中对齐,而TextView
的内部文本默认靠左对齐Button
会默认将英文字母转为大写,而TextView
保持原始的英文大小写
📚新增属性
TextView
相比,Button
增加了两个新属性:
textAlICaps
属性,指定了是否将英文字母转为大写,为true
是表示自动转为大写,为false
表示不做大写转换。onClick
属性,它用来接管用户的点击动作,指定了点击按钮时要触发哪个方法。
✅点击事件和长按事件
- 监听器,意思是专门监听控件的动作行为。只有控件发生了指定的动作,监听器才会触发 开关去执行对应的代码逻辑。
- 按钮控件有两种常用的监听器:
- 点击监听器,通过
setOnClickListener
方法设置。按钮被按住少于500毫秒时,会触发点击事件。 - 长按监听器,通过
setOnLongClickListener
方法设置。按钮被按住超过500毫秒时,会触发长按 事件。
- 点击监听器,通过
下面只演示一下点击事件,长按点击事件只需要把
setOnClickListener
换成setOnLongClickListener
即可
点击获取本地时间案例:
①在xml设置按钮组件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
>
<Button
android:id="@+id/button_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="获取时间"/>
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
②java代码中实现逻辑
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv_time = findViewById(R.id.tv_time);//通过id找到对应的TextView
Button button_time = findViewById(R.id.button_time);//通过id找到对应的Button
//Button点击事件
button_time.setOnClickListener(v -> tv_time.setText(Util.getNowTime()));
}
获取时间工具类:
public class DateUtil {
public static String getNowTime(){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(new Date());
}
}
③实现效果:点击按钮后打印时间
注意:这里使用了java8新特性
✅禁用和恢复按钮
在实际业务中,按钮通常拥有两种状态,即不可用状态与可用状态,它们在外观和功能上的区别如下:
- 不可用按钮:按钮不允许点击,即使点击也没反应,同时按钮文字为灰色
- 可用按钮:按钮允许点击,点击按钮会触发点击事件,同时按钮文字为正常的黑色
是否允许点击由enabled
属性控制,属性值为true
时表示允许点击,为false
时表示不允许点击。
案例:实现如下启用和禁用按钮
①定义xml组件
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
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"
>
<Button
android:id="@+id/bt_enable"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="启用测试按钮"/>
<Button
android:id="@+id/bt_disable"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="禁用测试按钮"/>
</LinearLayout>
<Button
android:id="@+id/bt_test"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="测试按钮"
android:enabled="false"
/>
<TextView
android:id="@+id/tv_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="测试内容"
android:gravity="center"/>
</LinearLayout>
②编写Java逻辑代码
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
//设置全局属性
Button bt_test;
TextView tv_result;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bt_enable = findViewById(R.id.bt_enable);//获取启用按钮组件
Button bt_disable = findViewById(R.id.bt_disable);//获取禁用按钮组件
bt_test = findViewById(R.id.bt_test);//获取测试按钮组件
tv_result = findViewById(R.id.tv_result);//获取结果文本组件
//设置监听事件
bt_enable.setOnClickListener(this);
bt_disable.setOnClickListener(this);
bt_test.setOnClickListener(this);
tv_result.setOnClickListener(this);
}
//设置全局监听
@Override
public void onClick(View v) {
Integer id = v.getId();
if (id == R.id.bt_enable){
bt_test.setEnabled(true);//设置启用
bt_test.setTextColor(Color.BLACK);
} else if (id == R.id.bt_disable) {
bt_test.setEnabled(false);//设置禁用
bt_test.setTextColor(Color.GRAY);
} else if (id == R.id.bt_test) {
tv_result.setText(DateUtil.getNowTime());//点击测试按钮,打印时间
}
}
}
📖3.5 图像显示
✅ImageView- 图像视图
图像视图展示的图片通常位于res/drawable***
目录,设置图像视图的显示图片有两种方式
- 在
XML
文件中,通过属性android:src
设置图片资源,属性值格式形如“@drawable/不含扩展名的图片名称
" - 在
Java
代码中,调用setlmageResource
方法设置图片资源,方法参数格式形如“R.drawable.不含扩展名的图片名称
”
①在xml文件中:
<ImageView
android:id="@+id/iv_img"
android:layout_width="match_parent"
android:layout_height="220dp"
android:src="@drawable/car"/>
②在Java代码中:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView iv_img = findViewById(R.id.iv_img);//获取组件
iv_img.setImageResource(R.drawable.car);//设置图片路径
}
图像视图缩放类型
✅ImageButton-图像按钮
lmageButton
是显示图片的图像按钮,但它继承自lmageView
,而非继承Button
。
lmageButton
和Button
之间的区别有:
- Button既可显示文本也可显示图片,lmageButton只能显示图片不能显示文本
- lmageButton上的图像可按比例缩放,而Button通过背景设置的图像会拉伸变形。
- Button只能靠背景显示一张图片,而lmageButton可分别在
foreground
前景和background
背景显示图片,从而实现两张图片叠加的效果。
案例:
<ImageButton
android:layout_width="match_parent"
android:layout_height="80dp"
android:src="@drawable/square_root_variable"
android:scaleType="fitCenter"
/>
效果:
✅实战案例:计算器
计算器的界面分为两大部分:
- 第一部分是上方的计算表达式,既包括用户的按键输入,也包括计算结果数字
- 第二部分是下方的各个按键,例如: 从0到9的数字按钮、加减乘除与等号、正负号按钮、小数点按钮、求倒数按钮、平方按钮、开方按钮,以及退格、清空chapter03取消等控制按钮。简单计算器
- 线性布局
LinearLayout
: 计算器的整体布局是从上到下排列着的。网格布局GridLayout
: 计算器下半部分的几排按钮,正好成五行四列表格分布,适合采用GridLayout。 滚动视图ScrollView
: 计算器界面如果超出屏幕大小,就要支持滚动。- 文本视图
TextView
: 计算结果文本需要使用TextView,且文字靠下靠右显示。- 按钮
Button
: 用于0-9的数字按键,以及加减乘除等运算按键。- 图像按钮
ImageButton
: 开根号的运算符“√”虽然能够打出来,但是右上角少了一横所以该按钮要用一张标准的开根号图片显示。