Kotlin項目實戰之手機影音---基類抽取、歡迎界面、抽取startactivityandfinish、主界面布局


基類抽取:

在上一次https://www.cnblogs.com/webor2006/p/12612286.html搭建了項目的基本框架,接下來則繼續往上磊代碼了,先來創建一個每個項目都必有的BaseActivity,這里跟Java的Android差不多的就不多解釋了,重點是解釋Kotlin相關的:

package com.kotlin.musicplayer.base

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

/**
 * Activity抽象基類
 */
abstract class BaseActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(getLayoutId())
        initListeners()
        initData()
    }

    protected fun initData() {

    }

    protected fun initListeners() {

    }

    protected abstract fun getLayoutId(): Int
}

其本上寫法跟傳統的Java差不多,再加上IDE的智能提示,寫起來貌似沒感到跟Java有太大的區別,之后遇到區別時再解釋,對於Toast和Log的輸出可以將其也封裝到這個Base里,此時anko庫就派上用場了,先看一下Toast的用法:

直接調用不就好了,干嘛還要封裝一下?因為沒有處理線程的問題,所以下面先封裝一下它:

這里有個Kotlin的語法來了:

具體原因可以參考:https://www.cnblogs.com/webor2006/p/11498842.html,Kotlin語法規則有一條是這樣說的:

而回到咱們這個方法的定義來看:

所以就符合這條規則了,另外看一下這個toast的具體實現:

這里函數的定義又涉及到好幾個Kotlin的語法了:它是Context類中的一個擴展方法:

另外這種直接將方法的使用用=號相連是個啥語法呢?

另外這里還用了一個關鍵字:

它叫內聯函數,可以參考https://www.cnblogs.com/webor2006/p/11518592.html

也就是我們在調用內聯函數時,並非單純的函數調用,而是將被調用函數的代碼直接嵌在了我們調用處。好接下來再來封裝一下BaseFragment:

package com.kotlin.musicplayer.base

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import org.jetbrains.anko.runOnUiThread
import org.jetbrains.anko.toast

/**
 * Fragment基類
 */
abstract class BaseFragment : Fragment() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initData();
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return initView()
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        initListeners()
        initData()
    }

    protected fun initData() {

    }

    protected fun initListeners() {

    }

    protected fun showToast(msg: String) {
        context?.runOnUiThread { toast(msg) }
    }

    protected abstract fun initView(): View?
}

歡迎界面:

有了基礎Activity的封裝之后,下面則來首先實現Splash頁面,先來回顧一下效果:

其背景圖如下:

package com.kotlin.musicplayer.ui.activity

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

class SplashActivity : BaseActivity() {
    override fun getLayoutId(): Int {
        return R.layout.activity_splash
    }
}

<?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">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:src="@mipmap/default_splash_bg" />
</LinearLayout>

此時運行看一下:

此時含有狀態欄,得將其隱藏掉,所以得定義個全屏的主題:

接下來需要處理動畫效果,其實就是讓圖片先放大一下,然后之后將其縮小成正常大小就可以了,比較簡單,默認先在定義圖片時將其放大一下:

接下來則需要處理縮小動畫,此時需要覆寫一下父類的initData()方法:

發現在子類中覆寫不了,這時Kotlin的語法就又出來了,在之前也提及過,可以參考https://www.cnblogs.com/webor2006/p/11203903.html,其實要想讓子類覆寫,必須加個open關鍵字:

接下來則需要跳到MainActivity了,這里跳轉依然可以使用anko庫,能大大簡化調用代碼,使用方式如:

所以咱們使用一下:

此時運行看一下效果:

抽取startactivityandfinish:

對於這句代碼可能未來也有需要調用:

所以可以將其提到父類中進行封裝一下:

很明顯這個抽取是有問題的:

關於泛型這塊可以參考:https://www.cnblogs.com/webor2006/p/11296775.html,這里來修改一下:

此時就需要看一下startActivity這個函數的泛型定義了:

這里先不管這么多,先來校仿着定義一下:

 

 

果真是可以了,下面咱們來調用一下:

那么對於reified關健字的作用,可以參考博主:https://www.jianshu.com/p/bbe694b2c0a8,其實也就是要想通過泛型來獲取到對應的class就必須加這個關鍵字,下面咱們舉個例子:

此時就需要使用reified修飾並變成內聯函數才行:

主界面布局:

接下來則來編寫主界面了,它的效果長這樣:

 

這里先來搭建一下界面框架,具體邏輯之后再慢慢實現,首先准備布局文件:

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="@color/colorPrimary"
    android:orientation="vertical"
    app:titleTextColor="#fff" />

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"
    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" />
</LinearLayout>

接下來則需要定義底部Tab了,這里使用一個三方的庫:https://github.com/roughike/BottomBar

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen>
    <tab
        icon="@mipmap/ic_bottom_home_icon"
        id="@+id/tab_home"
        title="首頁" />
    <tab
        icon="@mipmap/ic_bottom_mv_unselect"
        id="@+id/tab_mv"
        title="MV" />
    <tab
        icon="@mipmap/ic_bottom_vlist_unselect"
        id="@+id/tab_vbang"
        title="V榜" />
    <tab
        icon="@mipmap/ic_bottom_mvlist_unselect"
        id="@+id/tab_yuedan"
        title="悅單" />
</PreferenceScreen>

上面的文本直接寫在xml中而木有提至strings.xml了,因為是一個練習項目,重點是操練kotlin,這些細節就暫且忽略上,其中涉及到四張小icon,按順序今次為:

此時運行看一下整體效果:

呃,底部的圖標也太大了點吧,跟預期效果相差很多,這里其實就是要針對不同分辨率文件夾弄幾套對應的圖就可以了,如下:

具體就不多說了,最后再運行:

好,今天Kotlin的項目實戰先到這,水滴石穿~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM