安卓速通(其实是期末复习~)(第三章【ListView有点难搞】)
ZealSinger 发布于 阅读:179 期末复习
Android常见的界面控件⭐️
在安卓应用程序中,都是通过界面控件与用户交互。整个第三章都是考点重点,尤其是前面的简单控件,后面的列表控件和自定义控件感觉因为难度问题占比会少一点
简单控件的使用
TextView控件
TextView控件即文本控件,主要用于显示文本信息,可以在XML布局文件中添加属性的方式控制TextView控件的样式,TextView控件常见属性如下
属性名称 | 属性描述 |
---|---|
android:layout_width | 设置控件的宽度 |
android:layout_height | 设置控件的高度 |
android:id | 设置控件的唯一标识 |
android:background | 设置控件背景(颜色or图片) |
android:layou_margin | 设置当前控件和边界/周围控件/布局的距离 |
android:padding | 设置当前控件和控件中内容之间的距离 |
android:text | 设置控件的内容 |
android:textSize | 设置控件文本字体大小 推荐单位sp |
android:textColor | 设置控件文本字体颜色 |
android:gravity | 设置控件文本内容的位置,例如设置center标识居中展示 |
android:maxLength | 设置控件文本最大长度,超过该长度的内容不予显示 |
android:lines | 设置控件文本行数,超出此行数的文本不予显示 |
android:ellipsize | 设置当文本内容超出控件规定范围的时候的显示方式,属性值一般为start/middl/end 分别代表在文本头部/中间/尾部显示省略号.... |
android:drawableTop | 设置图片资源在文本的上方,图片资源可以通过@drawable/文件名引用 同理drawableBottom ; drawableRight ; drawableLeft |
android:lineSpacingExtra | 设置控件文本的行间距 |
android:textStyle | 设置控件文本样式。例如bold粗体 , italic斜体,normal正常 |
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textStyle="bold"
android:maxLength="2"
android:text="粗体啊啊" />
<TextView
android:layout_marginTop="100dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/black"
android:textSize="40sp"
android:textStyle="italic"
android:ellipsize="end"
android:maxLines="1"
android:text="斜体且超出了范围啊啊啊啊啊啊啊啊" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="300dp"
android:lineSpacingExtra="10dp"
android:text="正常文字有10dp的行距啊啊啊啊"
android:textSize="35sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="450dp"
android:text="正常文字但是没有行距啊啊啊啊"
android:textSize="35sp" />
</RelativeLayout>
需要注意的是,TextView组件也可以通过Java/Kotlin代码的形式进行创建和饿属性赋值
EditText控件
简单而言就是可编辑文本框控件,属于TextView的子类,支持通用属性和TextView的属性,以及自己特有的属性
属性名称 | 属性描述 |
---|---|
android:hint | 控件中文本内容为空的时候默认显示的内容 |
android:textColorHint | 控件中文本内容为空的时候默认显示的内容的颜色 |
android:password | 控件内容按照密码展示,即文本内容只会展示"." |
android:phoneNumber | 控件内容只能输入数字 |
android:minLines | 控件内容最小行数 |
android:scrollHorizontally | 控件文本内容超出EditText宽度的情况下是否出现横拉条 |
android:editable | 是否可编辑 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:layout_width="200dp"
android:layout_height="50dp"
android:background="@color/teal_200"
android:hint="可以输入任何内容"
android:textColorHint="@color/purple_500"
/>
<EditText
android:layout_marginTop="50dp"
android:layout_width="200dp"
android:layout_height="50dp"
android:background="@color/teal_200"
android:maxLines="1"
android:hint="只能输入数字且滑块"
android:phoneNumber="true"
android:scrollHorizontally="true"
android:textColorHint="@color/purple_500"
/>
<EditText
android:layout_marginTop="50dp"
android:layout_width="200dp"
android:layout_height="50dp"
android:background="@color/teal_200"
android:hint="密码保护"
android:password="true"
android:textColorHint="@color/purple_500"
/>
</LinearLayout>
Button控件点击事件的绑定
Button控件即按钮控件,继承自TextView,既可以显示文本,又可以显示图片,又可以处理点击事件,当按钮控件被点击的时候,被按下与弹起的背景会有一个动态的切换效果,这个就是按钮控件默认的一个点击效果,但是实际上,所有的控件都可以设置点击事件,只是Button更多一点,所以我们对于Button控件主要学习的也就是事件绑定,实现事件绑定有三种方法分别是Button控件配置onClick属性 ; 绑定监听 ; Activity实现监听接口
配置onClick事件
Button控件通过onClick属性的属性值来设置事件点击事件,代码如下
<Button android:onClick="...."
......
/>
其中....对应的就是事件名称,我们可以在Activity中定义对应的方法函数逻辑来实现对应的事件逻辑,需要注意的是,Activity中的方法/函数名必须和onClick中设置的属性值 .... 是一样的名字,就能保证跳转到对应的事件中
绑定监听
即在Button中不设置onClick属性,而是通过对于Button对象设置监听器和回调函数,从而当按钮被点击的时候进行逻辑回调,这个是比较推荐的方式,因为如今android:onClick属性已经快被Android弃用
对应的MainActivity代码
class MainActivity : ComponentActivity(),OnClickListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
KtAndroisTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding)
)
}
}
}
}
fun clickFun(view: View) {
// Toast类似于print打印 可以在安卓程序的最顶层展示内容 暂且知道有这个东西和使用 后面会讲
Toast.makeText(this, "按钮被点击了!", Toast.LENGTH_SHORT).show()
}
override fun onClick(v: View?) {
when(v?.id){
R.id.button->{
v.findViewById<Button>(R.id.button).setText("已经被点击了")
}
}
}
}
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Column(modifier = modifier) {
// 新增 XML 布局
AndroidView(
factory = { context ->
// 加载 XML 布局
val view = View.inflate(context, R.layout.relativelayouttext, null)
// createRelativeLayout(context)
val button= view.findViewById<Button>(R.id.button)
button.setOnClickListener {
Toast.makeText(context, "按钮被点击了!", Toast.LENGTH_SHORT).show()
}
view
},
modifier = Modifier.padding(20.dp)
)
}
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
KtAndroisTheme {
Greeting("Android")
}
}
Activity实现onClickListenter接口
对应MainActivity代码
class MainActivity : ComponentActivity(),OnClickListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
KtAndroisTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding)
)
}
}
}
}
override fun onClick(v: View?) {
when(v?.id){
R.id.button->{
v.findViewById<Button>(R.id.button).setText("已经被点击了")
}
}
}
}
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Column(modifier = modifier) {
// 新增 XML 布局
AndroidView(
factory = { context ->
// 加载 XML 布局
val view = View.inflate(context, R.layout.relativelayouttext, null)
// createRelativeLayout(context)
val button= view.findViewById<Button>(R.id.button)
button.setOnClickListener(view.context as MainActivity)
view
},
modifier = Modifier.padding(20.dp)
)
}
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
KtAndroisTheme {
Greeting("Android")
}
}
ImageView控件
ImageView即图片控件继承自View控件,主要用于加载各种图片资源,常用属性如下
属性名称 | 属性描述 |
---|---|
android:layout_width | 设置控件宽度 |
android:layout_height | 设置控件高度 |
android:id | 设置控件唯一标识 |
android:background | 设置控件背景 |
android:layout_margin | 设置控件和周围控件/布局边界的距离 |
android:src | 设置控件要显示的图片资源路径 |
android:scaleType | 将图片资源缩放或者移动,以适应控件的宽高 |
android:tint | 将图片渲染成指定颜色 |
<!--最外层布局采用RelativeLayout相对布局-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--
android:scaleType="fitStart" 让图片和布局顶部进行对齐
没有这个属性的话 默认是居中的
android:background="@color/purple_200"
即将没有图片的地方填充为指定颜色
还有一个没用到的android:tint 其实就是将图片用某个颜色完全填充覆盖
--->
<ImageView
android:layout_width="400dp"
android:layout_height="400dp"
android:background="@color/purple_200"
android:src="@drawable/cmd2"
android:scaleType="fitStart"
/>
</RelativeLayout>
RadioButton控件
RaioButton控件是单选控件,是Button控件的子类,常常与RadioGroup组合使用,RadioGroup继承自LinearLayout,所以可以通过android:orientation 属性决定每个选项是竖着排列or水平排列。每个单选按钮都具备 “选中” 和 “未选中” 两个状态,android:checked属性决定是否选中状态 true则为选中
一个RadioGroup代表一个单选组合框(或者理解一个单选题目),包含多个RadioButton(理解为选项),一个RadioGroup中一定只会有一个RadioButton处于选中状态,组合使用格式一般如下
<!--最外层布局采用RelativeLayout相对布局-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RadioGroup
android:layout_width="200dp"
android:layout_height="200dp">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="选项一"
android:textSize="20sp"
/>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="选项二"
android:textSize="20sp"
/>
</RadioGroup>
<RadioGroup
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginTop="100dp"
android:orientation="horizontal"
>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="A"
android:textSize="20sp"
/>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="B"
android:textSize="20sp"
/>
</RadioGroup>
</RelativeLayout>
样式属性上不是很多要讲的,可以看一下因为是继承了LinearLayout所以选项一和选项二是竖直排序而AB是水平排序
RadioButton是Button的子类,所以其能绑定事件,这个也是其最重要的一点点,RadioGroup通过setOnCheckedChageListener()方法进行绑定事件
package com.example.ktandrois
import android.content.Context
import android.os.Bundle
import android.view.View
import android.view.View.OnClickListener
import android.widget.Button
import android.widget.RadioButton
import android.widget.RadioGroup
import android.widget.RelativeLayout
import android.widget.TextView
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.ktandrois.ui.theme.KtAndroisTheme
import androidx.compose.foundation.layout.Column
import androidx.compose.ui.viewinterop.AndroidView
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
KtAndroisTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding)
)
}
}
}
}
// 处理 RadioGroup 选择事件 根据选择的checkId进行打印展示
private fun listenerHandler(checkedId: Int) {
val message = when (checkedId) {
R.id.g1b1 -> "您在 g1 选择了选项一"
R.id.g1b2 -> "您在 g1 选择了选项二"
R.id.g2b1 -> "您在 g2 选择了 A"
R.id.g2b2 -> "您在 g2 选择了 B"
else -> return
}
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
// 统一监听器,当发生选择事件 就会获取RadioGroup的groupId和对应的选项的id
private val checkedChangeListener = RadioGroup.OnCheckedChangeListener{
group, checkedId -> listenerHandler(checkedId)
}
fun getCheckedChangeListener():RadioGroup. OnCheckedChangeListener{
return checkedChangeListener
}
}
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Column(modifier = modifier) {
// 新增 XML 布局
AndroidView(
factory = { context ->
// 加载 XML 布局
val view = View.inflate(context, R.layout.relativelayouttext, null)
// createRelativeLayout(context)
var group1 = view.findViewById<RadioGroup>(R.id.g1)
var group2 = view.findViewById<RadioGroup>(R.id.g2)
var activity = context as MainActivity
// activity.getCheckedChangeListener()通过这个方法统一获得上面定义的 checkedChangeListener 这个监听器
group1.setOnCheckedChangeListener(activity.getCheckedChangeListener())
group2.setOnCheckedChangeListener(activity.getCheckedChangeListener())
view
},
modifier = Modifier.padding(20.dp)
)
}
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
KtAndroisTheme {
Greeting("Android")
}
}
checkBox控件
CheckBox控件表示复选框,是Button控件的子类,用于实现多选功能,每个选项都具备 选中和未选中 两种状态, 状态都是通过 android:checked属性指定的,true则为选中true则为选中
对于CheckBox的选择事件,也是通过OnCheckedChangeListener方法进行监听,通过setCheckedChangeListener进行绑定
需要注意的是checkBox就是多选中的单个选项,不存在checkGroup这种包含性的父标签
如下 实现多选的动态展示代码
package com.example.ktandrois
import android.content.Context
import android.os.Bundle
import android.view.View
import android.view.View.OnClickListener
import android.widget.Button
import android.widget.CheckBox
import android.widget.CompoundButton
import android.widget.RadioButton
import android.widget.RadioGroup
import android.widget.RelativeLayout
import android.widget.TextView
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.ktandrois.ui.theme.KtAndroisTheme
import androidx.compose.foundation.layout.Column
import androidx.compose.ui.viewinterop.AndroidView
import org.w3c.dom.Text
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
KtAndroisTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding)
)
}
}
}
}
private val likeList:MutableSet<String> = mutableSetOf()
private fun handler(buttonView: View,isChecked: Boolean){
var checkBox = buttonView as CheckBox
var boxContent = checkBox.text.toString()
var hobbyText = this.findViewById<TextView>(R.id.hobbyText)
if(isChecked){ // 为true则说明被选中 加入到likeList中
likeList.add(boxContent)
hobbyText.setText("你选择的是:${likeList}")
}else{
likeList.remove(boxContent)
hobbyText.setText("你选择的是:${likeList}")
}
}
private val checkedChangeListener = CompoundButton.OnCheckedChangeListener{
buttonView, isChecked -> handler(buttonView,isChecked) // buttoView就是对应的每个checkBox isChecked就是该checkBox是否被选
}
fun getListener(): CompoundButton. OnCheckedChangeListener{
return checkedChangeListener
}
}
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Column(modifier = modifier) {
// 新增 XML 布局
AndroidView(
factory = { context ->
// 加载 XML 布局
val view = View.inflate(context, R.layout.relativelayouttext, null)
val activity = context as MainActivity
// createRelativeLayout(context)
view.findViewById<CheckBox>(R.id.lq).setOnCheckedChangeListener(activity.getListener())
view.findViewById<CheckBox>(R.id.ymq).setOnCheckedChangeListener(activity.getListener())
view.findViewById<CheckBox>(R.id.ppq).setOnCheckedChangeListener(activity.getListener())
view
},
modifier = Modifier.padding(20.dp)
)
}
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
KtAndroisTheme {
Greeting("Android")
}
}
Toast类
Toast类是安卓提供的轻量级提醒机制,可以在整个程序界面的最上层展示用于提醒用户,我们上面的代码中其实有使用过了已经
其函数原型为
-
第一个参数 context 代表应用程序环境 一般是当前所在的activity
-
第二个参数 text 是一个String类型的参数 代表要展示输出的内容
-
第三个参数 time 为内置的时间单位 一般为 Toast.LENGTH_SHORT 或者 Toast.LENGTH_LONG 前者表示展示较长时间 后者表示较短时间
Toast.makeText(Context,String Text,Time).show()
列表控件ListView
列表控件ListView主要是能以列的形式展示数据,并且能根据屏幕高度自适应的显示,在安卓开发中常用
其常用属性为
属性名称 | 属性描述 |
---|---|
android:listSelector | 当条目被点击后,改变条目的背景颜色 |
android:divider | 设置分割线的颜色 |
android:dividerHeight | 设置分割线高度 |
android:scrollbars | 是否显示滚动条 |
android:fadingEdge | 去掉上边和下边的黑色阴影 |
如图可以看到 在默认状态下 ListView就展示出了他的特点,多条目
适配器
如上所示,ListView有很多条目,我们会需要将我们的数据添加到ListView中会需要用到数据适配器Adpater,数据适配器作为数据和视图之间的桥梁,类似一个转化器,将复杂的数据转化为用户可以接受的方式呈现,安卓配备了多个对ListView的数据适配器
-
BaseAdapter 基础数据适配器
是一个抽象类,一般通过自定义类实现这个类,从而使用自定义适配器,其主要方法是如下getCount() ; getItem(int position) ;getItemId(int position); View getView(position,view,parent)
override fun getCount(): Int // 获取条目总数
override fun getItem(position: Int): Any // 获取position位置上的Item对象
override fun getItemId(position: Int): Long // 获取position位置上的这个Item的id
// 获取对应的postion位置上的Item对象 convertView为复用旧视图 parent用于加载XML布局文件
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View -
SiimpleAdapter继承自BaseAdapter 实现了上述四个抽象方法,进行了简单的封装
-
ArrayAdapter 也是继承自BaseAdapter 和SimpleAdapter类似
RecycleView控件
RecycleView控件的作用是在有限的空间内展示大量数据 安卓5.0之后才出现的新特性,有点类似于ListView控件
RecyclerView可以通过LayoutManager类实现横向,竖向的列表效果,瀑布流效果和GridView效果,比ListView强大 ;
在数据适配器上使用的是RecyclerView.Adapter适配器,该适配器在BaseAdapter适配器上将getView方法进行了拆分为了onCreateViewHolder和onBindViewHolder两个方法,强制使用ViewHolder类,规范性更强
RecycleView控件复用 Item对象的工作由空间自己实现而ListView的复用Item工作由开发者优化实现
RecycleView可以给Item对象添加动画效果而ListView不可以
(书上说了这些之后就是直接案例了 所以直接过 也不多说了,感觉唯一可能的考点就是RecycleView和listView的区别)
自定义控件
我们知道控件本质上是View类对象,所以实际上自定义控件就是继承View类从而实现拓展,满足自定义需求
实现一个类一般就要重写父类的方法,一般需要重写的就是onMeasure()方法 , onDraw()方法 和 onLayout()方法
-
onMeasure()方法
设置控件本身的高度和宽度,接受两个参数,分别是父容器的宽度和父容器的高度
-
onDraw()方法
用于绘画图像,接受一个Canvas类型的参数表示化部,这个通常需要搭配Paint类搭配使用
-
onLayout()方法
文章标题:安卓速通(其实是期末复习~)(第三章【ListView有点难搞】)
文章链接:https://zealsinger.xyz/?post=10
本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明来自ZealSinger !
如果觉得文章对您有用,请随意打赏。
您的支持是我们继续创作的动力!

微信扫一扫

支付宝扫一扫
