框架库的使用文档

2022-06-28  本文已影响0人  你的益达233

框架库的使用文档

前言:

这个框架库旨在快速提供第三方sdk集成的调用例子,一般会进行封装,方便你们直接用。也尽快用一些新的技术在项目中,可供参考。

报接口错误正常的。为了保密有些接口是不能用的。登录账号:18900000066 点了验证码后填:123456 里面我是不允许注册了的,只能登录

生成apk时,最新先clean项目再打包

开发环境:

Android studio Arctic Fox | 2020.3.1 Patch 3(北极狐版本)

QQ图片20220601102408.png

classpath "com.android.tools.build:gradle:7.0.3"
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10'

distributionUrl=https://services.gradle.org/distributions/gradle-7.0.2-bin.zip

compileSdkVersion = 31
targetSdkVersion = 30

使用Androidx

如果你的开发环境过低可能没法使用,最好使用北极狐版本的,至少是4.2的
版本问题导致没法正常运行项目的,自行调整。如果是北极狐版本没法运行的,可在群里联系我
经测试,最新版2021.2.1袋鼠版本是可以直接运行的

提供下Android studio4.1的运行项目解决方案:
4.1_改1.png 4.1_改2.png 4.1-改3.png 4.1-改4.png

没有jdk11的,请自行百度下载

开发语言:

Kotlin 和部分的java

一、MVVM的实现(亮点)

配置: lib下

// mvvm框架
api 'androidx.databinding:viewbinding:7.0.3  
api 'org.koin:koin-androidx-viewmodel:2.0.1'  
api 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'

使用到的模块下的build.gradle配置

//使用viewBinding
buildFeatures {
    viewBinding true
}

配置完后,你的布局的Binding就自动生成了,即不用自己去findViewId了
(如你建的布局名是activity_base,它就是ActivityBaseBinding,自动生成的)
接下来就是如何构建ViewModel了(它主要用于请求接口)

我们来看下BaseActivity代码

abstract class BaseActivity<VB : ViewBinding, VM : BViewModel> : AppCompatActivity()  {    

里面有请求接口返回的回调

/**
 * 请求接口返回的回调
 */
abstract fun onModelData(model: BViewModel.UIModel)

接着看下它的BViewModel里面会有个关键方法emitUIState

接着看一个具体使用的ViewModel,app下的CommonViewModel

open class CommonViewModel (private val repo: CommonRepository) : BViewModel() {  

这里类下有个请求接口的方法:

fun resumeUpdate(body: UpdateResumeBody){
    viewModelScope.launch(Dispatchers.Main){
        val result = repo.resumeUpdate(body)
        if (result is RResult.Success){
            emitUIState(code = result.code,toast = if (result.code != ResultCodes._200) result.msg else "",
                data = result.data,type = "resumeUpdate")
        }
    }
}

关键的方法说完了,下面做个流转的总结:
拿MyGoldActivity来说

class MyGoldActivity :BaseActivity<ActivityMyGoldBinding,InfoViewModel>(){

lateinit var priceAdapter: GoldPriceAdapter

override fun initVB(): ActivityMyGoldBinding {
    return ActivityMyGoldBinding.inflate(layoutInflater)
}

override fun initVM(): InfoViewModel {
    return getViewModel()
}

override fun initData() {
    setCommonTitle(R.string.my_gold)
    
    mViewModel.getGoldPrices()
}

override fun initRealView(view: View) {
    mBinding.rvGoldList.run {
        layoutManager = object : LinearLayoutManager(mContext){
            override fun canScrollVertically(): Boolean {
                return false
            }
        }
        priceAdapter = GoldPriceAdapter()
        adapter = priceAdapter
    }
}

、

override fun errorClick() {
    mViewModel.getGoldPrices()
}

override fun onModelData(model: BViewModel.UIModel) {
    if(model.type == "GoldPrices"){
        if(model.code == ResultCodes._200){
            showRealView()
            model.data?.run {
                this as GoldPriceBean
                mBinding.tvMyGoldNum.text = "$goldBalance"
                list?.let {
                    if(it.size > 0){
                        priceAdapter.setNewInstance(list)
                    }
                }
            }
        }
    }else if(model.type == "GoldAliPayOrder"){
        if(model.code == ResultCodes._200){
            model.data?.run {
                this as GoldAlipayOrderBean
                signDataStr?.let {
                    PayUtils.aliPay(it,this@MyGoldActivity){ payResult ->
                        LogUtils.i("支付结果:","${payResult.resultStatus}\t${payResult.result}\t${payResult.memo}")
                        if(payResult.resultStatus == "9000"){
                            // 支付成功
                            show(R.string.pay_success)
                            mViewModel.getGoldPrices()
                        }else{
                            show(R.string.pay_failed)
                        }
                    }
                }
            }
        }
    }
}}

在initData方法调mViewModel.getGoldPrices()去请求金币列表数据,请求数据回来后回调emitUIState(code = result.code, data = result.data, type = "GoldPrices"),这是_uiState.value = model,它的数据变化了,就会通知观察者,这是就走到了BaseActivity的mViewModel.uiState.observe(this),里面一系列判断符合要求后调onModelData(it)。这时就回调了具体实现了该方法的子类。如果子类界面有多个接口请求的,根据type判断出是那个接口回调的(如if(model.type == "GoldPrices"))

别忘了MyApplication要配置viewmodel和接口仓库

/**
 * 初始化 Koin
 */
private fun initKoin() {
    startKoin {
        androidContext(this@MyApplication)
        modules(appModule)
    }
}

二、请求接口方式:协程+retrofit(亮点)

