One, foreword

Ever since I started android development, I’ve been suffering from Adapter writing anxiety. In the current Android App development, the ViewGroup we use the most, it must be the big brother RecyclerView, single layout list, multi-layout list, grid list, waterfall flow list, folding list, top list, even a page without scrolling, for screen height adaptation, It’s possible to make a list. This is enough to prove the importance of RecyclerView in practical development.

So how do we normally implement such an important component?

Step 1: add RecyclerVIew in the layout step 2: create item layout and its entity class step 3: inherit RecyclerVIew.Adapter class, write a custom Adapter step 4: bind Adapter to RecyclerVIew

This is the steps necessary to achieve a complete list, including the third step is the most complicated in the entire process, some of the tripartite library at present, to a certain extent, simplifies the third step, let developers after inherited their custom Adapter, can be less of a large part of the code, so as to improve development efficiency, I also used before the excellent library, For example, BRVAH, the most widely used product in the Android world, has greatly reduced development time for developers and allowed them to spend time at home with their families. Thank you for your contributions.

However, I started working on Android development in July 2016. I started working on Kotlin in early 2017, and then started working on kotlin projects after Google officially authorized Kotlin in May 2017. Since then, Fascinated by Kotlin’s DSL, I tried to convert these excellent third-party libraries into DSLS, but the capability was not there at the time, and the near-rewrite failed. Since large-scale transformation is not possible, can I find some Adapter DSL written by others? After a lot of searching, I finally found some libraries on Github, such as Kotlin-Adapter and Yasha.

Both of these are excellent libraries, and I used them for projects in the past, but gradually I found that they couldn’t meet some of my needs, so I started trying to write my own library. When the library was still exists in my private project, I met in the project problem can change in time, until the first half of 19 years, the library can be used for most basic daily development, then I will consider it for some improvement after open source, but you never know, because working reason, July 19 years, I went to a trip to Cambodia, that’s right, It’s one of the southeast Asian countries where programmers are reviled.

After I went there, I had to learn vue development, Flutter development, and back-end development due to staffing issues, and had little time to do open source work on the library. In September, 2012, I returned to Chongqing due to my work schedule. After several months of busy work, I finally got some time to continue my work recently.

As I reviewed the library, I saw a lot of improvements that I could make over the past year, and I was happy with them. After two or three weeks of free time polishing it and adding some new features, I decided to release it today. I hope you enjoy it.

Sorry, the preface is a little wordy, but still does not hinder the follow-up wonderful.

Second, the positive

A brief introduction to this library: YasuoRecyclerViewAdapter, why named Yasuo, because Yasuo == happy! This library is there to make writing code fun!

1. Functional features

List, Grid, StaggeredGrid type of normal layout and multiple layout

② Blank page/head/tail

③ Load more

4, folding layout (support multi-level folding)

⑤, drag and slide horizontally to delete

⑥, two item decorations are included, which can be selected according to different needs

Use ObservableList as the data source, without manual notify

Support findViewById, ViewBinding, DataBinding three modes, can be based on your existing project mode or preferences at will!

⑨, high configuration of animation (after comprehensive consideration of recyclerView itemAnimator program, if necessary, please rely on MikePenzItemAnimatorsLibrary)

⑩, suction top (adoptedsticky-layoutmanager, low coupling Adapter and item. Since there were some bugs in position acquisition of the original library, we integrated them into this project and fixed the bugs.)

2, dependence, the latest version please seegithuborjitpack

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io'}}}Copy the code
dependencies {
    implementation 'com.github.q876625596:YasuoRecyclerViewAdapter:x.y.z'
}
Copy the code

2. Demonstration examples

If you want to direct Ctrl CV code, quickly start the students, please move directlysample

3. Detailed introduction

1) Data source

YasuoList or a subclass of YasuoList must be used as the data source. YasuoList inherits from ObservableArrayList, adding some common methods and listening inside the Adapter, so manual notify is not required to use this type of data source

