Kotlin开发第三天,UI开发

Posted peacejay

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin开发第三天,UI开发相关的知识,希望对你有一定的参考价值。

完整代码Gitee地址:kotlin-demo: 15天Kotlin学习计划

第三天学习内容代码:Chapter3

目录

知识点1:公共标题栏

知识点2:自定义标题栏控件

知识点3:RecyclerView

①标准写法     

②使用框架


知识点1:公共标题栏

         市场上应用的界面顶部有一个标题栏,标题栏上会有一到两个按钮可用于返回或其他操作(iPhone没有专门的返回键)。虽然android系统已经给每个Activity提供了标题栏功能,但样式有很大局限性,我们自定义一个标题栏,新建item_title布局。 

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:cardBackgroundColor="@color/purple_500"
    app:cardElevation="2dp"
    app:cardMaxElevation="0dp">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="56dp">

        <LinearLayout
            android:id="@+id/lly_back"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:padding="15dp"
            android:orientation="horizontal">
            <ImageView
                android:layout_width="25dp"
                android:layout_height="25dp"
                android:src="@mipmap/img_return_withe"/>
        </LinearLayout>

        <TextView
            android:id="@+id/tv_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@color/white"
            android:layout_centerVertical="true"
            android:layout_centerHorizontal="true"
            android:textSize="18sp"
            android:textStyle="bold"
            android:text="标题"/>

        <TextView
            android:visibility="invisible"
            android:id="@+id/tv_right_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@color/white"
            android:layout_centerVertical="true"
            android:layout_alignParentRight="true"
            android:textSize="16sp"
            android:padding="12dp"
            android:text="确定"/>

    </RelativeLayout>
</androidx.cardview.widget.CardView>

在activity_learn3布局中引用:

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

运行效果如下:

        可以看到,我们在LinearLayout中分别加入了两个TextView和一个LinearLayout包裹ImageView,左边的LinearLayout可用于返回,右边的TextView可用于编辑,中间的TextView则可以显示一段标题文本。

知识点2:自定义标题栏控件

        引入布局的技巧确实解决了重复编写布局代码的问题,但是如果布局中有一些控件要求能够响应事件,我们还是需要在每个Activity中为这些控件单独编写一次事件注册的代码。比如标题栏中的返回按钮,其实不管是在哪一个Activity中,这个按钮的功能都是相同的,即销毁当前Activity。而如果在每一个Activity中都需要重新注册一遍返回按钮的点击事件,无疑会增加很多重复代码,这种情况最好是使用自定义控件的方式来解决。

        新建TitleLayout继承自LinearLayout,代码如下:

class TitleLayout(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
    //init结构体中需要对标题栏布局进行动态加载
    init {
        val view = LayoutInflater.from(context).inflate(R.layout.item_title, this)
        //为标题栏中的按钮注册点击事件
        val llyBack: LinearLayout = view.findViewById(R.id.lly_back)
        llyBack.setOnClickListener {
            val activity = context as Activity
            activity.finish()
        }
    }
}

        现在自定义控件已经创建好了,接下来我们需要在布局文件中添加这个自定义控件,修改activity_learn3.xml中的代码,如下所示:

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

    <!-- <include layout="@layout/item_title"/> -->

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

</LinearLayout>

重新运行程序,和使用引入布局方式的效果是一样的。

知识点3:RecyclerView

        ListView由于强大的功能,在过去的Android开发当中可以说是贡献卓越,直到今天仍然还有不计其数的程序在使用ListView。不过ListView并不是完美无缺的,比如如果不使用一些技巧来提升它的运行效率,那么ListView的性能就会非常差。还有,ListView的扩展性也不够好,它只能实现数据纵向滚动的效果,如果我们想实现横向滚动的话,ListView是做不到的。

        它可以说是一个增强版的ListView,不仅可以轻松实现和ListView同样的效果,还优化了ListView存在的各种不足之处。目前Android官方更加推荐使用RecyclerView:

新建item_rcy_cont作为RecyclerView每项Item局部:

<?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:orientation="horizontal"
    android:padding="10dp">

    <ImageView
        android:id="@+id/iv_herd"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:layout_marginStart="5dp"
        android:layout_marginLeft="5dp"
        tools:srcCompat="@tools:sample/avatars" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv_name"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:gravity="center"
            android:textSize="15sp"
            android:text="姓名:" />

        <TextView
            android:id="@+id/tv_phone"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:gravity="center"
            android:textSize="15sp"
            android:text="电话:" />
    </LinearLayout>

</LinearLayout>

新建实体类UserBean,作为数据存储映射实体:

class UserBean(val herd: Int, val name: String, val phone: String)

修改activity_learn3.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"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical">

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

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:listitem="@layout/item_rcy_cont"/>
</LinearLayout>

预览效果如下:

①标准写法     

        接下来需要为RecyclerView准备一个适配器,新建UserAdapter类,让这个适配器继承自RecyclerView.Adapter,并将泛型指定为UserAdapter.ViewHolder。其中,ViewHolder是我们在UserAdapter中定义的一个内部类,代码如下所示:

