常见控件的使用方法

Android 给我们提供了大量的 UI 控件,合理地使用这些控件就可以非常轻松地编写出相 当不错的界面。
 

1. TextView

TextView 可以说是 Android 中最简单的一个控件了,它主要用于在界面上显示一段文本信息,比如你在第一章看到的 Hello world!
<?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

Button是程序用于和用户进行交互的一个重要控件,它可配置的属性和 TextView 是差不多的,我们 可以在 activity_main.xml 中这样加入 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

ImageView 是用于在界面上展示图片的一个控件,通过它可以让我们的程序界面变得更加 丰富多彩。学习这个控件需要提前准备好一些图片,由于目前 drawable 文件夹下已经有一张 ic_launcher.png 图片了,那我们就先在界面上展示这张图吧,修改 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">

   ................

    <ImageView
        android:id="@+id/image_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/gougou"/>
</LinearLayout>
可以看到,这里使用 android:src 属性给 ImageView 指定了一张图片,并且由于图片的宽 和高都是未知的,所以将 ImageView 的宽和高都设定为 wrap_content,这样保证了不管图片 的尺寸是多少都可以完整地展示出来。重新运行程序,效果如图

我们还可以在程序中通过代码动态地更改 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 将会一直存在。

 

 

 

 

 

posted on 2021-07-09 17:17  夜尽天明00  阅读(272)  评论(0编辑  收藏  举报