Giter VIP home page Giter VIP logo

panpf / assembly-adapter Goto Github PK

View Code? Open in Web Editor NEW
179.0 9.0 34.0 3.02 MB

AssemblyAdapter 是 Android 上的一个为各种 Adapter 提供开箱即用实现的库。AssemblyAdapter is a library on Android that provides out-of-the-box implementations for various Adapters.

License: Apache License 2.0

Kotlin 100.00%
android recyclerview-adapter listview-adapter viewpager-adapter adapter recyclerview-divider multi-type-adapter

assembly-adapter's Introduction

AssemblyAdapter

Platform API Release License

AssemblyAdapter 是 Android 上的一个为各种 Adapter 提供开箱即用实现的库。

特性

  • Item 复用. 只需为你的 item 写一个 ItemFactory,然后就可以到处使用了. 了解更多
  • 支持多类型. 只需给 Adapter 添加多个 ItemFactory 即可轻松实现多类型 Adapter
  • 支持全部 Adapter. 支持 BaseAdapterRecyclerView.Adapter 等常用 Adapter. 了解更多
  • 更多 ConcatAdapter 支持. 为 BaseAdapter 等更多 Adapter 提供了 Concat 支持. 了解更多
  • 支持 Paging. 为 Paging 提供了多类型支持. 了解更多
  • 支持 ViewPager 和 ViewPager2. 为 ViewPager 和 ViewPager2 提供了多类型及 Paging 分页支持. 了解更多
  • 支持 spanSize 和 fullSpan. 提供了专用的 LayoutManager,可以根据 ItemFactory 设置 spanSize 和 fullSpan. 了解更多
  • 支持 divider. 为 RecyclerView 提供了强大的 divider 支持,还可以根据 position/spanIndex/ItemFactory 个性化或禁用 divider. 了解更多
  • 支持占位符 Placeholder. 通过固定的占位符数据类型支持占位符. 了解更多

导入

该库已发布到 mavenCentral

你可以直接导入所有模块,如下:

dependencies {
    implementation("io.github.panpf.assemblyadapter4:assemblyadapter:${LAST_VERSION}")
}

你还可以按需导入所需模块,如下:

dependencies {
    implementation("io.github.panpf.assemblyadapter4:assemblyadapter-list:${LAST_VERSION}")
    implementation("io.github.panpf.assemblyadapter4:assemblyadapter-pager:${LAST_VERSION}")
    implementation("io.github.panpf.assemblyadapter4:assemblyadapter-pager2:${LAST_VERSION}")
    implementation("io.github.panpf.assemblyadapter4:assemblyadapter-pager2-paging:${LAST_VERSION}")
    implementation("io.github.panpf.assemblyadapter4:assemblyadapter-recycler:${LAST_VERSION}")
    implementation("io.github.panpf.assemblyadapter4:assemblyadapter-recycler-paging:${LAST_VERSION}")
}

每个模块包含哪些 Adapter,可以参考后面 '支持的 Adapter' 部分

${LAST_VERSION}Release Version (no include 'v')

使用指南

在传统的自定义 Adapter 的过程中我们一般需要以下几个步骤(以 RecyclerView.Adapter 为例,其它 Adapter 大同小异):

  1. 定义 data 列表
  2. 重写 getItemCount、getItemId 方法
  3. 重写 getItemViewType、onCreateViewHolder、onBindViewHolder 方法根据不同的 data 提供不同的结果或实现

AssemblyAdapter 将这一传统定义过程拆分为两个组件,其职责分别如下:

  1. Adapter:
    • 定义 data 列表
    • 重写 getItemCount、getItemId 方法
    • 根据不同的 data 匹配不同的 ItemFactory
    • 使用匹配的 ItemFactory 重写 getItemViewType、onCreateViewHolder、onBindViewHolder 方法
  2. ItemFactory
    • 定义目标 data 的 class
    • 创建 item view
    • 绑定 data

支持的 Adapter

AssemblyAdapter 只是一个接口,不可以直接使用,你需要针对不同的 Adapter 使用具体的实现类,如下所示:

定义 ItemFactory

下面演示继承 BindingItemFactory 来定义我们的 ItemFactory

更多自定义 ItemFactory 详细内容请参考 ItemFactory 自定义详解

item 布局定义如下 (item_app_info.xml):

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <TextView android:id="@+id/appItemNameText" />
    <TextView android:id="@+id/appItemVersionText" />
    <TextView android:id="@+id/appItemSizeText" />
</androidx.constraintlayout.widget.ConstraintLayout>

数据类定义如下:

data class AppInfo(
    val name: String,
    val packageName: String,
    val versionName: String,
    val apkSize: Long,
)
class AppInfoItemFactory : BindingItemFactory<AppInfo, ItemAppInfoBinding>(AppInfo::class) {

    override fun createItemViewBinding(
        context: Context, inflater: LayoutInflater, parent: ViewGroup
    ): ItemAppInfoBinding {
        /*
         * 在此处创建 ViewBinding。这个方法只执行一次
         */
        return ItemAppInfoBinding.inflate(inflater, parent, false)
    }

