Kotlin项目实战之手机影音---toolbar处理、设置菜单点击事件处理、设置界面处理

在上一次https://www.cnblogs.com/webor2006/p/12622874.html已经初步对主界面进行了一个框架布局,目前的样子如下:

其主界面的布局文件为:

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

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

    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <com.roughike.bottombar.BottomBar
        android:id="@+id/bottomBar"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_alignParentBottom="true"
        app:bb_tabXmlResource="@xml/bottombar_tabs" />
</LinearLayout>

下面继续进行功能的实现。

toolbar处理:

修改背景色:

这里先来处理一下toolbar,先回忆一下最终的效果:

首先背景色不对,目前toolbar的背景用的是主题色:

所有这里将修改一下标题栏的主题色既可:

 

运行:

标题封装:

对于标题是每个界面都会要进行处理的,所以这里有必要对它进行一个封装处理了,这里就学一下在Kotlin中是如何来达到封装的目的的,跟Java的写法还是不太一样的。

这里新建一个封装管理类:

package com.kotlin.musicplayer.utils

/**
 * 标题栏管理类
 */
class ToolBarManager {

    /**
     * 初始化主界面的toolbar
     */
    fun initMainToolBar() {
        //TODO
    }
}

然后这里就跟Java不同的地方出来了,看好了,这里面可以定义一个Toolbar的引用:

但是,很明显这个Toolbar的初始化应该交由子类来提供,只有具体的界面才知道是什么样的Toolbar,所以为了不让它报错,可以将它声明成一个接口,此时val的变量就不需要强制初始化而转由子类来进行:

有了Toolbar的引用,接下来咱们就可以在初始化方法中设置一下主界面的标题:

设置标题:

接下来则可以在MainActivity来实现这个接口并对Toolbar进行初始化,具体如下:

此时就需要来初始化val的变量了:

属性重写可以参考:https://www.cnblogs.com/webor2006/p/11203903.html,这里打算用延迟初始化来提高程序的性能,怎么做?

此时看一下lazy函数:

所以为啥咱们调用是这样的:

另外,貌似之前咱们在学习Kotlin语言时还有一个延迟初始化的方式:

那这俩延迟初始化有啥区别呢?可以参考博主:https://www.jianshu.com/p/e2cb4c65d4ff,简单来说是lazyinit只能用到var的变量,而by lazy只能用于val的变量,而关于var和val有啥区别这里就不多说了,最最基础的了,接下来咱们则可以调用初始化方法了,如下:

运行:

另外咱们来打印一下日志,看一下lazy()函数的调用确实是在我们使用了Toolbar之后才执行的么?

 

运行看一下日志输出:

嗯,确实是!!

增加设置菜单:

接下来还需要给右侧增加一个设置菜单,如下:

其中用到一个图片:

它其实长这样:

此时可以在IDE上预览一下效果:

 

那此时需要再设置一个属性才行:

 

此时咱们再运行看一下:

设置菜单点击事件处理:

接下来给菜单增加一个点击事件:

其中这里又得复习一下相关语法了-----对象表达式(Object expression),关于这块可以参考:https://www.cnblogs.com/webor2006/p/11352421.html,关于它的作用可以大致回顾一下:

也就是在Koltin对于匿名内部类是采用对象表达式的形式来代替的,接下来咱们先来处理点击逻辑,这里先打个toast看一下:

在Kotlin中木有switch关键字,这里是用的when关键字,而关于它的用法可以参考:https://www.cnblogs.com/webor2006/p/11186089.html,其中它还简化的写法:

 

运行看一下:

另外对于这个事件监听代码在IDE上已经有一个标黄的提示了,很明显是有更加优化的写法:

用IDE的向导提示来修改一下,此时代码就精简为:

看一下这个回调接口的定义:

其实还可以进一步精简,这里就涉及到Kotlin调用Java的小细节了,“如果Java接口中只有一个未实现的方法,可以省略接口对象,直接用{}表示未实现的方法”,也就是:

其实这个规则就是Kotlin关于参数是Lambda表达式时直接可以用花括号来进行调用的差不多,回忆一下:

好,逻辑了这么多关于语法的知识,目的就是为了巩固Kotlin的语法,只有这样才会对Kotlin掌握得更加得熟练,接下来则需要点击跳转到一个设置界面,所以下面来准备一下:

package com.kotlin.musicplayer.ui.activity

import com.kotlin.musicplayer.R
import com.kotlin.musicplayer.base.BaseActivity

/**
 * 设置界面
 */
class SettingsActivity : BaseActivity() {