2) Simple (single layout/multiple layout /header/footer)
    fun findViewByIdMode(a){
        / / the data source
        val list = YasuoList<Any>()
        val headerList = YasuoList<Any>()
        val footerList = YasuoList<Any>()
        binding.myRV.layoutManager = GridLayoutManager(this.3)
        / / the findViewById mode
        binding.myRV.adapterBinding(this,list){
            //do something
            // Bind the text layout
            // Set holderConfig for the corresponding layout to implement multiple layouts, headers, and footers
            holderConfig(R.layout.item_layout_text, TextBean::class) {
                onHolderBind { holder, item ->
                    holder.getView<TextView>(R.id.itemText).apply {
                        text = item.text.value
                    }
                }
            }
        }
        / / ViewBinding mode
        binding.myRV.adapterViewBinding(this,list){
            //do something
            // Configure the text layout
            // Set holderConfig for the corresponding layout to implement multiple layouts, headers, and footers
            holderConfig(R.layout.item_layout_text, TextBean::class.{ ItemLayoutTextBinding.bind(it) }) {
                onHolderBind { holder, item ->
                    itemText.text = item.text.value
                }
            }
        }
        / / DataBinding mode
        binding.myRV.adapterDataBinding(this,list){
            //do something
            // Configure the text layout
            // Set holderConfig for the corresponding layout to implement multiple layouts, headers, and footers
            holderConfig(R.layout.item_layout_text_data_binding, TextBean::class.ItemLayoutTextDataBindingBinding::class) {
                onHolderBind { holder ->
                    //dataBInding schema already binds data in XML, no manual setting required}}}}Copy the code

There is only so much difference between the above three modes, and switching between them is quite convenient.

3) Empty layout

The empty layout is also very simple to use. After configuring the holderConfig for the empty layout, call Adapter.showemptyLayout.

        binding.myRV.adapterViewBinding(this,list){
            //do something
            holderConfig(R.layout.item_layout_text, TextBean::class.{ ItemLayoutTextBinding.bind(it) }) {
                onHolderBind { holder, item ->
                    itemText.text = item.text.value
                    itemText.setOnClickListener {
                        showEmptyLayout(/* Empty layout entity */EmptyBeanTwo(), /* Whether to clear the header*/true./* Whether to empty footer*/true)}}}}Copy the code
4) Set the proportion of the layout

There are two ways to set the ratio. The first way is to set the ratio for one type of layout:

        binding.myRV.adapterViewBinding(this,list){
            //do something
            holderConfig(R.layout.item_layout_text, TextBean::class.{ ItemLayoutTextBinding.bind(it) }) {
                //do something
                // Set the layout of an itemViewType uniformly
                // The waterfall fills the row
                staggeredGridFullSpan = true
                // Grid layout ratio
                gridSpan = 3}}Copy the code

The second way is to set the proportion of an item separately:

        list.add(ImageBean(MutableLiveData(ContextCompat.getDrawable(this@MainActivity, R.drawable.eee))).apply {
                    // Set an item separately
                    // The waterfall fills the row
                    staggeredGridFullSpan = true
                    // Grid layout ratio
                    gridSpan = 3
        }
Copy the code

Determine priority: Single item Settings > Type Settings

5) Load more

Load more akin to an empty layout, also will load more layout first holderConfig configuration, again calling adapter. ShowLoadMoreLayout make empty display layout, finally add adapter. OnLoadMoreListener listening.

        binding.myRV.adapterViewBinding(this,list){
            // Show loading more
            showLoadMoreLayout(DefaultLoadMoreItem())
            // Set up to load more listeners
            onLoadMoreListener(binding.myRV) {
                // Request data...
            }
            //do something
        }
Copy the code
6) Drag/side slide to delete

Only need to use the adapter. EnableDragOrSwipe to enable drag and drop, at the same time can also be set up to monitor, set the direction of gestures, as well as to the specific layout is disabled

        binding.myRV.adapterViewBinding(this,list){
            // Drag/slide to delete
            enableDragOrSwipe(binding.myRV, isLongPressDragEnable = true, isItemViewSwipeEnable = true)
            //do something
        }
Copy the code
7) absorption

First set up the layoutManager: StickyLinearLayoutManager StickyGridLayoutManager, StickyStaggeredGridLayoutManager suck the top there are two ways, first, in a certain type of layout Settings

        binding.myRV.adapterViewBinding(this,list){
            //do something
            holderConfig(R.layout.item_layout_text, TextBean::class.{ ItemLayoutTextBinding.bind(it) }) {
                // Set the layout of an itemViewType uniformly
                // Top, note that the top will fill the line by default
                sticky = true
                //do something}}Copy the code

Second, set the top for an item

list.add(ImageBean(MutableLiveData(ContextCompat.getDrawable(this@MainActivity, R.drawable.eee))).apply {
        // Set an item separately
        // Top, note that the top will fill the line by default
        sticky = true
}
Copy the code

Determine priority: Single item Settings > Type Settings

8) Folding layout

The foldable layout requires the data class to inherit YasuoFoldItem, and then only need to use adapter.expandOrFoldItem to expand/fold. Multi-level folding is supported. Recommend the use of adapter. RemoveAndFoldListItem and adapter. AddAndFoldListItem method

9) Animation configuration

Animations use mikepenz’s ItemAnimators library. If necessary, rely on this library yourself.

        binding.myRV.itemAnimator = SlideLeftAlphaAnimator()
Copy the code
10) itemDecoration

