GithubHelp home page GithubHelp logo

nukc / recycleradapter Goto Github PK

View Code? Open in Web Editor NEW
28.0 2.0 3.0 1.27 MB

简单易懂的 RecyclerView adapter 封装

License: Apache License 2.0

Java 6.69% Kotlin 93.31%
recycleradapter adapter kotlin dsl viewbinding

recycleradapter's Introduction

RecyclerAdapter

简单易懂的 RecyclerView 通用 adapter 封装

Intention

需要迁移到 AndroidX,封装实现方法很简单,代码也很少。

Installation

Add it in your root build.gradle at the end of repositories:

	allprojects {
		repositories {
			...
			maven { url 'https://jitpack.io' }
		}
	}

add the dependency to your build.gradle:

kotlinx.android.synthetic (LayoutContainer) Version: v1.0

    // ViewBinding Version
    implementation 'com.github.nukc:RecyclerAdapter:dsl-v1.2.1'

Usage

DSL 写法

// 返回 adapter
recycler_view.setup(LinearLayoutManager(this)) {
    hasStableIds = true
    
    renderItem<Int, ItemPureBinding> {
    	res(R.layout.item_pure)
        getViewBinding = {
            ItemPureBinding.bind(it)
        }
    }
    
    renderItem<NumberItem, ItemLeftBinding> {
        res(R.layout.item_left, R.layout.item_right) // 支持同个类型多个布局
        getViewBinding = {
            ItemLeftBinding.bind(it)
        }
        getItemViewType {
            when (data.number % 2) {
                0 -> R.layout.item_left
                else -> R.layout.item_right
            }
        }
        bind {
            // 可在这里更新视图
            binding.tvText.text = data.number.toString()
        }
        partialUpdate {
            // payloads 不为空的时候,在此局部更新
        }
    }
    
    renderItem<List<Banner>, ViewBannerBinding> {
        type = Banner::class.java  // 当 item 的数据是数组,需要设置 type
        getViewBinding = {
            ViewBannerBinding.bind(it)
        }
        res(R.layout.view_banner) {
            // 可在这里对试图进行设置,比如点击事件
        }
        bind {
           // ...
        }
        
        // ... 还有对应 Adapter 的其它一些方法
    }
    
}

常规写法

recycler_view.adapter = RecyclerAdapter.explosion()
            .register(bannerProvider)
            .register(chosenProvider)
            .register(object : PureLayoutProvider<Int>(Integer::class.java) {
                override fun getLayoutResId(): Int {
                    return R.layout.item_pure
                }

                override fun initHolder(holder: RecyclerView.ViewHolder, itemView: View) {
                    itemView.findViewById<View>(R.id.layout_likest).setOnClickListener {
                        // do something
                    }
                    // ..
                }
            })
            .register(multiProvider)
            .setItems(arrayListOf(banners, arrayListOf(chosen), 1))
            .build()

Provider

BaseProvider,以下为具体实现类

  • PureLayoutProvider 纯布局,不用绑定数据

  • SimpleProvider 不想自定义 ViewHolder(在 bind() 方法中 findViewById)

  • HolderProvider 大多数需求都可直接用此 Provider

  • MultiTypeProvider 遇到同个数据类型且有多个 viewType 的时候(比如聊天界面)

PureLayoutProvider

	object : PureLayoutProvider<Int>(Integer::class.java) {
                override fun getLayoutResId(): Int {
                    return R.layout.item_pure
                }

                override fun initHolder(holder: RecyclerView.ViewHolder, itemView: View) {
                    itemView.findViewById<View>(R.id.layout_likest).setOnClickListener {
                        // do something
                    }
                    // ..
                }
            }

MultiProvider

Model and Viewholder

public class NumberItem {
    private int number;

    public NumberItem(int number) {
        this.number = number;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }
}
private class MultiHolder(view: View) : RecyclerView.ViewHolder(view) {
    val tvText: TextView = view.findViewById(R.id.tv_text)
    var data: NumberItem? = null

    init {
        itemView.setOnClickListener {
            data?.let {
                // do something
            }
        }
    }
}

provider

    private val multiProvider = object
        : MultiTypeProvider<NumberItem, MultiHolder>(NumberItem::class.java) {
        /**
        * 需要先提供全部类型的 layoutResId
        * @see Builder.register
        */
        override fun providerAllLayoutResId(): IntArray {
            return intArrayOf(R.layout.item_left, R.layout.item_right)
        }

        /**
        * 根据 position 或 data 返回该位置的 layoutResId,同时当做该 item 的 view Type
        * @see RecyclerAdapter.getItemViewType
        */
        override fun getLayoutResId(position: Int, data: NumberItem): Int {
            return when (data.number % 2) {
                0 -> R.layout.item_left
                else -> R.layout.item_right
            }
        }

        /**
        * 可根据 viewType 返回 ViewHolder
        * @param itemView Inflate a new view hierarchy from the viewType
        * @param viewType = getLayoutResId
        */
        override fun provideHolder(itemView: View, viewType: Int): MultiHolder {
            return MultiHolder(itemView)
        }

        override fun bind(holder: MultiHolder, data: NumberItem) {
            holder.data = data
            holder.tvText.text = data.number.toString()
        }

    }

Other methods

Provider: 其它一些可覆写方法

fun getItemId(position: Int): Long = position.toLong()
fun onViewRecycled(holder: VH)
fun onFailedToRecycleView(holder: VH): Boolean = false
fun onViewAttachedToWindow(holder: VH)
fun onViewDetachedFromWindow(holder: VH)

Adapter: 之后都执行响应的 notify 方法

方法名 备注
refresh(items) 清空原先的数据再加入新的数据后刷新
add(position, item) 在指定位置插入
add(item) 在最后位置插入
addAll(positionStart, items) 在指定开始位置插入一个集合
addAll(items) 在最后位置插入一个集合
move(fromPosition, toPosition) 把 fromPosition 的 item 移动到 toPosition
change(position, item) 改变指定位置的数据,然后刷新 item
remove(position) 移除指定位置的 item
clear() 清空

License

Apache License, Version 2.0

recycleradapter's People

Contributors

nukc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.