常见控件的使用方法
1. TextView
<?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=".MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
外面的 LinearLayout 先忽略不看,在 TextView 中我们使用 android:id 给当前控件定义了 一个唯一标识符,这个属性在上一章中已经讲解过了。然后使用 android:layout_width 指定了 控件的宽度,使用 android:layout_height 指定了控件的高度。Android 中所有的控件都具有这 两个属性,可选值有三种 match_parent、fill_parent 和 wrap_content,其中 match_parent 和 fill_parent 的意义相同,现在官方更加推荐使用 match_parent。match_parent 表示让当前控件的大小和父布局的大小一样,也就是由父布局来决定当前控件的大小。wrap_content 表示让 当前控件的大小能够刚好包含住里面的内容,也就是由控件内容决定当前控件的大小。所以 上面的代码就表示让 TextView 的宽度和父布局一样宽,也就是手机屏幕的宽度,让 TextView 的高度足够包含住里面的内容就行。当然除了使用上述值,你也可以对控件的宽和高指定一 个固定的大小,但是这样做有时会在不同手机屏幕的适配方面出现问题。
TextView 中的文字默认是居左上角对齐的,虽然 TextView 的宽度 充满了整个屏幕,可是从效果上完全看不出来。开发时注意。
2. Button
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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/textView" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="TextView" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" /> </LinearLayout>
加入 Button 之后的界面如图:
然后我们就可以为TextView和Button添加逻辑了。
我们可以在 MainActivity 中为 Button 的点击事件注册一个监听器,如下所示:
package com.example.activitytest; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity { private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button)findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v) { } }); } }
这样每当点击按钮时,就会执行监听器中的 onClick()方法,我们只需要在这个方法中加 入待处理的逻辑就行了。如果你不喜欢使用匿名类的方式来注册监听器,也可以使用实现接 口的方式来进行注册,代码如下所示:
package com.example.activitytest; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button)findViewById(R.id.button); button.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.button: //采用id识别是哪个button的逻辑 // 在此处添加逻辑 break; default: break; } } }
这两种写法都可以实现对按钮点击事件的监听,至于使用哪一种就全凭你喜好了。
3.EditText
EditText 是程序用于和用户进行交互的另一个重要控件,它允许用户在控件里输入和编 辑内容,并可以在程序中对这些内容进行处理。EditText 的应用场景应该算是非常普遍了, 发短信、发微博、聊 QQ 等等,在进行这些操作时,你不得不使用到 EditText。那我们来看 一看如何在界面上加入 EditText 吧,修改 activity_main.xml 中的代码,如下所示:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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/edit_text" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
其实看到这里,我估计你已经总结出 Android 控件的使用规律了,基本上用法都很相似, 给控件定义一个 id,再指定下控件的宽度和高度,然后再适当加入些控件特有的属性就差不 多了。所以使用 XML 来编写界面其实一点都不难,完全可以不用借助任何可视化工具来实 现。现在重新运行一下程序,EditText 就已经在界面上显示出来了,并且我们是可以在里面 输入内容的。细心的你平时应该会留意到,一些做得比较人性化的软件会在输入框里显示一些提示性 的文字,然后一旦用户输入了任何内容,这些提示性的文字就会消失。这种提示功能在 Android 里是非常容易实现的,我们甚至不需要做任何的逻辑控制,因为系统已经帮我们都 处理好了。修改 activity_main.xml,如下所示:
<EditText android:id="@+id/edit_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="提示内容" />
这里使用 android:hint 属性来指定了一段提示性的文本,然后重新运行程序,效果如图
可以看到,EditText 中显示了一段提示性文本,然后当我们输入任何内容时,这段文本 就会自动消失。
不过随着输入的内容不断增多,EditText 会被不断地拉长。这时由于 EditText 的高度指 定的是 wrap_content,因此它总能包含住里面的内容,但是当输入的内容过多时,界面就会 变得非常难看。我们可以使用 android:maxLines 属性来解决这个问题,修改 activity_main.xml, 如下所示:
<EditText android:id="@+id/edit_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="提示内容" android:maxLines="2" />
这里通过 android:maxLines 指定了 EditText 的最大行数为两行,这样当输入的内容超过 两行时,文本就会向上滚动,而 EditText 则不会再继续拉伸,
我们还可以结合使用 EditText 与 Button 来完成一些功能,比如通过点击按钮来获取 EditText 中输入的内容。修改 MainActivity 中的代码,如下所示:
package com.example.activitytest; 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 { private Button button; private EditText editText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button)findViewById(R.id.button); editText = (EditText)findViewById(R.id.edit_text); button.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.button: //采用id识别是哪个button的逻辑 // 在此处添加逻辑 String inputText = editText.getText().toString(); Toast.makeText(MainActivity.this, inputText, Toast.LENGTH_LONG).show(); break; default: break; } } }
首先通过 findViewById()方法得到 EditText 的实例,然后在按钮的点击事件里调用 EditText 的 getText()方法获取到输入的内容,再调用 toString()方法转换成字符串,最后仍 然还是老方法,使用 Toast 将输入的内容显示出来。
4.ImageView
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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"> ................ <ImageView android:id="@+id/image_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/gougou"/> </LinearLayout>
我们还可以在程序中通过代码动态地更改 ImageView 中的图片。这里我准备了另外一张 图片,jelly_bean.png,将它复制到 res/drawable-hdpi 目录下,然后修改 MainActivity 的代码, 如下所示:
package com.example.activitytest; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.Toast; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button button; private EditText editText; private ImageView imageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button)findViewById(R.id.button); editText = (EditText)findViewById(R.id.edit_text); imageView = (ImageView)findViewById(R.id.image_view); button.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.button: //采用id识别是哪个button的逻辑 // 在此处添加逻辑 imageView.setImageResource(R.drawable.hudie); break; default: break; } } }
按钮的点击事件里,通过调用 ImageView 的 setImageResource()方法将显示的图片改 成 hudie.jpeg。
5.ProgressBar
ProgressBar 用于在界面上显示一个进度条,表示我们的程序正在加载一些数据。它的用 法也非常简单,修改 activity_main.xml 中的代码,如下所示:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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"> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" /> ..................... <ProgressBar android:id="@+id/progress_bar" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
重新运行程序,会看到屏幕中有一个圆形进度条正在旋转。
这时你可能会问,旋转的进度条表明我们的程序正在加载数据,那数据总会有加载完的 时候吧,如何才能让进度条在数据加载完成时消失呢?这里我们就需要用到一个新的知识 点 ,A n d r o i d 控 件 的 可 见 属 性 。所 有 的 A n d r o i d 控 件 都 具 有 这 个 属 性 ,可 以 通 过 a n d r o i d : v i s i b i l i t y 进行指定,可选值有三种,visible、invisible 和 gone。visible 表示控件是可见的,这个值是 默认值,不指定 android:visibility 时,控件都是可见的。invisible 表示控件不可见,但是它仍 然占据着原来的位置和大小,可以理解成控件变成透明状态了。gone 则表示控件不仅不可见, 而且不再占用任何屏幕空间。我们还可以通过代码来设置控件的可见性,使用的是 setVisibility()方法,可以传入 View.VISIBLE、View.INVISIBLE 和 View.GONE 三种值。
接下来我们就来尝试实现,点击一下按钮让进度条消失,再点击一下按钮让进度条出现 的这种效果。修改 MainActivity 中的代码,如下所示:
package com.example.activitytest; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.Toast; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button button; private ProgressBar progressBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button)findViewById(R.id.button); progressBar = (ProgressBar)findViewById(R.id.progress_bar); button.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.button: //采用id识别是哪个button的逻辑 // 在此处添加逻辑 if(progressBar.getVisibility()==View.GONE){ progressBar.setVisibility(View.VISIBLE); }else{ progressBar.setVisibility(View.GONE); } break; default: break; } } }
在按钮的点击事件中,我们通过 getVisibility()方法来判断 ProgressBar 是否可见,如果 可见就将 ProgressBar 隐藏掉,如果不可见就将 ProgressBar 显示出来。重新运行程序,然后 不断地点击按钮,你就会看到进度条会在显示与隐藏之间来回切换。
另外,我们还可以给 ProgressBar 指定不同的样式,刚刚是圆形进度条,通过 style 属性 可以将它指定成水平进度条,修改 activity_main.xml 中的代码,如下所示: 指定成水平进度条后,我们还可以通过 android:max 属性给进度条设置一个最大值,然 后在代码中动态地更改进度条的进度。修改 MainActivity 中的代码,如下所示:
<ProgressBar android:id="@+id/progress_bar" android:layout_width="wrap_content" android:layout_height="wrap_content" style="?android:attr/progressBarStyleHorizontal" android:max="100" />
指定成水平进度条后,我们还可以通过 android:max 属性给进度条设置一个最大值,然 后在代码中动态地更改进度条的进度。修改 MainActivity 中的代码,如下所示:
package com.example.activitytest; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.Toast; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button button; private ProgressBar progressBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button)findViewById(R.id.button); progressBar = (ProgressBar)findViewById(R.id.progress_bar); button.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.button: //采用id识别是哪个button的逻辑 // 在此处添加逻辑 int progress = progressBar.getProgress(); progress = progress + 10; progressBar.setProgress(progress); break; default: break; } } }
每点击一次按钮,我们就获取进度条的当前进度,然后在现有的进度上加 10 作为更新 后的进度。 ProgressBar 还有几种其他的样式,你可以自己去尝试一下。
6. AlertDialog
AlertDialog 可以在当前的界面弹出一个对话框,这个对话框是置顶于所有界面元素之上 的,能够屏蔽掉其他控件的交互能力,因此一般 AlertDialog 都是用于提示一些非常重要的 内容或者警告信息。比如为了防止用户误删重要内容,在删除前弹出一个确认对话框。下面 我们来学习一下它的用法,修改 MainActivity 中的代码,如下所示:
package com.example.activitytest; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import android.content.DialogInterface; import android.os.Bundle; import android.view.View; import android.widget.Button;import android.widget.Toast; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button button; private ProgressBar progressBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button)findViewById(R.id.button); button.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.button: //采用id识别是哪个button的逻辑 // 在此处添加逻辑 AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this); dialog.setTitle("这是一个对话框"); dialog.setMessage("你是否已经获取新的技能?"); dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); dialog.show(); break; default: break; } } }
首先通过 AlertDialog.Builder 创建出一个 AlertDialog 的实例,然后可以为这个对话框设 置标题、内容、可否取消等属性,接下来调用 setPositiveButton()方法为对话框设置确定按钮 的点击事件,调用 setNegativeButton()方法设置取消按钮的点击事件,最后调用 show()方法 将对话框显示出来。
7. ProgressDialog
ProgressDialog 和 AlertDialog 有点类似,都可以在界面上弹出一个对话框,都能够屏蔽 掉其他控件的交互能力。不同的是,ProgressDialog 会在对话框中显示一个进度条,一般是 用于表示当前操作比较耗时,让用户耐心地等待。它的用法和 AlertDialog 也比较相似,修 改 MainActivity 中的代码,如下所示:
package com.example.activitytest; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import android.app.ProgressDialog; import android.content.DialogInterface; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button)findViewById(R.id.button); button.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.button: //采用id识别是哪个button的逻辑 // 在此处添加逻辑 ProgressDialog progressDialog = new ProgressDialog(MainActivity.this); progressDialog.setTitle("这是一个进度条对话框!!"); progressDialog.setMessage("Loading......"); progressDialog.setCancelable(false); progressDialog.show(); break; default: break; } } }
可以看到,这里也是先构建出一个 ProgressDialog 对象,然后同样可以设置标题、内容、 可否取消等属性,最后也是通过调用show()方法将ProgressDialog显示出来。 注意如果在 setCancelable()中传入了 false,表示 ProgressDialog 是不能通过 Back 键取消 掉的,这时你就一定要在代码中做好控制,当数据加载完成后必须要调用 ProgressDialog 的 dismiss()方法来关闭对话框,否则 ProgressDialog 将会一直存在。