Android 常用控件


TextView

TextView 主要用于在界面上显示一段文本信息

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textColor="#00ff00"
        android:textSize="24sp"
        android:text="This is TextView"
        tools:ignore="HardcodedText" />

</LinearLayout>

可配置的属性如下:

  • android:id

    给当前控件定义一个唯一标识符

  • android:layout_width、android:layout_height

    指定控件的宽度和高度,可选值有三个:match_parent、wrap_content 和固定值,match_parent 表示让当前控件的大小和父布局的大小一样,wrap_content 表示让当前控件的大小能刚好包含里面的内容,固定值表示给控件指定一个固定的尺寸,单位一般用 dp

  • android:gravity

    指定文字的对齐方式,可选值有 top、bottom、start、end、center 等,可以用 | 来同时指定多个值,这里的 center 表示文字在垂直和水平方向都居中对齐

  • android:textColor

    指定文字的颜色

  • android:textSize

    指定文字的大小


Button

Button 可配置的属性和 TextView 是差不多的

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    ...

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button"
        tools:ignore="HardcodedText" />

</LinearLayout>

接下来我们可以在 MainActivity 中为 Button 的点击事件注册一个监听器

class MainActivity : AppCompatActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        button.setOnClickListener {
            // 在此处添加逻辑
        }
    }
}

也可以实现 View.OnClickListener 接口,并重写 onClick() 方法,然后调用 button 的 setOnClickListener() 方法将 MainActivity 的实例传进去

class MainActivity : AppCompatActivity(), View.OnClickListener {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        button.setOnClickListener(this)
    }

    override fun onClick(v: View?) {
        when (v?.id) {
            R.id.button -> {
                // 在此处添加逻辑
            }
        }
    }
}

EditText

EditText 允许用户在控件里输入和编辑内容,并可以在程序中对这些内容进行处理

<EditText
    android:id="@+id/editText"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Type something here"
    android:maxLines="2"
    tools:ignore="HardcodedText" />
  • android:hint

    指定一段提示性文本

  • android:maxLines

    指定了 EditText 的最大行数为两行,当输入的内容超过两行时,文本会向上滚动,EditText 不会再继续拉伸


ImageView

ImageView 用于在界面上展示图片的一个控件,图片通常放在 drawable 开头的目录下

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/img_1" />

ProgressBar

ProgressBar 用于在界面上显示一个进度条,表示我们的程序正在加载一些数据

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ProgressBar
        android:id="@+id/progressBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

旋转的进度条表明我们的程序正在加载数据,那数据总会有加载完的时候,如何让进度条在数据加载完时消失呢?这里我们就需要使用 android:visibility 属性,可选值有三个:visible、invisible 和 gone,visible 表示控件是可见的,invisible 表示控件不可见,但它仍然占据着原来的屏幕和大小,gone 表示控件不仅不可见,而且不占用屏幕任何控件。所以我们可以在代码中设置控件的可见性,使用的是 setVisibility() 方法,允许传入 View.VISIBLE、View.INVISIBLE 和 View.GONE

另外,我们可以给 ProgressBar 指定不同的样式,默认是圆形进度条,通过 style 属性可以将它指定成水平进度条

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ProgressBar
        android:id="@+id/progressBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="@style/Widget.AppCompat.ProgressBar.Horizontal"
        android:max="100" />

</LinearLayout>

我们通过 android:max 属性给进度条设置一个最大值,然后在代码中动态地更改进度条的进度

class MainActivity : AppCompatActivity(), View.OnClickListener {
   
	...
    override fun onClick(v: View?) {
        when (v?.id) {
            R.id.button -> {
                progressBar.progress = progressBar.progress + 10
            }
        }
    }
}

AlertDialog

AlertDialog 可以在当前界面弹出一个置顶于所有界面元素之上的对话框,一般用于提示一些非常重要的内容或者警告信息

