一.代码详解MVVM模式
1.代码截图
2.代码
model层
class PlatformModel { /** * 获取平台信息1 * 举例:数据库查询返回正常实体类 * */ fun getPlatformInfo1(dao: PlatformDao, platformId: String) = flow { try { val dbPlatformEntity = dao.queryByUserId(platformId) val platform = fromJson2Bean(fromObject2Json(dbPlatformEntity), Platform::class.java) platform.localId = dbPlatformEntity.id.toString() delay(3000.milliseconds)//模拟加载中 emit(platform) } catch (e: Exception) { throw e } } /** * 获取平台信息2 * 举例:数据库查询返回Flow * */ fun getPlatformInfo2(dao: PlatformDao, platformId: String) = flow { try { dao.queryByUserIdFlow(platformId) .collect { dbPlatform -> val platform = fromJson2Bean(fromObject2Json(dbPlatform), Platform::class.java) platform.localId = dbPlatform.id.toString() delay(3000.milliseconds)//模拟加载中 emit(platform) } } catch (e: Exception) { throw e } } }View层
class KotlinFlowActivity1 : CoroutineBaseActivity() { private val platformId: String = "platformId123456" private val platformDao = RoomManager.impl.platformDao() private val viewModel by viewModels<PlatformViewModel>() private lateinit var queryTextView1: TextView private lateinit var queryTextView2: TextView private lateinit var queryTextView3: TextView private lateinit var queryTextView4: TextView private lateinit var textView: TextView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_flow1) queryTextView1 = findViewById(R.id.flow_tv1) queryTextView1.setOnClickListener { query1() } queryTextView2 = findViewById(R.id.flow_tv2) queryTextView2.setOnClickListener { query2() } queryTextView3 = findViewById(R.id.flow_tv3) queryTextView3.setOnClickListener { query3() } queryTextView4 = findViewById(R.id.flow_tv4) queryTextView4.setOnClickListener { query4() } textView = findViewById(R.id.flow_content) } /** * 查询1 * */ private fun query1() { viewModel.getPlatformInfo1(platformDao, platformId, object : PlatformViewModel.ICallback { override fun onStart(msg: String) { textView.text = msg } @SuppressLint("SetTextI18n") override fun onComplete(platform: Platform, errorMsg: String) { textView.text = "平台信息1:\n" + fromObject2Json(platform) } }) } /** * 查询2 * */ private fun query2() { viewModel.getPlatformInfo3(platformDao, platformId, object : PlatformViewModel.ICallback { override fun onStart(msg: String) { textView.text = msg } @SuppressLint("SetTextI18n") override fun onComplete(platform: Platform, errorMsg: String) { textView.text = "平台信息2:\n" + fromObject2Json(platform) } }) } /** * 查询3 * */ private fun query3() { } /** * 查询4 * */ private fun query4() { } }ViewModel层
class PlatformViewModel : ViewModel() { private val platformModel = PlatformModel() /** * 获取平台信息1 * */ fun getPlatformInfo1(dao: PlatformDao, platformId: String, callback: ICallback) { viewModelScope.launch { callback.onStart("数据加载中...") platformModel.getPlatformInfo1(dao, platformId) .flowOn(Dispatchers.IO)//指定操作运行在IO线程 .catch { exception ->//异常处理 callback.onComplete(Platform(), exception.message.toString()) } .collect { platform ->//collect方法自动切换到主线程接收数据 callback.onComplete(platform, "获取成功") } } } /** * 获取平台信息2 * */ fun getPlatformInfo3(dao: PlatformDao, platformId: String, callback: ICallback) { viewModelScope.launch { callback.onStart("数据加载中...") platformModel.getPlatformInfo2(dao, platformId) .flowOn(Dispatchers.IO)//指定操作运行在IO线程 .catch { exception ->//异常处理 callback.onComplete(Platform(), exception.message.toString()) } .collect { platform ->//collect方法自动切换到主线程接收数据 callback.onComplete(platform, "获取成功") } } } /** * 回调 * */ interface ICallback { fun onStart(msg: String){} fun onComplete(platform: Platform, errorMsg: String) {} } }3.结果
二.Flow流实现实时搜索功能(去重&防抖)
1.说明
项目中常常用到,EditText实时输入搜索显示一个搜索结果(某个列表)。要是不做任何处理的话,可能会有几个问题。
问题1:比如实时输入hello,就会请求接口5次,h时请求一次,he时请求一次,hel时请求一次,hell时请求一次,hello时请求一次,造成不必要的请求,所以需要防抖操作。
问题2:也有可能出现输入了hello后,输入框实时变成其他的,然后又变成hello。这样也会造成重复请求。
那么,Flow流是怎么做到的呢?下面通过例子说明一下。
2.代码
3.结果