BaseDemo 是Android MVVM + Retrofit + OkHttp + Coroutine 协程 + 组件化架构的Android应用开发规范化架构,通过不断的升级迭代,目前主要分为两个版本,分别为分支 MVVM+Databinding 组件化版本,分支MVVM+Databinding+Single 单体版本。旨在帮助您快速构建属于自己的APP项目架构,做到快速响应上手,另外再长期的实践经验中汇总了大量的使用工具类,主要放在了项目 lib_common
组件中,以供大家参考使用。具体使用请开发者工具自己项目需求决定选择如何使用。
Github :https://github.com/zhouhuandev/BaseDemo
Gitee(国内镜像) :https://gitee.com/shandong_zhaotai_network_sd_zhaotai/BaseDemo
如果我的付出可以换来对您的帮助的话,还请您点个start,将会是我不懈更新的动力,万分感谢。如果在使用中有任何问题,请留言
软件架构说明
interface BaseView : ILoadView, INoDataView, ITransView, INetErrView {
fun initListener()
fun initData()
fun finishActivity()
}
interface ILoadView {
//显示初始加载的View,初始进来加载数据需要显示的View
fun showInitLoadView()
//隐藏初始加载的View
fun hideInitLoadView()
}
interface INoDataView {
//显示无数据View
fun showNoDataView()
//隐藏无数据View
fun hideNoDataView()
//显示指定资源的无数据View
fun showNoDataView(@DrawableRes resid: Int)
}
interface ITransView {
//显示背景透明小菊花View,例如删除操作
fun showTransLoadingView()
//隐藏背景透明小菊花View
fun hideTransLoadingView()
}
interface INetErrView {
//显示网络错误的View
fun showNetWorkErrView()
//隐藏网络错误的View
fun hideNetWorkErrView()
}
interface BaseRefreshView {
/**
* 是否启用下拉刷新
* @param b
*/
fun enableRefresh(b: Boolean)
/**
* 是否启用上拉加载更多
*/
fun enableLoadMore(b: Boolean)
/**
* 刷新回调
* 向 ViewModel 发送刷新请求
*/
fun onRefreshEvent()
/**
* 加载更多的回调
* 向 ViewModel 发送加载更多请求
*/
fun onLoadMoreEvent()
/**
* 自动加载的事件
* 向 ViewModel 发送自动加载的请求
*/
fun onAutoLoadEvent()
/**
* 停止刷新
*/
fun stopRefresh()
/**
* 停止加载更多
*/
fun stopLoadMore()
/**
* 自动加载数据
*/
fun autoLoadData()
}
abstract class BaseActivity : RxAppCompatActivity(), BaseView {
abstract fun onBindLayout(): Int
abstract fun initView()
abstract override fun initData()
override fun initListener()
}
abstract class BaseMvvmActivity<VM : BaseViewModel> : BaseActivity() {
/**
* 绑定 ViewModel
*/
abstract fun onBindViewModel(): Class<VM>
/**
* 放置 观察者对象
*/
abstract fun initViewObservable()
}
abstract class BaseMvvmDataBindingActivity<V : ViewDataBinding, VM : BaseViewModel> : BaseMvvmActivity<VM>() {
abstract fun onBindVariableId(): Int
}
abstract class BaseMvvmRefreshActivity<T, VM : BaseRefreshViewModel<T>> : BaseMvvmActivity<VM>(), BaseRefreshView {
protected abstract fun onBindRreshLayout(): Int
protected abstract fun enableRefresh(): Boolean
protected abstract fun enableLoadMore(): Boolean
}
abstract class BaseMvvmRefreshDataBindingActivity<T, V : ViewDataBinding, VM : BaseRefreshViewModel<T>> : BaseMvvmDataBindingActivity<V, VM>(), BaseRefreshView {
protected abstract fun onBindRreshLayout(): Int
protected abstract fun enableRefresh(): Boolean
protected abstract fun enableLoadMore(): Boolean
}
abstract fun onBindLayout(): Int
abstract fun initView(mView: View)
abstract override fun initData()
abstract class BaseMvvmFragment<VM : BaseViewModel> : BaseFragment() {
abstract fun onBindViewModel(): Class<VM>
abstract fun initViewObservable()
}
abstract class BaseMvvmDataBindingFragment<V : ViewDataBinding, VM : BaseViewModel> :
BaseMvvmFragment<VM>() {
abstract fun onBindVariableId(): Int
}
abstract class BaseMvvmRefreshFragment> : BaseMvvmFragment(),
BaseRefreshView {
protected abstract fun onBindRreshLayout(): Int
protected abstract fun enableRefresh(): Boolean
protected abstract fun enableLoadMore(): Boolean
}
abstract class BaseMvvmRefreshDataBindingFragment<T, V : ViewDataBinding, VM : BaseRefreshViewModel<T>> :
BaseMvvmDataBindingFragment<V, VM>(),
BaseRefreshView {
protected abstract fun onBindRreshLayout(): Int
protected abstract fun enableRefresh(): Boolean
protected abstract fun enableLoadMore(): Boolean
}
ToolBar
open fun enableToolbar(): Boolean {
return true
}
ToolBar
open fun onBindToolbarLayout(): Int {
return R.layout.common_toolbar
}
open fun getTootBarTitle(): String {
return ""
}
/**
* 设置返回按钮的图样,可以是Drawable ,也可以是ResId
* 注:仅在 enableToolBarLeft 返回为 true 时候有效
*
* @return
*/
open fun getToolBarLeftIcon(): Int {
return R.drawable.ic_white_black_45dp
}
/**
* 是否打开返回
*
* @return
*/
open fun enableToolBarLeft(): Boolean {
return false
}
/**
* 设置标题右边显示文字
*
* @return
*/
open fun getToolBarRightTxt(): String {
return ""
}
/**
* 设置标题右边显示 Icon
*
* @return int resId 类型
*/
open fun getToolBarRightImg(): Int {
return 0
}
/**
* 右边文字监听回调
* @return
*/
open fun getToolBarRightTxtClick(): View.OnClickListener? {
return null
}
/**
* 右边图标监听回调
* @return
*/
open fun getToolBarRightImgClick(): View.OnClickListener? {
return null
}
loading
加载数据 override fun showInitLoadView() {
showInitLoadView(true)
}
override fun hideInitLoadView() {
showInitLoadView(false)
}
loading
的加载数据 override fun showTransLoadingView() {
showTransLoadingView(true)
}
override fun hideTransLoadingView() {
showTransLoadingView(false)
}
open fun enableAllowFullScreen(): Boolean {
return false
}
override fun showNoDataView() {
showNoDataView(true)
}
override fun showNoDataView(resid: Int) {
showNoDataView(true, resid)
}
override fun hideNoDataView() {
showNoDataView(false)
}
override fun hideNetWorkErrView() {
showNetWorkErrView(false)
}
override fun showNetWorkErrView() {
showNetWorkErrView(true)
}
Fragment
的懒加载 /**
* 懒加载机制 当页面可见的时候加载数据
* 如果当前 FragmentTransaction.setMaxLifecycle 处理 Lifecycle.State.RESUMED 则 懒加载失效
* 如果 FragmentTransaction.setMaxLifecycle 传入BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT ,
* 则只有当前的Fragment处于Lifecycle.State.RESUMED状态。 所有其他片段的上限为Lifecycle.State.STARTED 。
* 如果传递了BEHAVIOR_SET_USER_VISIBLE_HINT ,则所有片段都处于Lifecycle.State.RESUMED状态,
* 并且将存在Fragment.setUserVisibleHint(boolean)回调
*/
private fun lazyLoad() {
//这里进行双重标记判断,必须确保onCreateView加载完毕且页面可见,才加载数据
if (isViewCreated && isViewVisable) {
Log.d(TAG, "lazyLoad: Successful")
initData()
//数据加载完毕,恢复标记,防止重复加载
isViewCreated = false
isViewVisable = false
} else {
Log.d(TAG, "lazyLoad: Fail")
}
}
//默认不启用懒加载
open fun enableLazyData(): Boolean {
return false
}
DataBinding
UIChangeLiveData
、UIChangeRefreshLiveData
ViewModel
lazy加载基于阿里 ARouter
作为路由,实现组件与组件的通信跳转
https://github.com/alibaba/ARoute
Module的属性是在每个组件的 build.gradle 文件中配置的,当我们在组件模式开发时,业务组件应处于application属性,这时的业务组件就是一个 Android App,可以独立开发和调试;而当我们转换到集成模式开发时,业务组件应该处于 library 属性,这样才能被我们的“app壳工程”所依赖,组成一个具有完整功能的APP
先打开 BaseDemo
工程的根目录下找到 gradle.properties
文件,然后将 isModule
改为你需要的开发模式(true/false), 然后点击 Sync Project
按钮同步项目
isModule=false
if (isModule.toBoolean()) {
apply plugin: 'com.android.application'
} else {
apply plugin: 'com.android.library'
}
我们可以为组件开发模式下的业务组件再创建一个 AndroidManifest.xml,然后根据isModule指定AndroidManifest.xml的文件路径,让业务组件在集成模式和组件模式下使用不同的AndroidManifest.xml,这样表单冲突的问题就可以规避了 已module_main组件为例配置如下:
sourceSets {
main {
jniLibs.srcDirs = ['libs']
if (isModule.toBoolean()) {
manifest.srcFile 'src/main/module/AndroidManifest.xml'
} else {
manifest.srcFile 'src/main/AndroidManifest.xml'
java {
exclude 'debug/**'
}
}
}
}
在每个组件的debug目录下创建一个Application并在module下的AndroidManifest.xml进行配置
排除掉 debug/**
下面的Application,使用 moudle_app
壳子下面的 Application,其必须继承 ModuleApplication
class MyApp : ModuleApplication()
lib.build.gradle
,每个单独 moudle 都需要引入 module.build.gradle
versions.gradle
依赖三方库版本统一管理base.build.gradle
基础编译版本统一管理欢迎 Start ,打call https://github.com/zhouhuandev/BaseDemo 在使用中有任何问题,请留言
国内镜像:https://gitee.com/shandong_zhaotai_network_sd_zhaotai/BaseDemo
Name : "zhouhuandev",
Blog : "https://blog.csdn.net/youxun1312"
Github:"https://github.com/zhouhuandev/BaseDemo"
Gitee:"https://gitee.com/shandong_zhaotai_network_sd_zhaotai/BaseDemo"
注:还有一大部分对此项目提供帮助的开源大佬们,就不一一列出,在此衷心感谢,若是有不足地方麻烦指导改正。
Copyright (C) zhouhuan, BaseDemo Framework Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.