• 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的项目实战先到这,水滴石穿~~

  • 相关阅读:
    继续OI
    [WARNING]考前必读?!
    近些日的总结吧
    续上文
    又是一年NOIP然鹅我考的是高数(虽然我没打并且内容与NOIP无关)(手动滑稽)
    轮船问题(DP基础)
    NOIP2016报零记
    字符数组
    HA-0302 退役
    各种模板(part 2)
  • 原文地址:https://www.cnblogs.com/webor2006/p/12622874.html
Copyright © 2020-2023  润新知