{"id":17688682,"url":"https://github.com/boybeak/anyadapter","last_synced_at":"2026-02-18T15:31:54.033Z","repository":{"id":87642731,"uuid":"231913281","full_name":"boybeak/AnyAdapter","owner":"boybeak","description":"An adapter that can work for all kind of data.","archived":false,"fork":false,"pushed_at":"2022-07-21T06:43:02.000Z","size":4373,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-13T00:48:22.635Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/boybeak.png","metadata":{"files":{"readme":"README-CN.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-01-05T12:23:48.000Z","updated_at":"2021-12-26T07:14:48.000Z","dependencies_parsed_at":null,"dependency_job_id":"531e3b80-c13a-4ac3-ae1a-b77584652dc6","html_url":"https://github.com/boybeak/AnyAdapter","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boybeak%2FAnyAdapter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boybeak%2FAnyAdapter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boybeak%2FAnyAdapter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boybeak%2FAnyAdapter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/boybeak","download_url":"https://codeload.github.com/boybeak/AnyAdapter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253850882,"owners_count":21973672,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-10-24T11:45:04.347Z","updated_at":"2025-10-13T14:07:04.531Z","avatar_url":"https://github.com/boybeak.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AnyAdapter [ ![Download](https://api.bintray.com/packages/boybeak/nulldreams/any-adapter/images/download.svg) ](https://bintray.com/boybeak/nulldreams/any-adapter/_latestVersion)\n\n## 安装\n\n```groovy\nbuildscript {\n  repositories {\n        jcenter()\n    }\n}\n```\n\n```groovy\nimplementation 'com.github.boybeak:any-adapter:version'\n```\n\n\u003cimg src=\"https://github.com/boybeak/AnyAdapter/blob/master/gif/list.png\" width=\"360\" height=\"640\"/\u003e\n\n## 使用\n\n```kotlin\nval adapter = new AnyAdapter()\n// Or you can use FooterAdapter, AutoFooterAdapter\nrecyclerView.adapter = adapter\n```\n\n你的model类必须被 `ItemImpl\u003cT\u003e`所包裹. `T`就是你要展现的数据. AnyAdapter 只接受 `ItemImpl`的子类作为其中的Item, 实际上，继承 `AbsItem`会更方便.\n\n```kotlin\n// A data example.\ndata class Post(val id: Int, val title: String, val text: String)\n```\n\n```kotlin\n// An item example.\nclass PostItem(post: Post) : AbsItem\u003cPost\u003e(post) {\n\toverride fun layoutId(): Int {\n        return R.layout.xxx\n    }\n\n    override fun holderClass(): Class\u003cPostHolder\u003e {\n        return PostHolder::class.java\n    }\n\n    override fun areContentsSame(other: ItemImpl\u003c*\u003e): Boolean {\n        if (other is PostItem) {\n            val os = other.source()\n            return source().id == os.id \u0026\u0026 source().title == os.title \n          \t\t\u0026\u0026 source().text == os.text\n        }\n        return false\n    }\n}\n```\n\n```kotlin\n// A holder example\nclass PostHolder(v: View) : AbsHolder\u003cPostItem\u003e(v) {\n  override fun onBind(item: JourneyItem, position: Int, absAdapter: AnyAdapter) {\n    // Fill content to the view.\n  }\n}\n```\n\n\n\n### Add and addAll\n\n#### add\n\n```kotlin\nval post = xxx\nadapter.add(PostItem(post))\n// Or adapter.add(position, PostItem(post))\n```\n\n这是一个非常典型的 `add` 操作. 再也不用执行 **notifyDataXXXChanged** 操作了. 数据刷新是自动完成的.\n\n另外一个 **one-to-many** 添加函数能够将一个单一数据转换成一组数据添加进来.\n\n```kotlin\nadapter.add(post, object : IConverter\u003cPost, TextItem\u003e {\n  override fun convert(s: Post): List\u003cTextItem\u003e {\n    return mutableListOf(\n      TextItem(s.title), TextItem(s.text)\n    )\n  }\n})\n```\n\n\n\n#### addAll\n\n```kotlin\nval posts = ArrayList\u003cPost\u003e();\nval postItems = List(posts.size) { index -\u003e\n  PostItem(posts[index])\n}\n// Fill data to post\nadapter.addAll(postItems)\n// Or adapter.add(position, postItems)\n```\n\n实际上，你可以使用更为方便快捷的方式，如下:\n\n```kotlin\nadapter.addAll(posts, object : AnyAdapter.IEachConverter\u003cPost, PostItem\u003e {\n  override fun convert(s: Post, position: Int): PostItem {\n    return PostItem(s)\n  }\n})\n/* With lamada\n* adapter.addAll(posts) { s, position -\u003e\n\tPostItem(s)\n}\n*/\n```\n\n\n\n### Remove\n\n**单个删除**\n\n使用  `remove(Int)` 或者 `remove(Item)`.\n\n**多个删除**\n\n删除数据集合, 使用 `removeAll(Collection\u003cItem\u003e)`;\n\n条件删除, 使用 `removeBy(IFilter)`;\n\n类型条件删除, 使用 `removeBy(Class\u003cItem\u003e, IFilter)`;\n\n类型删除, 使用 `removeAll(Class\u003cItem\u003e)`;\n\n删除所有, 使用 `clear()`;\n\n\n\n### Replace\n\n`replace(position, item)`.\n\n\n\n### FilterRun\n\n`filterRun(IFilter, IRun)` - 如果`IFilter`返回true, 则执行 `IRun`;\n\n`filterRun(Class\u003cItem\u003e, IFilter, IRun)` - 如果是 `Class\u003cItem\u003e` 类型并且 `IFilter`返回true, 执行 `IRun` ;\n\n\n\n### Selector\n\n内置两个选择器, `SingleSelector` 和 `MultipleSelector`. \n\n你可以通过 `singleSelectorFor(Class\u003cItem\u003e)` 或者 `multipleSelectorFor(Class\u003cItem\u003e)`来获取对应的选择器. 当第一次调用 `SingleSelector` 或者 `MultipleSelector` 的时候，对应的实例将被创建. \n\n\u003e  在使用选择功能前, 请确保你的item class支持选择. 在你的item class中重写 **supportSelect** 方法并且返回true.\n\n在调用 `select`前，先调用 `begin()`  以确保选择器进去选择状态.\n\n```kotlin\nval selector = adapter.singleSelectorFor(Post::class.java)\nselector.begin()\nselector.select(0) // Select the 0 item\nselector.remove() // Remove the selected item\n```\n\n执行相关操作后, 调用 `end()`结束选择状态.\n\n\n\n### Sort\n\n```kotlin\nadapter.sortWith(Comparator\u003cSongItem\u003e{ o1, o2 -\u003e\n    o1.source().title.compareTo(o2.source().title)\n})\n```\n\n\n\n\n\n### OnClick and OnLongClick\n\n**OnClick**\n\n```kotlin\nadapter.setOnClickFor(PostItem::class.java, object : OnClick\u003cPostItem\u003e {\n  override fun getClickableIds() {\n    return intArrayOf(0, R.id.post_title) // 0 for the itemView\n  }\n  override fun onClick(view: View, item: PostItem, position: Int, adapter: AnyAdapter) {\n    when(view.id) {\n      R.id.post_title -\u003e {\n        \n      }\n      else -\u003e {\n        // Do item click here\n      }\n    }\n  }\n})\n```\n\n如果你只想为整个item设置点击事件, 你可以直接使用 `OnItemClick` . 不用再重写 *getClickableIds*.\n\n\n\n**OnLongClick**\n\n```kotlin\nadapter.setOnLongClickFor(PostItem::class.java, object : OnClick\u003cPostItem\u003e {\n  override fun getLongClickableIds() {\n    return intArrayOf(0, R.id.post_title) // 0 for the itemView\n  }\n  override fun onLongClick(view: View, item: PostItem, position: Int, adapter: AnyAdapter): Boolean {\n    when(view.id) {\n      R.id.post_title -\u003e {\n        \n      }\n      else -\u003e {\n        // Do item click here\n      }\n    }\n    return true\n  }\n})\n```\n\n如果你只想为整个item设置长按事件, 你可以直接使用 `OnItemLongClick`. 无需再重写 *getLongClickableIds*.\n\n\u003e 如果点击事件和长按事件都要设置，你可以使用 `OnItemEvent` ，既是 `OnItemClick` 又是 `OnItemLongClick`.\n\n另外一种方法，可以在创建adapter时候直接设置相关事件。\n\n```kotlin\nprivate val adapter = AutoFooterAdapter(FooterItem(Footer()))\n        .withOnClicks(\n            object : AbsOnItemClick\u003cSongItem\u003e(SongItem::class.java) {\n                override fun onItemClick(\n                    view: View,\n                    item: SongItem,\n                    position: Int,\n                    adapter: AnyAdapter\n                ) {\n                    TODO(\"Not yet implemented\")\n                }\n            }\n        )\n        .withOnLongClicks(\n            \n        )\n```\n\n# One more thing!!!\n\n你可以使用 [AnyAdapterPlugin](https://github.com/boybeak/AnyAdapterPlugin) 来产生 `item` `holder` 对, 如果你使用了viewBinding，还可以在holder类中，添加对应的binding对象.\n\n\u003cimg src=\"https://github.com/boybeak/AnyAdapter/blob/master/menu_create_item_and_holder.png\" width=\"249\" height=\"645\"/\u003e\n\n\u003cimg src=\"https://github.com/boybeak/AnyAdapter/blob/master/any_adapter_plugin.png\" width=\"426\" height=\"284\"/\u003e\n\n\u003cimg src=\"https://github.com/boybeak/AnyAdapter/blob/master/menu_create_binding.png\" width=\"311\" height=\"484\"/\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fboybeak%2Fanyadapter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fboybeak%2Fanyadapter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fboybeak%2Fanyadapter/lists"}