一.前言
kotlin已经出来这么久了,为了更快更高效完成公司的业务逻辑,一套完整高效的开发框架必不可少。再也不会抱怨代码冗余了,开心写业务吧。
二.框架大致结构介绍
1.kotlin语言编写
2.组件化,采用了路由框架ARouter
3.MVVM架构
4.Koin轻量级依赖注入框架,简单易学,具体用法可搜索
5.今日头条屏幕适配方案
6.官方提供的Room数据库,用起来很爽
7.30秒即可上手,学习成本极低的网络请求库Rxhttp,支持kotlin协程,github:github.com/liujingxing…,
8.一个非常丰富的工具类utilcode:github:github.com/Blankj/Andr…
9.非常智能的上拉刷新下拉加载的控件SmartRefreshLayout
三.详细介绍
1.关于组件化的开发框架
Module主要有两种属性:
//通过isBuildModule这个变量来确定每个模块是单独运行还是以Library的形式加载到整个App
if (isBuildModule.toBoolean()) {
apply plugin: 'com.android.application'
} else {
apply plugin: 'com.android.library'
}
apply from: "../config_build.gradle"
android {
//这里进行设置使用单独运行还是合并运行的Manifest.xml
sourceSets {
main {
jniLibs.srcDirs = ['libs']
if (isBuildModule.toBoolean()) {
manifest.srcFile 'src/main/debug/AndroidManifest.xml'
} else {
manifest.srcFile 'src/main/release/AndroidManifest.xml'
}
}
}
}
关于组件的跳转
* 关于所有ARouter路由跳转的类
* */
object NavigationUtils {
/**
* 去往首页
*/
fun goMainActivity() {
ARouter.getInstance().build(RouterConstants.MAIN_ACTIVITY).navigation()
}
fun goMineActivity() {
ARouter.getInstance().build(RouterConstants.MINE_ACTIVITY).navigation()
}
fun goLoginActivity() {
ARouter.getInstance().build(RouterConstants.LOGIN_ACTIVITY).navigation()
}
}
2.koin管理module
##管理所有的viewmodel#
val viewModelModule = module {
viewModel { MainViewModel(get())}
}
val localModule = module {
single<AppDatabase> { AppDatabase.getInstance(androidApplication()) }
single<UserDao> { get<AppDatabase>().userDao() }
single<User2Dao> { get<AppDatabase>().user2Dao() }
}
val appModule = listOf(viewModelModule,localModule)
举个例子首页ViewModel
class MainViewModel(private val userdao: UserDao) :BaseViewModel(){
init {
}
fun loadData(){
showLoading.set(true)
}
}
MainActiviyde 初始化
@Route(path = RouterConstants.MAIN_ACTIVITY)
class MainActivity : BaseActivity<ActivityMainBinding>() {
override fun getLayout(): Int = R.layout.activity_main
private val mViewModel : MainViewModel by viewModel()
}
组件只需在ProApp里实现自己的依赖注入
class ProApp :BaseApplication(){
override fun onCreate() {
super.onCreate()
//该类是module单独运行时候需要的Application类,这里我们不需要实现第三方的实例逻辑,只需要注入AppComponent就好
}
}
3.初始化基类
abstract class BaseActivity<B : ViewDataBinding> :SupportActivity(),View.OnClickListener{
private var mConfig=ActivityConfig()
var mRootView:View?=null
/**
* 状态视图
*/
protected var mStateView: StateView? = null
/**
* toolbar中间标题
*/
private var tvCenterTitle: TextView? = null
/**
* Activity配置类
*/
protected var mToolbar: Toolbar? = null
private var tvRight: TextView? = null
private var flBaseContent: FrameLayout? = null
protected lateinit var mBinding: B
override fun onAttachedToWindow() {
super.onAttachedToWindow()
BarUtils.setStatusBarColor(
this,
ColorUtils.getColor(android.R.color.white)
)
if (mToolbar != null) {
BarUtils.addMarginTopEqualStatusBarHeight(mToolbar!!)
}
BarUtils.setStatusBarLightMode(this, true)
}
override fun onCreate(savedInstanceState: Bundle?) {
updateActivityConfig(mConfig)
super.onCreate(savedInstanceState)
mRootView = View.inflate(this, R.layout.activity_base, null)
addContent()
setContentView(mRootView)
initView()
}
abstract fun getLayout(): Int
abstract fun initView()
open fun updateActivityConfig(activityConfig: ActivityConfig){}
private fun addContent(){
initToolbar()
flBaseContent = mRootView?.findViewById(R.id.fl_base_content)
val inflater = getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
mBinding= DataBindingUtil.inflate(inflater, getLayout(), flBaseContent, true);
mBinding.lifecycleOwner = this
if (mConfig.mStateView) {
if(getInjectStateView()!=null) {
mStateView = StateView.inject(getInjectStateView()!!)
mStateView!!.setOnRetryClickListener { this.onRetry() }
}
}
}
protected fun getInjectStateView(): ViewGroup? {
return flBaseContent
}
protected fun onRetry() {
}
open fun showLoading() {
if (mStateView != null) {
mStateView!!.showLoading()
}
}
open fun showEmpty() {
if (mStateView != null) {
mStateView!!.showEmpty()
}
}
open fun showRetry() {
if (mStateView != null) {
mStateView!!.showRetry()
}
}
open fun showContent() {
if (mStateView != null) {
mStateView!!.showContent()
}
}
/**
* 初始化toolbar
*/
private fun initToolbar() {
mToolbar = mRootView?.findViewById(R.id.toolbar)
tvCenterTitle = mToolbar?.findViewById(R.id.tv_toolbar_center_title)
tvRight = mToolbar?.findViewById(R.id.tv_toolbar_right)
tvRight?.setOnClickListener(View.OnClickListener { v: View? -> setToolbarRightTextClick() })
if (!mConfig.mToolbar) {
mToolbar?.setVisibility(View.GONE)
return
}
setSupportActionBar(mToolbar)
if (supportActionBar != null) {
supportActionBar!!.setHomeAsUpIndicator(resources.getDrawable(R.drawable.icon_base_back))
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
supportActionBar!!.setDisplayShowTitleEnabled(false)
}
}
/**
* 点击toolbar 右边的文字
*/
protected open fun setToolbarRightTextClick(){
}
/**
* 设置toolbar中间标题
*
* @param title 标题
*/
protected open fun setCenterTitle(title: String?) {
if (tvCenterTitle != null && !TextUtils.isEmpty(title)) {
tvCenterTitle!!.text = title
}
}
/**
* 设置toolbar右边文字
*
* @param text 文字
*/
protected fun setToolbarRightText(text: String?) {
if (tvRight != null && !TextUtils.isEmpty(text)) {
tvRight!!.visibility = View.VISIBLE
tvRight!!.text = text
}
}
override fun onDestroy() {
super.onDestroy()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
onBackPressedSupport()
return true
}
return super.onOptionsItemSelected(item)
}
override fun onBackPressedSupport() {
super.onBackPressedSupport()
}
override fun onClick(v: View) {
}
}