    override fun getLayoutId(): Int {
        return R.layout.activity_settings
    }
}
<?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"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="settings" />

</LinearLayout>

然后点击时跳转一下,这里又有一个Koltin的语法出来了:

其中这里获取Class时后面跟了一个.java,原因是我们的每个Activity继承的是一个Java的Activity,而非Kotlin的,如下:

 

而要获取对应Java的class类就需要用这种语法,关于这块可以参考:https://www.cnblogs.com/webor2006/p/11571472.html

好,接下来运行看一下设置界面:

设置界面处理:

接下来则来对设置界面进行调整,先展示一下预期的效果图:

标题处理:

先来修改toolbar,照之前主界面的toolbar的写法来:

<?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"
    android:orientation="vertical">

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

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="settings" />
</LinearLayout>
package com.kotlin.musicplayer.ui.activity

import androidx.appcompat.widget.Toolbar
import com.kotlin.musicplayer.R
import com.kotlin.musicplayer.base.BaseActivity
import com.kotlin.musicplayer.utils.ToolBarManager
import org.jetbrains.anko.find

/**
 * 设置界面
 */
class SettingsActivity : BaseActivity(), ToolBarManager {

    override fun getLayoutId(): Int {
        return R.layout.activity_settings
    }

    override val toolbar by lazy { find<Toolbar>(R.id.toolbar) }

    override fun initData() {
        super.initData()
        initSettingsToolBar()
    }
}

运行看下效果:

 

设置项处理:

这里采用PreferenceFragment来构造咱们的设置项,所以新建一个Fragment:

package com.kotlin.musicplayer.ui.fragment

import android.os.Bundle
import android.preference.PreferenceFragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.kotlin.musicplayer.R


/**
 * 设置项
 */
class SettingsFragment: PreferenceFragment() {
    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        addPreferencesFromResource(R.xml.setting)
        return super.onCreateView(inflater, container, savedInstanceState)
    }
}

其中配置项是在xml中:

 

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <Preference
        android:key="clear_cache"
        android:title="清除缓存" />
    <SwitchPreference
        android:key="push"
        android:title="推送通知" />
    <SwitchPreference
        android:key="no_wifi"
        android:title="非wifi下加载图片" />
    <Preference
        android:key="about"
        android:title="关于" />
</PreferenceScreen>

然后将其声明到Activity布局当中:

运行看一下效果:

使用PreferenceFragment的好处就是对于配置的开关就不需要咱们自己来写了,它里面已经为我们处理好了,下面咱们来读取一下开关状态,看是否能正常的读取出来:

package com.kotlin.musicplayer.ui.activity

import android.preference.PreferenceManager
import androidx.appcompat.widget.Toolbar
import com.kotlin.musicplayer.R
import com.kotlin.musicplayer.base.BaseActivity
import com.kotlin.musicplayer.utils.ToolBarManager
import org.jetbrains.anko.find

/**
 * 设置界面
 */
class SettingsActivity : BaseActivity(), ToolBarManager {

    override fun getLayoutId(): Int {
        return R.layout.activity_settings
    }

    override val toolbar by lazy { find<Toolbar>(R.id.toolbar) }

    override fun initData() {
        super.initData()
        initSettingsToolBar()
        println("push checked:" + PreferenceManager.getDefaultSharedPreferences(this).getBoolean("push", false))
    }
}

其中SP的key则是在xml中配置的:

运行一下:

接下来需要处理“关于”的点击事件,简单处理下:

/**
 * 设置项
 */
class SettingsFragment : PreferenceFragment() {
    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        addPreferencesFromResource(R.xml.setting)
        return super.onCreateView(inflater, container, savedInstanceState)
    }

    override fun onPreferenceTreeClick(preferenceScreen: PreferenceScreen?, preference: Preference?): Boolean {
        val key = preference?.key
        if ("about".equals(key)) {
            //点击了关于
            activity.startActivity(Intent(activity, AboutActivity::class.java))
        }
        return super.onPreferenceTreeClick(preferenceScreen, preference)
    }
}

package com.kotlin.musicplayer.ui.activity

import com.kotlin.musicplayer.R
import com.kotlin.musicplayer.base.BaseActivity


/**
 * 关于页面
 */
class AboutActivity : BaseActivity() {
    override fun getLayoutId(): Int {
        return R.layout.activity_about
    }
}
<?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"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="这是一款免费的Kotlin视频播放器" />
</LinearLayout>

运行:

原文地址:https://www.cnblogs.com/webor2006/p/12637282.html