项目作者: SamiuZhong

项目描述 :
MVVM架构的真Material Design版玩Android客户端
高级语言: Kotlin
项目地址: git://github.com/SamiuZhong/WanAndroid_Gank.git


WanAndroidGanK

玩Android大家都很熟悉了,是鸿洋大佬的一个开源知识网站,目前基于玩Android开源API的各种版本APP多如过江之鲫。

那么经过一段时间的潜心修炼,今天给大家带来了一个从未有过的全新版本。

设计

这次的UI整体是根据Google官方的设计,参照Material Design的风格整粗来的。

下面我们先来看看效果图

底部导航栏的展开动画

滑动收藏文章

技术

技术方面采用的是Kotlin语言实现,整体架构为MVVM。

Model

Model包含本地和网络数据仓库,本地数据使用ROOM交互,网络数据使用Retrofit配合协程调用接口

  1. class WanHomeRepository : BaseWanRepository() {
  2. suspend fun getBanners(): WanResult<List<Banner>> {
  3. return readyCall(
  4. call = {
  5. call(WanClient.service.getBanner())
  6. }, errorMessage = NETWORK_ERROR
  7. )
  8. }
  9. suspend fun getArticlesList(page: Int): WanResult<ArticleList> {
  10. return readyCall(
  11. call = {
  12. call(WanClient.service.getHomeArticles(page))
  13. }, errorMessage = NETWORK_ERROR
  14. )
  15. }
  16. }

ViewModel

ViewModel持有Model层,在协程的作用域内与Model进行交互

  1. class WanHomeViewModel(
  2. private val wanHomeRepository: WanHomeRepository
  3. ) : ViewModel() {
  4. val mArticles = MutableLiveData<List<Article>>()
  5. val mBanners = MutableLiveData<List<Banner>>()
  6. fun getBanners() = viewModelScope.launch {
  7. val data = wanHomeRepository.getBanners()
  8. if (data is WanResult.Success)
  9. mBanners.value = data.data
  10. }
  11. fun getArticles(page: Int) = viewModelScope.launch {
  12. val articleList = wanHomeRepository.getArticlesList(page)
  13. if (articleList is WanResult.Success)
  14. mArticles.value = articleList.data.datas
  15. }
  16. }

View

View层即为我们熟悉的Activity和Fragment,通过注入的方式持有ViewModel,调用ViewModel的方法获取数据之后再通过LiveData通知界面进行刷新。

  1. class WanHomeFragment : BaseFragment(R.layout.fragment_wan_home) {
  2. private val binding by viewBinding(FragmentWanHomeBinding::bind)
  3. private val viewModel: WanHomeViewModel by viewModel()
  4. ...
  5. override fun initData() {
  6. viewModel.getBanners()
  7. binding.refreshLayout.autoRefresh()
  8. }
  9. override fun startObserve() = viewModel.run {
  10. mBanners.observe(this@WanHomeFragment, Observer { setBanner(it) })
  11. mArticles.observe(this@WanHomeFragment, Observer { mAdapter.addAll(it) })
  12. }
  13. }

更多实现请clone查看。