//让这个适配器继承自RecyclerView.Adapter,并将泛型指定为FruitAdapter.ViewHolder。
class UserAdapter(private val userList: List<UserBean>) :
    RecyclerView.Adapter<UserAdapter.ViewHolder>() {

    //内部类绑定控件
    inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val nameText: TextView = view.findViewById(R.id.tv_name)
        val phoneText: TextView = view.findViewById(R.id.tv_phone)
        val ivHerd: ImageView = view.findViewById(R.id.iv_herd)
    }

    //创建布局
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view =
            LayoutInflater.from(parent.context).inflate(R.layout.item_rcy_cont, parent, false)
        return ViewHolder(view)
    }

    //展示布局数量
    override fun getItemCount(): Int {
        return userList.size
    }

    //给控件赋值与样式
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.nameText.text = userList[position].name
        holder.phoneText.text = userList[position].phone
        holder.ivHerd.setImageResource(userList[position].herd)
    }
}

        虽然看上去好像多了好几个方法,但其实它比ListView的适配器要更容易理解。适配器准备好了之后,我们就可以开始使用RecyclerView了,修改Learn3Activity中的代码,如下所示:

class Learn3Activity : BaseActivity() {

    private val userList = ArrayList<UserBean>()
    private lateinit var mAdapter: UserNewAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_learn3)
        //3、RecyclerView控件
        recyclerView()
    }

    private fun recyclerView() {
        //初始化用户数据
        initUser()
        val recyclerView: RecyclerView = findViewById(R.id.recyclerView)
        //①标准写法,使用适配器
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = UserAdapter(userList)
    }

    private fun initUser() {
        repeat(2) {
            userList.add(UserBean(R.mipmap.image_nv,"迪丽不热", "17321341289"))
            userList.add(UserBean(R.mipmap.image_nan,"杀手不冷", "17377621412"))
            userList.add(UserBean(R.mipmap.image_nv,"赵思露", "19987878221"))
            userList.add(UserBean(R.mipmap.image_nv,"井川里予", "13612344637"))
            userList.add(UserBean(R.mipmap.image_nan,"阿斯顿", "13635465678"))
            userList.add(UserBean(R.mipmap.image_nan,"没啥用科技", "13801940921"))
            userList.add(UserBean(R.mipmap.image_nv,"阿瑟东", "16622348923"))
        }
    }
}

        这里使用了initUser()方法,用于初始化所有的用户数据。接着在onCreate()方法中先创建了一个LinearLayoutManager对象,并将它设置到RecyclerView当中。LayoutManager用于指定RecyclerView的布局方式,这里使用的LinearLayoutManager是线性布局的意思,可以实现和ListView类似的效果。接下来我们创建了UserAdapter的实例,并将水果数据传入UserAdapter的构造函数中,最后调用RecyclerView的setAdapter()方法来完成适配器设置,这样RecyclerView和数据之间的关联就建立完成了。现在运行一下程序,如下所示。

        当然这只是RecyclerView的基本用法而已,还有更多用法,比如实现横向滚动和瀑布流布局,这个也并不复杂,与Java写法类似。

②使用框架

        BaseRecyclerViewAdapterHelper是一个比较成熟的框架,代码书写简洁很大提升开发效率,接下来我们用Kotlin写法使用它,在app目录下的build.gradle添加依赖:

/* 灵活的RecyclerView框架 */
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.4'

创建适配器UserNewAdapter:

class UserNewAdapter :
    BaseQuickAdapter<UserBean, BaseViewHolder>(R.layout.item_rcy_cont) {
    override fun convert(holder: BaseViewHolder, item: UserBean) {
        //获取控件ID
        val icon = holder.getView<ImageView>(R.id.iv_herd)
        //展示图片
        icon.setImageResource(item.herd)
        //直接设置文本内容
        holder.setText(R.id.tv_name, item.name)
        holder.setText(R.id.tv_phone, item.phone)
    }
}

        适配器准备好了之后,我们就可以开始使用RecyclerView了,修改Learn3Activity中的代码,如下所示:

private fun recyclerView() {
    //初始化用户数据
    initUser()
    val recyclerView: RecyclerView = findViewById(R.id.recyclerView)

    //②使用框架,BaseRecyclerViewAdapterHelper
    mAdapter = UserNewAdapter()
    recyclerView.layoutManager = LinearLayoutManager(this)
    recyclerView.adapter = mAdapter
    mAdapter.addData(userList)//添加数据
}

 总体来看框架写法更简单,运行效果和写法①一样就不再赘述。

未完待续......

以上是关于Kotlin开发第三天,UI开发的主要内容,如果未能解决你的问题,请参考以下文章

Android开发之记账本开发第三天

软件工程课设迭代开发第三天

Android_校易app开发日志_第三天

微信小程序开发-学习第三天总结

使用绑定从片段访问父活动的 UI 元素

开发第三天