写在前面
本篇主要介绍一些Android中常用的控件,例如Button、TextView等,这些控件都直接或间接的继承了android.view.View类。每个Android的界面中都包含了很多的控件,这些控件通过布局文件来约束排列位置,各自提供了不同的同用户交流的窗口。注:本文主要参考资料有:《移动操作系统原理与实践》关东升,Android开发者官网:https://developer.android.google.cn/guide/topics/ui/controls/button?hl=zh_cn
1 按钮(Button)
1.1 概述
按钮主要是接收用户单击事件的一个控件,Android中按钮有Button、ImageButton、ToggleButton三种主要形式。
Button是能够显示文本的普通按钮,默认是直角样式。通过android:text属性来设置按钮上显示的文本。Button类继承TextView类。
ImageButton是一种带有图片的按钮,默认样式也是直角样式,显示的不是文本而是图片。按钮上图片的选择是通过android:src属性来完成的,ImageButton类继承ImageView类。
ToggleButton是可以显示两种状态的按钮,其文本默认显示OFF或者ON,也可以自定义显示的文本,通过android:textOn和android:textOff属性来设置。
1.2 按钮实例
下面举几个简单的例子来说明这几种按钮的使用。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
android:orientation="vertical"
tools:context=".MainActivity" >
<TextView
android:id="@+id/title_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="相对布局"
android:textSize="24sp" />
<Button
android:id="@+id/button_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/title_tv"
android:text="Button"
tools:layout_alignParentLeft="true"
android:onClick="ButtonClick"/>
<ImageButton
android:id="@+id/imageButton_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/button_btn"
android:src="@android:drawable/ic_delete"
tools:layout_alignParentLeft="true" />
<ToggleButton
android:id="@+id/toggleButton_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/imageButton_btn"
android:text="ToggleButton"
tools:layout_alignParentLeft="true" />
</RelativeLayout>
这里我们新建一个非常简单的相对布局,布局文件也给出来了。我们要做的事情就是监测用户对这些按钮的点击动作,并在TextView中显示出来。
下面是MainActivity.java文件中的代码:
package com.beihang.test;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.ToggleButton;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
public static final String TAG = "MainActivity";
private TextView tv;
private Button btn;
private ImageButton imgBtn;
private ToggleButton ToggleBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initUI();
}
private void initUI() {
tv = findViewById(R.id.title_tv);
btn = findViewById(R.id.button_btn);
imgBtn = findViewById(R.id.imageButton_btn);
ToggleBtn = findViewById(R.id.toggleButton_btn);
ToggleBtn.setOnClickListener(this);
imgBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tv.setText("ImageButton 被点击!");
}
});
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.toggleButton_btn) {
tv.setText("ToggleButton 被点击!" + String.valueOf(ToggleBtn.isChecked()));
}
}
//当Button被点击时调用
public void ButtonClick(View v) {
tv.setText("Button 被点击!");
}
}
我们需要为按钮设置监听器(Listener),也就是当按钮被点击时发出响应。为按钮设计Listener通常有三种方式,一般来说选择自己喜欢或者顺手的一种就可以,这里为了展示这三种方式,我比较麻烦的三种按钮分别用不同的方式来写。
方式一:在布局文件中声明回调函数
可以看到,上面activity_main.xml文件中Button的有一个android:onClick="ButtonClick"属性,这个属性就是声明该控件被点击后的回调函数为ButtonClick(),别忘了在MainActivity.java文件中定义这个函数!
方式二:使用setOnClickListener方法传入View.OnClickListener的匿名内部类
简单的来说就是不在布局文件中声明回调函数,而是在MainActivity.java文件中自己通过控件的setOnClickListener方法来绑定回调函数,这个方法需要传入一个View.OnClickListener对象,这里我们可以直接使用匿名内部类,也就是直接new一个!
方式三:使用setOnClickListener方法,直接将活动本身传入,但活动本身要实现View.OnClickListener接口
这种方法实际上就等同与第二种方法,只不过传入setOnClickListener方法的不再是一个新声明的内部类,而是让控件所在的活动类实现这个接口,然后传入活动。这样可以使代码简洁一些,且能在控件较多的时候避免多次使用匿名内部类。
活动本身实现View.OnClickListener接口:
一定要覆写onClick方法:
最后实现的结果就同我们预料的一样,点击不同的按钮,上面的标签显示不同的信息。
2 标签(TextView)
标签控件使用来显示一些文字信息的,它是只读的,不能够被修改。它直接继承自android.view.View类,可以自行设置字号、颜色等属性。在程序中可以调用setText(CharSequence)方法来设置TextView的内容,通过getText()方法来获取TextView的内容,在按钮的例子中,也使用到了TextView这种控件,这个控件比较简单,更为详细的内容参见Android开发者官网。
3 文本框(EditText)
EditText是用来收集输入文本信息与展示文本信息的控件。这个控件有一些常用的属性:
android:maxLines。用来设置显示的最大行数。
android:minLines。用来设置显示的最小行数。
android:inputType。设置输入类型,Android提供了很多中输入类型可以选择,包括number、textPassword、numberDecimal等等。
android:hint。文本框中的提示文本,当文本框没有输入的时候,提示文本显示。
android:textColorHint。设置文本显示颜色,默认浅灰色。
下面举一个小例子来熟悉文本框的用法:
还是以登录界面为例,简单起见,略去复杂的功能。界面设计如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
android:orientation="vertical"
tools:context=".MainActivity" >
<EditText
android:id="@+id/name_et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:text="Name" />
<EditText
android:id="@+id/passward_et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/name_et"
android:ems="10"
android:hint="input password here"
android:inputType="textPassword" />
<Button
android:id="@+id/log_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/passward_et"
android:layout_centerHorizontal="false"
android:text="登录" />
</RelativeLayout>
MainActivity.java代码如下:
package com.beihang.test;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
public static final String TAG = "MainActivity";
private Button btn;
private EditText nameEt;
private EditText passwordEt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initUI();
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.log_btn) {
if (nameEt.getText().toString().equals("Xiaoqie") && passwordEt.getText().toString().equals("Xiaoqie")) {
Toast.makeText(this,"登录成功!",Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this,"输入错误!",Toast.LENGTH_LONG).show();
}
}
}
private void initUI() {
btn = findViewById(R.id.log_btn);
nameEt = findViewById(R.id.name_et);
passwordEt = findViewById(R.id.passward_et);
btn.setOnClickListener(this);
}
}
代码逻辑很简单,当用户点击登录按钮时,通过EditText的getText()方法来分别获取用户输入的用户名和密码,和数据库里的匹配就显示登录成功,这里直接验证输入是否都是"Xiaoqie",如果是就用Toast通知,Toast是常用的一种显示提示的控件,用法就和上面代码中一样,后面讲控件可能还会详细提到这种。
模拟的效果如下图:
4 单选按钮(RadioButton)
RadioButton用来实现从一组选项中选择一个,不能多选,也就是说同一组内的选项之间是互斥的。之所以叫RadioButton,是因为它很像老式的收音机按钮,一个按下之后其它的会弹起。RadioButton有一个特有的属性:android:checked,这是一个布尔值,表示是否被选中。
RadioGroup是一个视图组,它作为RadioButton的容器,只有放到同一个RadioGroup中的RadioButton才能够产生互斥的效果,RadioGroup是继承自线性布局的。
这里我们同样以一个简单的例子来熟悉这种控件的使用方法。页面布局如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
android:orientation="vertical"
tools:context=".MainActivity" >
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="你选择了:"
android:textSize="18sp" />
<RadioGroup
android:id="@+id/radio_gp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tv">
<RadioButton
android:id="@+id/radio_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="语文" />
<RadioButton
android:id="@+id/radio_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="数学" />
<RadioButton
android:id="@+id/radio_3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="英语" />
</RadioGroup>
</RelativeLayout>
MainActivity.java文件如下:
package com.beihang.test;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener {
public static final String TAG = "MainActivity";
private TextView tv;
private RadioGroup radioGp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initUI();
}
@Override
public void onCheckedChanged(RadioGroup rdp, int checkedId) {
if (rdp.getId() == R.id.radio_gp) {
RadioButton rb1 = findViewById(checkedId);
tv.setText(rb1.getText());
}
}
private void initUI() {
tv = findViewById(R.id.tv);
radioGp = findViewById(R.id.radio_gp);
radioGp.setOnCheckedChangeListener(this);
}
}
这里和Button控件采取的方法一样,调用RadioGroup的setOnCheckedChangeListener()方法,传入活动本身,活动内部覆写onCheckedChanged(RadioGroup rdp, int checkedId)回调方法,这个回调方法的两个参数分别为:事件源(也就是哪个RadioGroup发出的);以及勾选控件的ID。这个事件源主要是用来区分多个RadioGroup的,这里只有一个。回调函数里通过checkedId获得被选中的RadioButton,最后在TextView中显示。
运行结果如下:
总结
本文主要介绍了Android中的一些简单控件,包括Button、RadioButton、TextView和EditText的一些基本也是常用的用法。这些简单的控件在开发的过程中是很重要的,主要弄清楚监听器的设置方法。和单选框(RadioButton)对应的还有复选框(CheckBox),这两者原本可以对比,但限于篇幅的原因,下次再介绍。文章的例子是自己现敲的,可能会存在某些小瑕疵。