【程式設計框架】Android可配置的ScrollView框架

Colin_Mindset發表於2018-09-27

給大家推薦一下我最近剛寫好的“可配置的ScrollView框架”,凡是採用scrollView結構的業務頁面都可以採用這個框架。該框架主要有以下幾個優點:
1、scrollView中的每個模組位置走配置,有一個configuration類統一管理
2、業務程式碼模組化。activity裡不再充斥了各種業務程式碼,每個模組的業務程式碼分別在自己的模組裡實現
3、layout佈局模組化。每個模組的佈局都寫在單獨的layout裡,activity的layout只有一個scrollView作為container
4、模組間可通訊。採用中介者模式,模組間很好地解耦,可以輕鬆地在模組A中通知模組B去修改
5、模組中可拿到activity的生命週期,徹底實現了業務程式碼模組化
6、框架結構嚴格按照mvp的思想設計,層次清晰

下面來介紹一下我的設計思想。
先看一下框架結構
在這裡插入圖片描述
首先看一下Activity程式碼:

class MainActivity : AppCompatActivity(), IView {

    private val mModuleConfiguration = ModuleConfiguration()
    private lateinit var mContainer: LinearLayout
    private lateinit var mPresenter: Presenter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initViews()
        init()
    }

    private fun initViews() {
        mContainer = findViewById(R.id.container)
    }

    private fun init() {
        mPresenter = Presenter(this, this)
        mModuleConfiguration.init(this, mPresenter).doConfigure().assemblePage(mContainer)
        mModuleConfiguration.onViewCreated()

        mPresenter.startDrawUI()
    }

    override fun onDestroy() {
        super.onDestroy()
        mModuleConfiguration.onDestroy()
    }

    override fun onResume() {
        super.onResume()
        mModuleConfiguration.onResume()
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        mModuleConfiguration.onActivityResult(requestCode, resultCode, data)
    }

    override fun refreshModule(type: String, fromNetwork: Boolean) {
        mModuleConfiguration.getModule(type)?.refresh(fromNetwork)
    }
}

可以看到,activity中有一個ModuleConfiguration類負責管理配置各個module,它主要負責控制每個module位置,新增新的module,控制每個module的生命週期回撥,模組間通訊。
使用起來也非常方便:
mModuleConfiguration.init(this, mPresenter).doConfigure().assemblePage(mContainer)
採用一個鏈式呼叫就可以完成模組的配置。

接下來看一下每個module的結構

class BModule : BaseModule(), View.OnClickListener {
    override fun onClick(v: View?) {
        notifyAModule()
    }

    override fun refresh(fromNetwork: Boolean) {

    }

    override fun getModuleView(): View {
        mView = LayoutInflater.from(mContext).inflate(R.layout.layout_b,
                getParentView(), false)
        return mView
    }

    override fun onViewCreated() {
        super.onViewCreated()
        mView.setOnClickListener(this)
    }

    private fun notifyAModule() {
        mMediator.notifyAdoSomething()
    }

    override fun onDestroy() {
        super.onDestroy()

    }

    override fun onResume() {
        super.onResume()
    }

    override fun onResumeAndLoginStateChanged() {
        super.onResumeAndLoginStateChanged()

    }


}

這裡不用多說了吧,層次非常清晰。每個module有一個基類BaseModule:

abstract class BaseModule {
    lateinit var mContext: Context
    lateinit var mView: View
    lateinit var mParent: ViewGroup
    lateinit var mPresenter: Presenter
    lateinit var mMediator: Mediator

    open fun init(context: Context, presenter: Presenter, mediator: Mediator) {
        this.mContext = context
        this.mPresenter = presenter
        this.mMediator = mediator
    }

    open fun onViewCreated() {

    }

    open fun onDestroy() {

    }

    open fun onResume() {

    }

    open fun onResumeAndLoginStateChanged() {

    }

    open fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {

    }

    fun bind(parent: ViewGroup) {
        if (parent == null) {
            return
        }
        mParent = parent
        var view = getModuleView()
        if (view == null || view.parent != null) {
            return
        }
        view.visibility = View.VISIBLE
        parent.addView(view)
    }

    abstract fun getModuleView(): View

    fun getParentView(): ViewGroup {
        return mParent
    }

    abstract fun refresh(fromNetwork: Boolean)

}

看到這裡,你應該已經大致知道了我的設計思想了。下面就是mvp架構的具體實現:
首先是View層:
demo裡view層只有一個方法,

interface IView {
    fun refreshModule(type: String, fromNetwork: Boolean)
}

要想重新整理哪個module,只需要把對應的type傳進來。

interface IPresenter {
    fun onDataRes(type: String, fromNetwork: Boolean)
    fun getModel(): Model
}

接下來看Presenter層:
這裡負責接收model層處理好的資料,並通知ui層更新ui。
最後看一下Model層:

interface IModel {
    fun requestDataARes(modelA: ModelA, fromNetwork: Boolean)
    fun requestDataBRes(modelB: ModelB, fromNetwork: Boolean)
    fun requestDataCRes(modelC: ModelC, fromNetwork: Boolean)
    fun requestDataDRes(modelD: ModelD, fromNetwork: Boolean)
}

這裡負責處理各個網路請求的資料,model層主要負責:傳送網路請求、將網路請求回來的資料進行記憶體和檔案快取。
到這裡mvp就介紹完了,程式碼沒有全部列出,後面會奉上demo地址。
最後有一個MemoryCache類,可以在裡面輕鬆拿到所有的記憶體快取。

object MemoryCache {
    fun setModelA(presenter: IPresenter, modelA: ModelA) {
        presenter.getModel().memoryCache.modelA = modelA
    }

    fun getModelA(presenter: IPresenter): ModelA? {
        return presenter.getModel().memoryCache.modelA
    }

    fun setModelB(presenter: IPresenter, modelB: ModelB) {
        presenter.getModel().memoryCache.modelB = modelB
    }

    fun getModelB(presenter: IPresenter): ModelB? {
        return presenter.getModel().memoryCache.modelB
    }

    fun setModelC(presenter: IPresenter, modelC: ModelC) {
        presenter.getModel().memoryCache.modelC = modelC
    }

    fun getModelC(presenter: IPresenter): ModelC? {
        return presenter.getModel().memoryCache.modelC
    }


}

這個框架基本上就可以支援任何業務頁面的開發了,層次非常清晰。奉上demo地址

相關文章