框架庫的使用文檔

框架庫的使用文檔

前言:

這個框架庫旨在快速提供第三方sdk集成的調用例子,一般會進行封裝,方便你們直接用。也儘快用一些新的技術在項目中,可供參考。

報接口錯誤正常的。爲了保密有些接口是不能用的。登錄賬號:18900000066 點了驗證碼後填:123456 裏面我是不允許註冊了的,只能登錄

生成apk時,最新先clean項目再打包

開發環境:

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

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的運行項目解決方案:

沒有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做法

有需要框架源碼的私信我

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章