栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

android

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

android

代码重构之美

随着代码量增多,越来越觉得有必要构建fragment基类,今天实在受不了,于是重构开始…

注入viewmodel

实际上是要真正意义上对viewmodel进行自动注入的,由于我使用的是viewmodelFactory需要传参所以这里没有实现注入

baseVmFragment.kt

package com.example.module_main.base

import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel

//虽然没法注入viewmodel但是可以使写法一眼知道碎片对应的ViewModel是什么
abstract class baseVmFragment: Fragment() {
    //这里的VM并没有实际意义,没有使用到,仅仅用于可观性,让人一眼就知道碎片所对应的viewmodel
    lateinit var mActivity: AppCompatActivity


    //这个属性用来是否处理 使用jetpack navigation组件导航后,fragment是否重新执行onCreateView方法,重新执行就要重新初始化,之前初始化的状态丢失
    abstract var isHandleFragmentAgainOnCreateView: Boolean

    protected var isNavigationViewInit = false//记录是否已经初始化过一次视图
    protected var lastView: View? = null//记录上次创建的view

    //在Fragment直接只用getActivity()获得上下文有时会得到空引用,所以需要重写onAttach方法拿到上下文
    override fun onAttach(context: Context) {
        super.onAttach(context)
        mActivity = activity as AppCompatActivity
        onFragmentAttach()
    }

    
    abstract fun onFragmentAttach()

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? = inflater.inflate(layoutId(),container,false)

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        if(isHandleFragmentAgainOnCreateView){
            if(!isNavigationViewInit){
                init(savedInstanceState)
                isNavigationViewInit = true
            }
        }else{
            init(savedInstanceState)
        }
    }



    fun init(savedInstanceState: Bundle?){

        initBeforeBinding(savedInstanceState)
        initBinding(savedInstanceState)
        initAfterBinding(savedInstanceState)
    }

    
    abstract fun initAfterBinding(savedInstanceState: Bundle?)

    
    abstract fun initBeforeBinding(savedInstanceState: Bundle?)

    
    abstract fun initBinding(savedInstanceState: Bundle?)


    
    abstract fun layoutId(): Int
}

注入DataBinding

baseVmDbFragment.kt

package com.example.module_main.base

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.ViewModel

//自动注入viewmodel和databinding
abstract class baseVmDbFragment : baseVmFragment() {
    private var _binding: DB? = null
    val mBinding: DB get() = _binding!!

    //这个属性用来是否处理 使用jetpack navigation组件导航后,fragment是否重新执行onCreateView方法,重新执行就要重新初始化,之前初始化的状态丢失
    abstract override var isHandleFragmentAgainOnCreateView: Boolean


    //注意这里重写方法会直接覆盖baseVmFragment,因此不用担心baseVmFragme里onCreateView方法下实现的方法有影响
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        if (isHandleFragmentAgainOnCreateView) {
            //通过这种方式解决解决Android jetpack导航组件Navigation返回Fragment重走onCreateView方法刷新视图的问题
            if (lastView == null) {
                _binding = DataBindingUtil.inflate(inflater, layoutId(), container, false)
                //mBinding.lifecycleOwner = this
                // 因为这里和数据相关联着,所以这行一定要注释,否则会出现崩溃,这行正确做法应该放到onViewCreated()方法中!!!
                lastView = mBinding.root
            }
            return lastView
        } else {
            _binding = DataBindingUtil.inflate(inflater, layoutId(), container, false)
            mBinding.lifecycleOwner = this
            lastView = mBinding.root
            return lastView
        }



    }


    override fun onDestroy() {
        super.onDestroy()
        onFragmentDestroy()
        _binding = null
    }

    //- - - 注意以下两个方法除非是特殊需要否则直接覆盖后不执行操作即可!!!之所以把方法暴露出来是为了防止有特殊需求 ^.^

    
    abstract fun onFragmentDestroy()

    
    abstract override fun onFragmentAttach()

}
fragment基类的创建

baseFragment.kt

package com.example.module_main.base

import android.os.Bundle
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.ViewModel

//创建这个类没有实际作用,主要就是为了看起来好看,暴露所有需要或者重要的方法给使用者看, 老强迫症了
abstract class baseFragment: baseVmDbFragment(){
    //- - - 注意以下onFragmentDestroy和onFragmentAttach两个方法通常覆盖后不操作!!!   之所以把方法暴露出来是为了防止有特殊需求 ^.^
    //- - - layoutId方法必须覆盖!!!


    
    abstract override var isHandleFragmentAgainOnCreateView: Boolean

    
    abstract override fun onFragmentDestroy()

    
    abstract override fun onFragmentAttach()

    
    abstract override fun layoutId(): Int


    
    abstract override fun initBeforeBinding(savedInstanceState: Bundle?)

    
    abstract override fun initBinding(savedInstanceState: Bundle?)

    
    abstract override fun initAfterBinding(savedInstanceState: Bundle?)
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/328810.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号