Some thoughts on Android using adapter mode in MVVM


Some thoughts on Android using adapter mode in MVVM



foreword

People are always progressing through continuous learning. After learning the design pattern, they always want to use it in the project and integrate it, but it will be counterproductive to use it forcibly. Therefore, it is still necessary to use it in the right place. The right way . This article will introduce how to switch different viewmodels to display different data in a fragment through the adapter design mode, so as to achieve the effect of replacing viewpager+fragment.


1. What is the adapter design pattern?

If we want to display the following list on the mobile phone screen, friends who have studied Andorid know that to display a list requires the use of recycleview, and then create a new layout to display the item, and then our highlight today, adapter (adapter), we need to create an adapter Speaking of item layout filled into recycleview and displayed, and then achieve the following effect.

insert image description here
At this time, some friends will laugh, you won't tell me that this is the adapter mode, right? Then I will; yes, this is the adapter mode. By switching different adapters, you can display different item data. Among them, recycleview is the adapter, and the adapter we created is the implementation of specific adaptation to recycleview. And the RecyclerView.Adapter we inherited
is a general specification, telling recycleview that we are here to adapt.

In more plain terms, it is equivalent to you looking for a job, and then telling the boss that I want to interview an Android development engineer, the
boss is the adaptee, you are the specific adaptation, and the Android development engineer is the agreed specification

2. Use adapter mode in MVVM

1. Reason

Let me talk about it first, don't force the use of design patterns, because it will appear that you are showing off your skills.

I received a request to put a Gaode map in a fragment, and then dynamically switch tabs in the map, then switch the data displayed on the map. In line with the work attitude of being able to copy and never write by myself, I have not yet When I opened it, I was looking at how the requirements of the business group next door were written, and then I felt the deep malice of the business group next door to the world. Let’s talk about their implementation first. There is a tablayout at the top of the screen, and a tablayout at the bottom. It is a viewpager with 6 modules of fragments, and each fragment has the same map logic and layout. The only difference is that the display data is different and the filter items are different. Each fragment has reached an astonishing 3000+ lines of code. The whole article is full of repetitive logic and drowsy code. I was so sleepy after reading it for half an hour. Using this wording, I can only say that my head was caught by the door. So I thought of using the adapter pattern. After all, only the displayed data and filter items are really different, and the UI is similar. Why use six layouts when you can use one layout, right?

2. Realize

After finalizing the method to use, it is the design stage. Because the project is MVVM, I finally decided to start with the viewmodel, because the viewmodel is the processing of data, and the difference between us happens to be in the data layer, so I created a new entity class.

class MapEntity {
    
    
    //区域编号
    var areaCode = ""
    //区域名称
    var areaNames = ""
    //纬度
    var latitude = ""
    //经度
    var longitude = ""
    //统计数量
    var mapCount = 0

    var dataList : List<Any> = emptyList()

}

The dataList here is the data I am going to display, but because each data type is different, the specific data type is not declared, but Any is used instead.
Then define the position of an Android development engineer; (create a viewmodel interface), similar to the following

interface IBaseMapViewModel {
    
    

    var getList: MutableLiveData<List<Any>>
        get() = MutableLiveData<List<Any>>()
        set(value) = TODO()

    var isEmpty: MutableLiveData<Boolean>
        get() = MutableLiveData()
        set(value) = TODO()
    var loading: MutableLiveData<Boolean>
        get() = MutableLiveData()
        set(value) = TODO()
        
    var hintString : String

    var type : Int

    var drawable : Int

    var drawableClick : Int

    fun getMapData(
        botRightLat: String,
        botRightLon: String,
        categoryNo: String,
        industryNo: String,
        thirdCategoryNo: String,
        keyWord: String,
        searchType: Int,
        topLeftLat: String,
        topLeftLon: String,
        context: Context,
        distance: String,
        mCenterLatLng: LatLng,
        employmentStatus: String,//用工状态
        proficiency: String, //专业职级 	熟练度(专业职级 1:高级工(大工) 2:中级工(中工) 3:初级工(小工))
        workYear: String, //工龄 1-3传1 3-5传2 5-10传3 10以上传4
        qualificationTypeNo: String,
        qualificationClassNo: String,
        teamNumber: String,
        businessType : String
    )

    //成都房建水泥工成都房建水… 2.2w/月
    fun getMarkerText(item: MapEntity):String

    //等12份工作
    fun getMarkerNum(item: MapEntity,isProvince:Boolean):String

    fun getUrlSetting( id:String,  type:Int,  modelType:String, userNo:String, context: Context)

}

It can be seen that in this abstract viemodel, our input parameters include MapEntity; look at the input parameters of the getMapData method, which may be a bit too much, because it includes all six page filter items, which is also an adapter mode a shortcoming

Then create a viemodel like "you"

class MapViewModel () : BaseViewModel(), IBaseMapViewModel {
    
    

Implement the interface in IBaseMapViewModel, and specifically handle the display of each data entity class. I have created a total of six such specific business viewmodels!

Finally, how to use these specific viewmodels? In the fragment, first define the abstract viewmodel

    //地图viewmodel
    private lateinit var viewModel: IBaseMapViewModel

Then click different positions through tablayout to initialize different viewmodels

 when (selectSecondTap) {
    
    
            xxxxType -> {
    
    
                viewModel = MapViewModel()
            }
           
           ......

There is a pitfall here is that observe needs to be reinitialized every time the viewmodel is reinitialized, otherwise it will not get the requested data


A summary of the advantages and disadvantages of using the adapter pattern like this

advantage:

  • Reduced the amount of code, reduced the code amount of the fragment, from 3000+ lines to 1000+ lines
  • The code is clearer, basically only when the viewmodel is switched can judgment be made, the rest are real business codes
  • Reduce maintenance costs. If you want to add new data display on the basis of the six, you only need to add a viewmodel and logical judgment, which is very convenient

shortcoming:

  • Additional processing needs to be done in different places. If you don’t write comments, that piece of code will look scary (such as the input parameter of getMapData)
  • If there is a huge change in requirements, for example, different data needs to be represented in different ways, it will be necessary to overthrow and rewrite or add a lot of meaningless interfaces, making the readability and maintainability very poor

Guess you like

Origin blog.csdn.net/shop_and_sleep/article/details/128419440