{"id":17982408,"url":"https://github.com/nekocode/items","last_synced_at":"2026-03-04T17:31:18.021Z","repository":{"id":98385526,"uuid":"65919473","full_name":"nekocode/Items","owner":"nekocode","description":"Generate data-view-binding adapters of android recycler view.","archived":false,"fork":false,"pushed_at":"2019-01-14T09:13:53.000Z","size":543,"stargazers_count":251,"open_issues_count":0,"forks_count":22,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-06-11T04:46:05.208Z","etag":null,"topics":["android"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nekocode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2016-08-17T15:32:55.000Z","updated_at":"2025-04-02T07:50:56.000Z","dependencies_parsed_at":"2023-04-26T08:33:57.539Z","dependency_job_id":null,"html_url":"https://github.com/nekocode/Items","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/nekocode/Items","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nekocode%2FItems","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nekocode%2FItems/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nekocode%2FItems/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nekocode%2FItems/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nekocode","download_url":"https://codeload.github.com/nekocode/Items/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nekocode%2FItems/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30087316,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T15:40:14.053Z","status":"ssl_error","status_checked_at":"2026-03-04T15:40:13.655Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android"],"created_at":"2024-10-29T18:14:10.907Z","updated_at":"2026-03-04T17:31:17.999Z","avatar_url":"https://github.com/nekocode.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Items\n\n[![Build Status](https://travis-ci.com/nekocode/Items.svg?branch=master)](https://travis-ci.com/nekocode/Items) [![codecov](https://codecov.io/gh/nekocode/Items/branch/master/graph/badge.svg)](https://codecov.io/gh/nekocode/Items)\n\n这个库可以为 Android 的 `RecyclerView` 生成基于 **Data-View-Binding** 的 Adapter。\n\n对比其他一些类似的开源库，它有以下的一些优势：\n* 更好的拓展性。这个库不需要你继承特定的 Adapter 或 ViewHolder 类，你可以继承任何第三方提供的基类；\n* 更好的性能。使用 Annotation Processor 意味着实现 Binding 时无需使用反射。支持 [增量处理](https://docs.gradle.org/current/userguide/java_plugin.html#sec:incremental_annotation_processing)；\n* 更低的侵入性。和传统的 Adapter 写法类似，可以快速从旧的 Codebase 迁移到新的写法；\n* 更可靠的代码。提供了单元测试覆盖大部分的 Case。\n\n## 集入\n\n替换以下代码中的 `${lastest-version}` 为最新版本号 [![](https://jitpack.io/v/nekocode/Items.svg)](https://jitpack.io/#nekocode/Items)，并复制到 Android 工程中的 build.gradle 脚本:\n\n```gradle\nrepositories {\n    maven { url \"https://jitpack.io\" }\n}\ndependencies {\n    implementation \"com.github.nekocode.Items:itemsLib:${lastest-version}\"\n    annotationProcessor \"com.github.nekocode.Items:itemsProcessor:${lastest-version}\"\n}\n```\n\n注意，在 Kotlin 工程中，需要使用 `kapt` 关键字代替 `annotationProcessor` 关键字。\n\n## 使用\n\n使用 `BaseItem` 能够帮助你把 `ViewHolder` 的创建和绑定从 Adapter 中提取出来，并且与特定的数据类型绑定。例如你可以为 `String` 类型的数据创建一个 Item：\n\n```java\npublic class StringItem extends BaseItem\u003cString, StringItem.Holder, StringItem.Callback\u003e {\n\n    public StringItem(ItemAdapter adapter, int viewType) {\n        super(adapter, viewType);\n    }\n\n    @NonNull\n    @Override\n    public Holder onCreateViewHolder(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent) {\n        final View itemView = inflater.inflate(R.layout.item_string, parent, false);\n        final Holder holder = new Holder(itemView);\n        holder.button.setOnClickListener(v -\u003e {\n            if (getCallback() != null) {\n                getCallback().onButtonClick(holder.data);\n            }\n        });\n        return holder;\n    }\n\n    @Override\n    public void onBindViewHolder(@NonNull Holder holder, int position, @NonNull String data) {\n        holder.data = data;\n        holder.textView.setText(data);\n    }\n\n    static class Holder extends RecyclerView.ViewHolder {\n        private TextView textView;\n        private Button button;\n        private String data;\n\n        Holder(View itemView) {\n            super(itemView);\n            textView = itemView.findViewById(R.id.textView);\n            button = itemView.findViewById(R.id.button);\n        }\n    }\n\n    public interface Callback {\n        void onButtonClick(@NonNull String data);\n    }\n}\n```\n\nItem 提供了很好的拓展能力：\n* 可以使用任意类型的 `ViewHolder`；\n* 可以通过 `Callback` 为 `ViewHolder` 设置 UI 事件回调。\n\n接下来你需要创建一个 Adapter 来装载你的所有 Item：\n\n```java\n@AdapterClass\npublic abstract class TestAdapter extends RecyclerView.Adapter\u003cRecyclerView.ViewHolder\u003e implements ItemAdapter {\n    private final LinkedList mList = new LinkedList();\n\n    @NonNull\n    public LinkedList list() {\n        return mList;\n    }\n\n    @Override\n    public int getItemCount() {\n        return mList.size();\n    }\n\n    @NonNull\n    @Override\n    public \u003cT\u003e T getData(int position) {\n        return (T) mList.get(position);\n    }\n\n    /**\n     * 定义一个任意名称的方法来返回你想装载的 Item\n     */\n    @NonNull\n    @ItemMethod\n    public abstract StringItem stringItem();\n}\n```\n\n这个 Adapter 必须实现 `ItemAdapter` 接口的 `getItemCount()` 和 `getData()` 方法。你可以使用任意类型的 Collection（例如上面的 `LinkedList`）来装载你的数据，这个 Adapter 会通过这两个方法来访问你的数据，然后根据数据的类型来选择对应的 Item 来创建 `ViewHolder`。\n\n在编译期间，Annotation Processor 会为这个 Adapter 生成一个实现类 `TestAdapterImpl`，你可以通过以下例子来使用这个 Adapter：\n\n```java\n// 创建 Adapter 实例\nTestAdapter adapter = new TestAdapterImpl();\n\n// 给 Adapter 插入数据\nadapter.list().add(\"Item1\");\nadapter.list().add(\"Item2\");\n\n// 给 Item 设置 Callback\nadapter.stringItem().setCallback(data -\u003e {\n    // Button 点击时\n});\n\n// 为 RecyclerView 设置 Adapter\nrecyclerView.setAdapter(adapter);\n```\n\n以上就是这个工具的基础使用。\n\n此外，你还可以让你的单个数据类型绑定多个 Item：\n\n```java\n@Adapter\npublic abstract class TestAdapter extends RecyclerView.Adapter\u003cRecyclerView.ViewHolder\u003e implements ItemAdapter {\n    // ...\n\n    @NonNull\n    @ItemMethod\n    public abstract StringItem stringItem();\n\n    @NonNull\n    @ItemMethod\n    public abstract StringItem2 stringItem2();\n\n    /**\n     * 定义一个任意名称的方法来帮助 Adapter 选择绑定了同一数据类型的 Item\n     */\n    @SelectorMethod\n    public int itemForString(int position, @NonNull String data) {\n        if (!data.endsWith(2)) {\n            return stringItem().getViewType();\n        } else {\n            return stringItem2().getViewType();\n        }\n    }\n}\n```\n\n最后，还有一个小的 Tip。你可以定义一些 BaseAdapter 来简化你 Adapter 的代码，例如把对集合的操作封装起来，举个例子：\n\n```java\npublic abstract class BaseArrayListAdapter extends RecyclerView.Adapter\u003cRecyclerView.ViewHolder\u003e implements ItemAdapter {\n    private final ArrayList mList = new ArrayList();\n\n    public ArrayList getList() {\n        return mList;\n    }\n\n    @NonNull\n    @Override\n    public \u003cT\u003e T getData(int position) {\n        return (T) mList.get(position);\n    }\n\n    @Override\n    public int getItemCount() {\n        return mList.size();\n    }\n}\n\n@Adapter\npublic abstract class TestAdapter extends BaseArrayListAdapter {\n    // ...\n}\n```\n\n更详细的应用可以参考这个仓库中的 [exampleApp](exampleApp) 模块。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnekocode%2Fitems","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnekocode%2Fitems","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnekocode%2Fitems/lists"}