  1. 请求接口的域名修改在BaseRequest
  2. 具体每个接口的配置在CommonAPI
  3. 请求接口的获取返回的数据在CommonRepository
  4. 具体使用可参考InfoViewModel的getGoldPrices方法(协程就这里用)
  5. 修改请求头在APIRequest
  6. 接口返回的默认结构体在RResult(项目中的是code,msg,data,其中data是泛型)

注意:
项目中200或者是以4开头都是认为是正确的返回,比如200是可以正常送礼物,4002代表金币不足。具体在BaseRepository的executeResponse

这个功能没法一步步讲,我会上传一个只有mvvm-http的项目,里面没有多余的代码,就一个界面,点击一下,请求一个接口(现在不上传了,有需要可以单独找我)

三、BaseActivity

  1. 它有三部分组成头部(标题栏),页面错误,添加真实界面(子类的界面)
  2. 首先子类继承它,在重写的initData去请求接口(可参考MyGoldActivity),如果要刚进界面正在加载的弹框,在请求接口里面写 emitUIState(true)即可
  3. 如果界面一开始加载不用请求接口的,在initData中调showRealView方法即可
  4. 如果是请求接口或者界面上有多个请求,它的数据回调都在onModelData方法中,里面根据type来判断是那个接口返回的
  5. 在initRealView方法中才能操作你子类的控件。(showRealView方法后子类布局就会添加到基类中,所以得showRealView后initRealView才起作用(可参考MyGoldActivity))

四、统一头部

BaseActivity的showRealView方法

五、BaseListActivity(亮点)

主要是研究多个列表界面,发现它们处理的逻辑都一样,就抽离一个列表基类。
它变的是每个列表上的item的数据,和布局。

abstract class BaseListActivity<VM : BViewModel,T,D : BaseListBean<T>, A : BaseQuickAdapter<T, BaseViewHolder>> : BaseActivity<LibBaseListLayoutBinding,VM>(), BaseListIView{

所以你看item的数据T,和adapter都由具体子类指定。
列表基类控制是否能翻页,数据的加载,刷新等操作。难点在于T的处理
具体参考DetailsActivity

六、首页用jectpack的navigation

我们来看下activity_main.xml
fragment就相当于地图,BottomNavigationView底部栏的显示。
nav_main.xml配置地图上的有的地方

MainActivity上如何将fragment和BottomNavigationView结合起来。

mBinding.navigationMain.itemIconTintList = null
    val mMainNavFragment: Fragment? = supportFragmentManager.findFragmentById(R.id.fragment_nav_main)
    val navController = NavHostFragment.findNavController(mMainNavFragment!!)
    mBinding.navigationMain.setupWithNavController(navController)

七、路由arouter,进一步封装

配置我就不说了。
封装类在lib下CRouter类

八、图片框架Glide,进一步封装

封装类在lib下的ImageLoader类

九、仿双击

配置:
api 'com.jakewharton.rxbinding4:rxbinding:4.0.0'

封装类RxViewUtils

十、权限请求封装

配置:

api 'com.github.tbruyelle:rxpermissions:0.12'  

封装类PermissionAppUtils

十一、选择本地图片框架

封装类PictureSelectorUtils
界面在:编辑基本信息上传头像(InfoEditActivity)

十二、阿里云oss上传图片文件

封装类OssManager
界面在:编辑基本信息上传头像 (InfoEditActivity)

十三、高德定位

封装类AMapLocationUtils
界面在:首页的附近

十四、支付宝SDK

封装类PayUtils
界面在:金币充值(MyGoldActivity)

十五、网络图片浏览器(关闭时回到原来图片位置,类似微信朋友圈)

封装类PhotoPreviewUtils
界面在:看对方详情的照片处
代码在:PhotoAdapter代码中PhotoPreviewUtils.asImageViewer

十六、依赖某个view的弹框

用的是XPopup
界面在:消息上的三个点点点(你可以看不见,没关系直接看代码)
代码在:MsgOutFragment的initPrClick方法里面

十七、富文本的多个点击

封装类TvUtils

TvUtils.create()
        .addSsbColorClick(getString(R.string.agreement),getColors(R.color.color_FFD596)){
            show("点击了用户协议")
        }
        .addSsb(getString(R.string.and))
        .addSsbColorClick(getString(R.string.policy),getColors(R.color.color_FFD596)){
            show("点击了隐私政策")
        }.showIn(mBinding.tvAgree)  

十八、城市,年龄联动选择框

用的是XPopup
界面在:编辑基本信息上传头像 (InfoEditActivity)
代码:InfoEditActivity的selectArea

十九、选择送礼物弹框

用的是XPopup
这个界面看不见,前置礼物列表接口被我注释掉了
弹框代码还在:SelectGiftBottomPopup

二十、正在加载中或者上传中弹框

用的是Xpopup
代码在:BaseActivity的showLoading()方法

二十一、本地视频列表

界面在:我的->设置->我的动态列表->点击发布->视频
代码:VideoSelectActivity

二十二、阿里云短视频

短视频即如何录制视频
界面在:我的->设置->我的动态列表->点击发布->视频->点击选择视频列表的第一个
代码:要引入AlivcPlayerTools库后,具体实现代码VideoUtils的startRecordAuthVideo()方法

二十三、阿里云视频播放器

界面在:我的->设置->我的动态列表->点击发布->视频->点击选择视频列表中的本地列表
如果要播放网络地址视频,发布视频动态后,在点击动态中的视频。
代码:VideoPlayActivity

二十四、阿里云视频上传

代码在:VideoUtils的videoUpload()方法

二十五、动态(朋友圈)九宫格

界面在:我的->设置->我的动态列表(发多张图片就看到效果了)
代码:NineGridPhotoView
就是嵌套RecycleView做法

有需要框架源码的私信我

上一篇下一篇

猜你喜欢

热点阅读