android mvvm实例解析

class ChooseAreaFragment : Fragment() {
private val viewModel by lazy { ViewModelProviders.of(this, InjectorUtil.getChooseAreaModelFactory()).get(ChooseAreaViewModel::class.java) }
private var progressDialog: ProgressDialog? = null
private lateinit var adapter: ArrayAdapter<String>
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.choose_area, container, false)
val binding = DataBindingUtil.bind<ChooseAreaBindingImpl>(view)
binding?.viewModel = viewModel
return view
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
adapter = ChooseAreaAdapter(context!!, R.layout.simple_item, viewModel.dataList)
listView.adapter = adapter
observe()
}
private fun observe() {
viewModel.currentLevel.observe(this, Observer { level ->
when (level) {
LEVEL_PROVINCE -> {
titleText.text = "中国"
backButton.visibility = View.GONE
}
LEVEL_CITY -> {
titleText.text = viewModel.selectedProvince?.provinceName
backButton.visibility = View.VISIBLE
}
LEVEL_COUNTY -> {
titleText.text = viewModel.selectedCity?.cityName
backButton.visibility = View.VISIBLE
}
}
})
viewModel.dataChanged.observe(this, Observer {
adapter.notifyDataSetChanged()
listView.setSelection(0)
closeProgressDialog()
})
viewModel.isLoading.observe(this, Observer { isLoading ->
if (isLoading) showProgressDialog()
else closeProgressDialog()
})
viewModel.areaSelected.observe(this, Observer { selected ->
if (selected && viewModel.selectedCounty != null) {
if (activity is MainActivity) {
val intent = Intent(activity, WeatherActivity::class.java)
intent.putExtra("weather_id", viewModel.selectedCounty!!.weatherId)
startActivity(intent)
activity?.finish()
} else if (activity is WeatherActivity) {
val weatherActivity = activity as WeatherActivity
weatherActivity.drawerLayout.closeDrawers()
weatherActivity.viewModel.weatherId = viewModel.selectedCounty!!.weatherId
weatherActivity.viewModel.refreshWeather()
}
viewModel.areaSelected.value = false
}
})
if (viewModel.dataList.isEmpty()) {
viewModel.getProvinces()
}
}
/**
* 显示进度对话框
*/
private fun showProgressDialog() {
if (progressDialog == null) {
progressDialog = ProgressDialog(activity)
progressDialog?.setMessage("正在加载...")
progressDialog?.setCanceledOnTouchOutside(false)
}
progressDialog?.show()
}
/**
* 关闭进度对话框
*/
private fun closeProgressDialog() {
progressDialog?.dismiss()
}
companion object {
const val LEVEL_PROVINCE = 0
const val LEVEL_CITY = 1
const val LEVEL_COUNTY = 2
}
}
class ChooseAreaViewModel(private val repository: PlaceRepository) : ViewModel() {
var currentLevel = MutableLiveData<Int>()
var dataChanged = MutableLiveData<Int>()
var isLoading = MutableLiveData<Boolean>()
var areaSelected = MutableLiveData<Boolean>()
var selectedProvince: Province? = null
var selectedCity: City? = null
var selectedCounty: County? = null
lateinit var provinces: MutableList<Province>
lateinit var cities: MutableList<City>
lateinit var counties: MutableList<County>
val dataList = ArrayList<String>()
fun getProvinces() {
currentLevel.value = LEVEL_PROVINCE
launch {
provinces = repository.getProvinceList()
dataList.addAll(provinces.map { it.provinceName })
}
}
private fun getCities() = selectedProvince?.let {
currentLevel.value = LEVEL_CITY
launch {
cities = repository.getCityList(it.provinceCode)
dataList.addAll(cities.map { it.cityName })
}
}
private fun getCounties() = selectedCity?.let {
currentLevel.value = LEVEL_COUNTY
launch {
counties = repository.getCountyList(it.provinceId, it.cityCode)
dataList.addAll(counties.map { it.countyName })
}
}
fun onListViewItemClick(parent: AdapterView<*>, view: View, position: Int, id: Long) {
when {
currentLevel.value == LEVEL_PROVINCE -> {
selectedProvince = provinces[position]
getCities()
}
currentLevel.value == LEVEL_CITY -> {
selectedCity = cities[position]
getCounties()
}
currentLevel.value == LEVEL_COUNTY -> {
selectedCounty = counties[position]
areaSelected.value = true
}
}
}
fun onBack() {
if (currentLevel.value == LEVEL_COUNTY) {
getCities()
} else if (currentLevel.value == LEVEL_CITY) {
getProvinces()
}
}
private fun launch(block: suspend () -> Unit) = viewModelScope.launch {
try {
isLoading.value = true
dataList.clear()
block()
dataChanged.value = dataChanged.value?.plus(1)
isLoading.value = false
} catch (t: Throwable) {
t.printStackTrace()
Toast.makeText(CoolWeatherApplication.context, t.message, Toast.LENGTH_SHORT).show()
dataChanged.value = dataChanged.value?.plus(1)
isLoading.value = false
}
}
}
class PlaceRepository private constructor(private val placeDao: PlaceDao, private val network: CoolWeatherNetwork) {
suspend fun getProvinceList() = withContext(Dispatchers.IO) {
var list = placeDao.getProvinceList()
if (list.isEmpty()) {
list = network.fetchProvinceList()
placeDao.saveProvinceList(list)
}
list
}
suspend fun getCityList(provinceId: Int) = withContext(Dispatchers.IO) {
var list = placeDao.getCityList(provinceId)
if (list.isEmpty()) {
list = network.fetchCityList(provinceId)
list.forEach { it.provinceId = provinceId }
placeDao.saveCityList(list)
}
list
}
suspend fun getCountyList(provinceId: Int, cityId: Int) = withContext(Dispatchers.IO) {
var list = placeDao.getCountyList(cityId)
if (list.isEmpty()) {
list = network.fetchCountyList(provinceId, cityId)
list.forEach { it.cityId = cityId }
placeDao.saveCountyList(list)
}
list
}
companion object {
private var instance: PlaceRepository? = null
fun getInstance(placeDao: PlaceDao, network: CoolWeatherNetwork): PlaceRepository {
if (instance == null) {
synchronized(PlaceRepository::class.java) {
if (instance == null) {
instance = PlaceRepository(placeDao, network)
}
}
}
return instance!!
}
}
}
android mvvm实例解析的更多相关文章
- 【转】Android HAL实例解析
原文网址:http://www.embedu.org/Column/Column339.htm 作者:刘老师,华清远见嵌入式学院讲师. 一.概述 本文希望通过分析台湾的Jollen的mokoid 工程 ...
- Android HAL实例解析
一.概述 本文希望通过分析台湾的Jollen的mokoid 工程代码,和在s5pc100平台上实现过程种遇到的问题,解析Andorid HAL的开发方法. 二.HAL介绍 现有HAL架构由Patric ...
- Android AIDL实例解析
AIDL这项技术在我们的开发中一般来说并不是很常用,虽然自己也使用新浪微博的SSO登录,其原理就是使用AIDL,但是自己一直没有动手完整的写过AIDL的例子,所以就有了这篇简单的文章. AIDL(An ...
- Android实例-Delphi开发蓝牙官方实例解析(XE10+小米2+小米5)
相关资料:1.http://blog.csdn.net/laorenshen/article/details/411498032.http://www.cnblogs.com/findumars/p/ ...
- Android开发之IPC进程间通信-AIDL介绍及实例解析
一.IPC进程间通信 IPC是进程间通信方法的统称,Linux IPC包括以下方法,Android的进程间通信主要采用是哪些方法呢? 1. 管道(Pipe)及有名管道(named pipe):管道可用 ...
- Android Service完全解析,关于服务你所需知道的一切(上)
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11952435 相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的A ...
- [转] Android Volley完全解析(一),初识Volley的基本用法
版权声明:本文出自郭霖的博客,转载必须注明出处. 目录(?)[-] Volley简介 下载Volley StringRequest的用法 JsonRequest的用法 转载请注明出处:http ...
- Android IntentService完全解析 当Service遇到Handler
一 概述 大家都清楚,在Android的开发中,凡是遇到耗时的操作尽可能的会交给Service去做,比如我们上传多张图,上传的过程用户可能将应用置于后台,然后干别的去了,我们的Activity就很可能 ...
- Android Volley完全解析
1. Volley简介 我们平时在开发Android应用的时候不可避免地都需要用到网络技术,而多数情况下应用程序都会使用HTTP协议来发送和接收网络数据.Android系统中主要提供了两种方式来进行H ...
- Android Bitmap 全面解析(四)图片处理效果对比 ...
对比对象: UIL Volley 官方教程中的方法(此系列教程一里介绍的,ImageLoader的处理方法和官方的差不多) -------------------------------------- ...
随机推荐
- SV 数据类型-3
联合数组 在内存中分配的空间可以是不连续的 联合数组方法 数组的方法 数组使用推荐 结构体 枚举类型 字符串变量类型String 操作符
- [转帖]查询 HTTPS 网站 TLS 版本
参考 检查网站的TLS版本 – wentao's blog Linux curl 命令详解 - 腾讯云开发者社区-腾讯云 TLS 版本查询_天泽岁月的博客-CSDN博客_查看tls版本 使用 Open ...
- [转帖]【SQL SERVER】锁机制
https://www.cnblogs.com/WilsonPan/p/12618849.html 锁定是 SQL Server 数据库引擎用来同步多个用户同时对同一个数据块的访问的一种机制. 基 ...
- [转帖]查看mysql分区名和各分区数据量
– 查看mysql分区名和各分区数据量 SELECT table_name, partition_name, table_rows FROM information_schema.PARTITIONS ...
- Tidb 使用minio 进行br备份数据库的过程
Tidb 使用minio 进行br备份数据库的过程 背景 br 备份恢复时一般需要共享存储. 前段时间一直使用的是nfs 进行共享文件备份. 这样需要所有的机器在 相同的目录下面挂载相同的nfs. 并 ...
- [转帖]goproxy 使用说明
Go 版本要求 建议您使用 Go 1.13 及以上版本, 可以在这里下载最新的 Go 稳定版本. 配置 Goproxy 环境变量 Bash (Linux or macOS) export GOPROX ...
- 【转帖】route命令详解大全(route命令使用实例)
https://www.cxdtop.cn/n/225987.html 在实际的网络应用中,我们可能会遇到这样的网络环境,上外网我们使用的无线网络,内网我们使用的是有限网卡.在设置完成后会出现外网和内 ...
- 浅浅的源码剖析grpc-go(一)
最近在学习 rpc 相关的知识,如果让我去从头设计一个 rpc,我从使用者的角度出发,究竟需要去做一下什么工作? 第一,RPC 本质上就是一个远程调用,那肯定就需要通过网络来传输数据.虽然传输协议可以 ...
- 【0基础学爬虫】爬虫基础之自动化工具 Playwright 的使用
大数据时代,各行各业对数据采集的需求日益增多,网络爬虫的运用也更为广泛,越来越多的人开始学习网络爬虫这项技术,K哥爬虫此前已经推出不少爬虫进阶.逆向相关文章,为实现从易到难全方位覆盖,特设[0基础学爬 ...
- 用Unity3D做游戏开发在Android上的常用调试方法
Hdg Remote Debug 远程调试 游戏运行在手机上,可以通过pc端的unity来随时修改当前场景中GameObject的变量,从而改变手机上运行时的表现.比如,我可以勾掉下图中的" ...