JetPack控件LifeCycles(基于android-sunflower-0.1.6)

前言:

开始前我们先回答几个问题

1.Jetpack是什么/怎么用?
2.android-sunflower-0.1.6是什么?

问题一:

  1. Jetpack是什么?
    *给出下图:*简单的概括为四大组件库,可以看到他提供的功能还是蛮实用的,没有多余的部分。
    是什么
  2. Jetpack怎么用?
    这个问题比较大一下说不清楚,我们从接下来的源码分析中,一步一步理解和掌握,有人会说既然做这么多年开发直接看文档不就能行了吗,你说的有道理,但是阅读外文文档学习确实不符合中国国情,这里就涉及到个人以及政治方面的原因了。也可以看到上面的模块之多,不是一日而语的,纸上读来终觉浅,绝知此事要躬行,我们需要慢慢来,我也是第一次在技术迁移上感受到这种焦虑感,Kotlin在Android开发当中的比重越来越大,还在使用JAVA的伙伴赶紧跟上脚步。

问题二:
长征第一步
地址:https://github.com/googlesamples/android-sunflower
--------------------------------------进入正题---------------------------------------
衔接上篇
JetPack控件NavigationUI(基于android-sunflower-0.1.6)

LifeCycles +LiveData

坐标 :PlantDetailFragment

//获取跳转参数,应该在Navigation篇就讲的
val plantId = PlantDetailFragmentArgs.fromBundle(arguments).plantId

//最终获取一个ViewModel 我们先看看PlantDetailViewModel
val factory = InjectorUtils.providePlantDetailViewModelFactory(requireActivity(), plantId)
val plantDetailViewModel = ViewModelProviders.of(this, factory)
        .get(PlantDetailViewModel::class.java)

坐标 :PlantDetailViewModel

//按照MVVM的思想,ViewModel就是关联View和Data的,即只处理数据
//有了解过SpringMVC的都知道Repository就是典型的Sql中间件,即处理Data和Sql中间类
class PlantDetailViewModel(
	//植物列表
    plantRepository: PlantRepository,
    //正在种的植物
    private val gardenPlantingRepository: GardenPlantingRepository,
    private val plantId: String
) : ViewModel() {
	//LiveData  理解为一个有生命周期的数据类型
	//有种过
    val isPlanted: LiveData<Boolean>
    val plant: LiveData<Plant>

    init {
    //看翻译  正在查询或插入中则返回空 
      /* The getGardenPlantingForPlant method returns a LiveData from querying the database. The
         * method can return null in two cases: when the database query is running and if no records
         * are found. In these cases isPlanted is false. If a record is found then isPlanted is
         * true. 
         */
    	//即查找这个植物
        val gardenPlantingForPlant = gardenPlantingRepository.getGardenPlantingForPlant(plantId)
        // 下面我们分解来看
        isPlanted = Transformations.map(gardenPlantingForPlant) { it != null }
        
        plant = plantRepository.getPlant(plantId)
    }
	//顾名思义 创建植物到花园
    fun addPlantToGarden() {
        gardenPlantingRepository.createGardenPlanting(plantId)
    }
}

可以看出来Transformations也就是一个转换函数,liveData 可以是任何类型,和Rxjava差不多。

  val liveData = Transformations.map(
                plant,
                object : Function<Plant, Any> {
                    override fun apply(input: Plant?): Any {
                        return input != null
                    }
                }
        )

坐标:InjectorUtils

fun providePlantDetailViewModelFactory(
        context: Context,
        plantId: String
    ): PlantDetailViewModelFactory {
    //获取两个数据库中间件  我们看看PlantDetailViewModelFactory
        return PlantDetailViewModelFactory(getPlantRepository(context),
                getGardenPlantingRepository(context), plantId)
    }

坐标:PlantDetailViewModelFactory

class PlantDetailViewModelFactory(
    private val plantRepository: PlantRepository,
    private val gardenPlantingRepository: GardenPlantingRepository,
    private val plantId: String
   //最终继承ViewModel
) : ViewModelProvider.NewInstanceFactory() {
	//重写方法 泛型T限定为ViewModel和它的子类
    @Suppress("UNCHECKED_CAST")
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        return PlantDetailViewModel(plantRepository, gardenPlantingRepository, plantId) as T
    }
}

查看ViewModelProvider源码可知道NewInstanceFactory的create被调用返回泛型Model

viewModel = mFactory.create(modelClass);

回到 :PlantDetailFragment

一个ViewModel的生产

//装备SQL以及其他参数
val factory = InjectorUtils.providePlantDetailViewModelFactory(requireActivity(), plantId)
//get 实例化Model 
val plantDetailViewModel = ViewModelProviders.of(this, factory)
        .get(PlantDetailViewModel::class.java)

ViewModel的应用

//等同于Databinding的双向绑定
//翻译:没有设置LifecycleOwner,将不会观察LiveData并对其进行更新,不会传播到UI。
setLifecycleOwner(this@PlantDetailFragment)
//简单使用
fab.setOnClickListener { view ->
     plantDetailViewModel.addPlantToGarden()
     Snackbar.make(view, R.string.added_plant_to_garden, Snackbar.LENGTH_LONG).show()
 }

//Observer观察者,不是Rxjava的
plantDetailViewModel.plant.observe(this, Observer { plant ->
   shareText = if (plant == null) {
       ""
   } else {
       getString(R.string.share_text_plant, plant.name)
   }
})
//
//其他写法 onChanged就知道啥意思了,
//也就是ViewModel中 plant = plantRepository.getPlant(plantId)调用后
//onChanged被触发
plantDetailViewModel.plant.observe(this, object : Observer<Plant> {
    override fun onChanged(t: Plant?) {

    }
})
//简化
 plantDetailViewModel.plant.observe(this, Observer<Plant> { })

到这里一个简单ViewModel生成和绑定页面数据操作就完成了

自己操作一下

坐标:AboutFragment

class AboutFragment : Fragment() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        val aboutViewModel = AboutViewModel()
        //新写法
        val binding = FragmentAboutBinding.inflate(inflater, container, false).apply {
            aboutModel = aboutViewModel
            setLifecycleOwner(this@AboutFragment)
            name.setOnClickListener {
                aboutViewModel.name.value = "${aboutViewModel.name.value}${Random(100).nextInt()}"
            }
            age.setOnClickListener {
                aboutViewModel.age.value = Random(100).nextInt()
            }
            //既然databinding实现了双向绑定功能,这个observe在这方面功能就比较鸡肋
            aboutViewModel.name.observe(this@AboutFragment, Observer { name ->
                Toast.makeText([email protected](), "${"名字改变$name"}", Toast.LENGTH_SHORT).show()
            })
            aboutViewModel.age.observe(this@AboutFragment, Observer { age ->
                Toast.makeText([email protected](), "${"年纪改变$age"}", Toast.LENGTH_SHORT).show()
            })
        }
        return binding.root
    }
}

坐标:AboutViewModel

class AboutViewModel(
        var name: MutableLiveData<String> =
                MutableLiveData<String>().apply { value = "much" },
        var age: MutableLiveData<Int> =
                MutableLiveData<Int>().apply { value = 18 }) : ViewModel() {
}

ROOM

https://blog.csdn.net/qq_20330595/article/details/87797828#ROOM_22

猜你喜欢

转载自blog.csdn.net/qq_20330595/article/details/87777131