    override fun initItem(
        context: Context, binding: ItemAppInfoBinding, item: BindingItem<AppInfo, ItemAppBinding>
    ) {
        /*
         * 在此处初始化 item 并绑定 click 事件。这个方法只执行一次
         */
        binding.root.setOnClickListener {
            // 事件发生时从 item 获取 position 和 数据
            val data: AppInfo = item.dataOrThrow
            val bindingAdapterPosition: Int = item.bindingAdapterPosition
            val absoluteAdapterPosition: Int = item.absoluteAdapterPosition
            val launchIntent =
                context.packageManager.getLaunchIntentForPackage(data.packageName)
            if (launchIntent != null) {
                context.startActivity(launchIntent)
            }
        }
    }

    override fun bindItemData(
        context: Context,
        binding: ItemAppInfoBinding,
        item: BindingItem<AppInfo, ItemAppInfoBinding>,
        bindingAdapterPosition: Int,
        absoluteAdapterPosition: Int,
        data: AppInfo
    ) {
        /*
         * 在此处绑定 item view 的数据。这个方法会经常执行
         */
        binding.appItemNameText.text = data.name
        binding.appItemVersionText.text = "v${data.versionName}"
        binding.appItemSizeText.text = Formatter.formatFileSize(context, data.apkSize)
    }
}

使用 ItemFactory 创建多类型 Adapter

只需在创建 Adapter 时通过构造函数传入 ItemFactory 即可,传入多个 ItemFactory 就可以实现多类型 Adapter,如下:

// ListSeparatorItemFactory 是一个列表分割符 ItemFactory 具体实现就不写了
val appAdapter = AssemblyRecyclerAdapter(
    listOf(AppInfoItemFactory(), ListSeparatorItemFactory())
)

appAdapter.submitList(
    listOf(
        ListSeparator("A"),
        AppInfo("AirPortal", "cn.airportal", "4.21", 1258291L),
        AppInfo("Apex Legends Mobile", "com.ea.gp.apex", "1.2", 100258291L),
        AppInfo("APKPure", "com.apkpure.aegon", "3.17.23", 157879798L),
        ListSeparator("B"),
        AppInfo("Block Earth", "com.craft.earth", "2.42", 57879798L),
        AppInfo("Bluestack", "app.bluestack", "1.0.0", 41534523L),
        ListSeparator("C"),
        AppInfo("Craft Pixel Art Rain", "com.lucky.fairy", "15", 4247204L),
        AppInfo("Cutting Edge!", "com.cuttingedge", "0.16", 4289472412L),
        AppInfo("Cyber Knights", "com..cyberknightselite", "2.9.4", 6174924L),
        AppInfo("Guardians", "com.emagroups.cs", "1.2.3", 7782423L),
    )
)

RecyclerView(activity).adapter = appAdapter

更多功能

更新日志

Please view the CHANGELOG.md file

License

Copyright (C) 2021 panpf <[email protected]>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

assembly-adapter's People

Contributors

panpf 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  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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

assembly-adapter's Issues

很不错,先感谢一下作者的贡献

首先很多的Adapter开源项目的封装太臃肿了,很多功能是多余的,就比如说下拉刷新的功能,我觉得这个完全是多余的功能,下拉刷新为什么要封装到适配器里面,用自带的SwipeRefreshLayout就挺好的,还有很多开源的下拉刷新的库,Adapter里面有一个加载更多的功能就非常好了,希望作者不要加入下拉刷新的功能,还有多布局的功能,其实RecyclerView本身的多布局的实现就不是很复杂,只需要重写一个getItemViewType方法即可,希望对多布局这一块也能够保持原生的实现步骤,如果对原生的一些方法改造幅度过大,对开发人员来说并不是一件好事

是来赞的

开一条issue,就是想说,可组装化这思路真是不错!!

不过对于点击事件还有优化的空间,可以往这方面优化一下,个人建议,不需要点击事件放在Item里,不考虑长按情况的话点击事件无非就两种:1、整个列表而言单个item的点击事件;2、每个Item中Child View的点击事件;放眼Activity来看,如果把点击事件放在你现在的Demo中示例的AssemblyItemFactory的子类,势必会造成Activity需要实现多个接口来完成点击后的逻辑,建议为:对于点击事件的接口,可以定义为通用且统一接口,置于最高级别的基类AssemblyAdapter或者AssemblyItem, 另:这两种基类还需要进一步往通用化的功能完善。

加载更多

就是加载能不能到底自动加载数据,而不是点击一下在加载更多,大多数用户都是习惯拉倒底部自动显示加载更多数据

很酷,有个小问题:加载更多有些不自然

加载更多有些不自然:加载更多得到增加的数据后,刷新数据会导致原先的最后一项消失然后又重新添加到列表内。另外,新增加的内容添加后列表也会向下滑动,希望能改进

减少实现的方法数

将AssemblyItem等类的 onFindViews(), onConfigViews(Context var1)改为默认实现,不需要在子类强制实现。子类按需重写。另外findViewById(int id)方法改为泛型自动转换类型。

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.