class MainActivity : AppCompatActivity(), View.OnClickListener {
	...
    override fun onClick(v: View?) {
        when (v?.id) {
            R.id.button -> {
                AlertDialog.Builder(this).apply {
                    setTitle("This is Dialog")
                    setMessage("Something important")
                    setCancelable(false)
                    setPositiveButton("OK") {dialog, which ->}
                    setNegativeButton("Cancel") {dialog, which -> }
                    show()
                }
            }
        }
    }
}

创建自定义控件

在这里插入图片描述

在 Android 中,我们所用的所有控件都是直接或间接继承自 View 的,所用的所有布局都是直接或间接继承自 ViewGroup 的。View 是 Android 中最基本的一种 UI 组件,我们所使用的各种控件其实就是在 View 的基础上又添加了各自特有的功能。而 ViewGroup 则是一种特殊的 View,它可以包含很多子 View 和子 ViewGroup,是一个用于放置控件和布局的容器

当系统自带的控件不能满足我们的需求时,可以利用上面的继承结构来创建自定义控件,下面介绍两种创建自定义控件的简单方法:

1. 引入布局

相信创建一个标题栏布局对你来说不是一件难事,只需要加入两个 Button 和一个 TextView。但如果每个 Activity 都需要一个这样的标题栏,就会导致代码的大量重复。这时,我们可以利用引入布局的方式来解决这个问题

新建一个 title.xml 布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/title_bg">

    <Button
        android:id="@+id/titleBack"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="5dp"
        android:background="@drawable/back_bg"
        android:text="Back"
        android:textColor="#fff"
        tools:ignore="HardcodedText" />

    <TextView
        android:id="@+id/titleText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_weight="1"
        android:text="Title Text"
        android:textColor="#fff"
        android:textSize="24sp"
        tools:ignore="HardcodedText" />

    <Button
        android:id="@+id/titleEdit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="5dp"
        android:background="@drawable/back_bg"
        android:text="Edit"
        android:textColor="#fff"
        tools:ignore="HardcodedText" />

</LinearLayout>

标题栏布局已经编写完成,剩下的就是如何在程序中使用这个标题栏了,修改 activity_main.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">

    <include layout="@layout/title" />

</LinearLayout>

最后别忘了在 MainActivity 中将系统自带的标题栏隐藏掉

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        supportActionBar?.hide()
    }
}
2. 创建自定义控件

引入布局的方式确实可以解决重复代码的问题,但如果布局中有一些控件要求能够响应事件,我们还是需要在 Activity 中为这些控件单独编写一次事件注册的代码,这种情况最好是使用自定义控件的方式来解决

新建 TitleLayout 继承自 LinearLayout,让它成为我们自定义的标题栏控件

class TitleLayout(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
    init {
        LayoutInflater.from(context).inflate(R.layout.title, this)
    }
}

我们在 TitleLayout 的主构造函数中声明了 Context 和 AttributeSet 这两个参数,在布局中引入 TitleLayout 控件时就会调用这个构造函数

然后在 init 结构体中需要对标题栏布局进行动态加载,通过 LayoutInflater 的 from() 方法可以构建出一个 LayoutInflater 对象,然后调用 inflate() 方法可以动态加载一个布局文件。inflate() 方法接收两个参数:第一个参数是要加载的布局文件的 id,这里传入 R.layout.title;第二个参数是给加载好的布局再添加一个父布局,这里我们想要指定为 TitleLayout,于是传入 this

自定义控件已经创建好了,接下来我们需要在布局文件中添加这个自定义控件,修改 activity_main.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">

    <com.example.uiwidgettest.TitleLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

下面我们尝试为标题栏中的按钮注册点击事件,修改 TitleLayout 中的代码,如下所示:

class TitleLayout(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {

    init {
        LayoutInflater.from(context).inflate(R.layout.title, this)

        titleBack.setOnClickListener {
            val activity = context as Activity
            activity.finish()
        }

        titleEdit.setOnClickListener {
            Toast.makeText(context, "You clicked Edit button", Toast.LENGTH_SHORT).show()
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值