Support for styling each edge individually

        binding.myRV.addYasuoDecoration {
            setDecoration(R.layout.item_layout_text, this@MainActivity, defaultRes)
            setDecoration(R.layout.item_layout_image, this@MainActivity, defaultRes)
        }
Copy the code

A grid layout space with equal span is attached

        binding.myRV.addItemDecoration(GridSpacingItemDecoration(3.20.true))
Copy the code

4. API display

1) Adapter can be configured with a list of properties/methods
Property name/method name introduce The default value
itemList The main list YasuoList()
headerList Head the list YasuoList()
footerList The tail list YasuoList()
showLoadMoreLayout(loadMoreItem: T) Configure and show loading more layouts ——
removeLoadMore() Remove loading more layouts ——
enableLoadMoreListener() Enable loading more listeners when scrolling to the bottom of the list ——
disableLoadMoreListener() Disable loading more listeners when the list scrolls to the bottom ——
isShowEmptyLayout() Check whether the current empty layout state is displayed ——
showEmptyLayout(emptyItem: T, clearHeader: Boolean = false, clearFooter: Boolean = false) Check whether the current empty layout state is displayed ——
expandOrFoldItem(item: YasuoFoldItem) Expand/collapse an item ——
removeAndFoldListItem(childItem: Any, foldList: YasuoList? = null) Removing an item removes the same item from its collapsed list ——
getAllListSize() Gets the length of the entire list ——
getItemListTrueSize() Gets the actual length of [itemList] ——
getHeaderListTrueSize() Gets the actual length of [headerList] ——
getFooterListTrueSize() Gets the actual length of [footerList] ——
getHeaderTruePosition(position: Int) Gets the real position for [headerList] ——
getItemTruePosition(position: Int) Gets the real position for [itemList] ——
getFooterTruePosition(position: Int) Gets the real position for [footerList] ——
inHeaderList(position: Int) Check position within [headerList] ——
inItemList(position: Int) Check position within [itemList] ——
inFooterList(position: Int) Check position within [footerList] ——
setAfterDataChangeListener(listener: () -> Unit) Listening after list data changes, triggered after notify ——
enableDragOrSwipe(…) Set whether item can be deleted by dragging and sliding ——
onLoadMoreListener(…) Set up to load more listeners ——
holderConfig(…) Configure the holder to establish a match between the data class and the layout file ——
2) holderConfig list of configurable properties/methods
Property name/method name introduce The default value
sticky Whether this type of layout is top suction false
isFold Whether this type of layout supports expansion folding false
gridSpan The percentage of this type of layout in the grid 0
staggeredGridFullSpan Whether the staggeredGrid is full for this type of layout false
holderCreateListener This type of listener is created when Holder null
holderBindListener Listener for this type of Holder binding null
createBindingFun ViewBinding creation method, ViewBinding mode only null
variableId The corresponding data ID in XML, DataBinding schema only BR.item
YasuoNormalItem list of configurable properties/methods
Property name/method name introduce The default value
sticky Whether the item is at the top false
gridSpan The percentage of this item in the grid 0
staggeredGridFullSpan Whether the item is full in the staggeredGrid false
4) YasuoNormalItem list of configurable properties/methods
Property name/method name introduce The default value
list Next level list YasuoList()
isExpand Whether expanded false
parentHash Parent hash, which will not be assigned until expanded false
sticky Whether the item is at the top false
gridSpan The percentage of this item in the grid 0
staggeredGridFullSpan Whether the item is full in the staggeredGrid false

Three, endnotes

First of all, thank you for your reading. The Chinese New Year is coming. I wish you a happy New Year. If you like **YasuoRecyclerViewAdapter** this library, hope to give a star on Github, as my motivation for progress! If he has deficiencies or needs new functions, he can issue to me or add my QQ :876625596