{"id":19462774,"url":"https://github.com/mvojtkovszky/properbaseadapter","last_synced_at":"2026-02-09T06:33:52.634Z","repository":{"id":41146571,"uuid":"262553974","full_name":"mvojtkovszky/ProperBaseAdapter","owner":"mvojtkovszky","description":"Straightforward, fast, easy to use and adaptable generic RecyclerView adapter allowing assembly of items in declarative way. Never create another RecyclerView adapter again.","archived":false,"fork":false,"pushed_at":"2024-11-05T10:28:04.000Z","size":837,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-13T06:44:23.625Z","etag":null,"topics":["adapteritem","android","android-library","declarative","declarative-ui","kotlin","recyclerview","recyclerview-adapter","recyclerview-multi-type","recyclerviewadapter","stickyheader"],"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/mvojtkovszky.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","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,"zenodo":null}},"created_at":"2020-05-09T11:15:59.000Z","updated_at":"2024-11-05T10:28:08.000Z","dependencies_parsed_at":"2025-04-15T02:44:39.119Z","dependency_job_id":"3ec127d3-e7f5-4699-993b-8d288ab0d720","html_url":"https://github.com/mvojtkovszky/ProperBaseAdapter","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/mvojtkovszky/ProperBaseAdapter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mvojtkovszky%2FProperBaseAdapter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mvojtkovszky%2FProperBaseAdapter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mvojtkovszky%2FProperBaseAdapter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mvojtkovszky%2FProperBaseAdapter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mvojtkovszky","download_url":"https://codeload.github.com/mvojtkovszky/ProperBaseAdapter/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mvojtkovszky%2FProperBaseAdapter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29258217,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-09T04:11:57.159Z","status":"ssl_error","status_checked_at":"2026-02-09T04:11:56.117Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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":["adapteritem","android","android-library","declarative","declarative-ui","kotlin","recyclerview","recyclerview-adapter","recyclerview-multi-type","recyclerviewadapter","stickyheader"],"created_at":"2024-11-10T18:05:28.901Z","updated_at":"2026-02-09T06:33:52.621Z","avatar_url":"https://github.com/mvojtkovszky.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ProperBaseAdapter\nStraightforward, fast, easy to use and adaptable generic RecyclerView adapter. Never create another RecyclerView adapter again.\n\u003cbr/\u003e\u003cbr/\u003e\n\u003cimg src=\"example.gif\" alt=\"Example Flow\" width=\"320\"/\u003e\n\n## How does it work?\n1. Define an AdapterItem representing an adapter item view type.\n``` kotlin\nclass ImageViewRecyclerItem(private val drawable: Drawable?): AdapterItem\u003cImageView\u003e() {\n    // here we define how view is created\n    override fun getNewView(parent: ViewGroup): ImageView {\n        return ImageView(parent.context)\n    }\n    // here we populate the view\n    override fun onViewBound(view: ImageView) {\n        view.setImageDrawable(drawable)\n        view.scaleType = ImageView.ScaleType.CENTER\n    }\n}\n```\nor inflate your own view.\n``` kotlin\nclass TextRowRecyclerItem(private val text: String): AdapterItem\u003cView\u003e() {\n    override fun getNewView(parent: ViewGroup): View {\n        return getViewFromLayout(parent, android.R.layout.activity_list_item)\n    }\n    override fun onViewBound(view: View) {\n        view.findViewById\u003cTextView\u003e(R.id.text1).text = text\n    }\n}\n```\n\nAdapterItem subscribes to callbacks you can override to fine-tune behaviour in different states.\n``` kotlin\noverride fun onItemViewAttached(view: YourView): Unit\noverride fun onItemViewDetached(view: YourView): Unit\noverride fun onItemViewRecycled(view: YourView): Unit\noverride fun onItemViewFailedToRecycle(view: YourView): Unit\n```\n\nand has a few public methods to help you fine tune behaviour of each item.\n``` kotlin\nfun getView(): YourView\nfun setAnimation(@AnimRes animation: Int): Unit\nfun setClickListener(clickListener: View.OnClickListener?): Unit\nfun setMargins(marginStart: Int = 0, marginTop: Int = 0, marginEnd: Int = 0, marginBottom: Int = 0): Unit\nfun setIsStickyHeader(isStickyHeader: Boolean)\nfun setViewTag(viewTag: Any?): Unit\n```\n\n\u003cbr/\u003e2. Have your Activity, Fragment or View implement BaseRecyclerViewImplementation .\n``` kotlin\nclass MainActivity : AppCompatActivity(), ProperBaseAdapterImplementation {\n  ...\n  // library needs to know how to locate a RecyclerView\n  override fun getRecyclerView(): RecyclerView? {\n        return findViewById(R.id.recyclerView)\n  }\n\n  // add items to provided data list, those will be added to the adapter.\n  override fun getAdapterData(data: MutableList\u003cAdapterItem\u003c*\u003e\u003e): MutableList\u003cAdapterItem\u003c*\u003e\u003e {\n    // let's say we want to display an image on top\n    data.add(ImageViewRecyclerItem(ContextCompat.getDrawable(this, android.R.drawable.btn_radio))\n        .withTopBottomMargins(topMargin = resources.getDimensionPixelSize(R.dimen.dp16))\n    // and add 10 text view items\n    for (i in 1..10) {\n        data.add(TextViewRecyclerItem(\"Text item $i\")\n            .withAllMargins(resources.getDimensionPixelSize(R.dimen.dp16))\n            .withAnimation(R.anim.item_fall_down)\n            .withClickListener(View.OnClickListener {\n                Toast.makeText(this, \"Clicked item $i\", Toast.LENGTH_SHORT).show()\n            }))\n    }\n    // and add another image on bottom\n    data.add(ImageViewRecyclerItem(ContextCompat.getDrawable(this, android.R.drawable.ic_btn_speak_now)))\n\n    return data\n  }\n  ...\n```\n\n\u003cbr/\u003e3. Simply calling refreshRecyclerView method will do the rest and populate recycler view with provided data.\n``` kotlin\noverride fun onCreate(savedInstanceState: Bundle?) {\n    super.onCreate(savedInstanceState)\n    setContentView(R.layout.activity_main)\n    refreshRecyclerView()\n}\n```\n\n\u003cbr/\u003eYou're of course not required use a provided BaseRecyclerViewImplementation and simply construct ProperBaseAdapter yourself and set it to your RecyclerView.\\\n\u003cbr/\u003eMake use of multiple adapter's public methods based on your needs:\n``` kotlin\nfun getItemAt(position: Int): AdapterItem\u003c*\u003e?\nfun getItemByViewTag(viewTag: Any): AdapterItem\u003c*\u003e?\nfun getItemTypeAt(position: Int): KClass\u003c*\u003e\nfun getPositionForItemWithViewTag(viewTag: Any): Int?\n\nfun addItems(data: List\u003cAdapterItem\u003c*\u003e\u003e, index: Int = data.size, notifyItemRangeChanged: Boolean = true): Unit\nfun setItems(data: List\u003cAdapterItem\u003c*\u003e\u003e, notifyDataSetChanged: Boolean = true): Unit\nfun updateItems(data: List\u003cAdapterItem\u003c*\u003e\u003e): Unit\nfun removeItems(fromPosition: Int, itemCount: Int = 1, notifyDataSetChanged: Boolean = true): Unit\nfun removeAllItems(notifyDataSetChanged: Boolean = true): Unit\n\nfun notifyItemWithViewTagChanged(viewTag: Any): Unit\nfun hasStickyHeaders(): Boolean\nfun setDefaultItemMargins(start: Int = 0, top: Int = 0, end: Int = 0, bottom: Int = 0): Unit\nfun setDefaultItemSideMargins(@Px startAndEnd: Int): Unit\n```\n\n## Nice! How do I get started?\nMake sure root build.gradle repositories include JitPack\n``` gradle\nallprojects {\n    repositories {\n        maven { url 'https://jitpack.io' }\n    }\n}\n```\n\nAnd ProperBaseAdapter dependency is added to app build.gradle\n``` gradle\ndependencies {\n    implementation \"com.github.mvojtkovszky:ProperBaseAdapter:$latest_version\"\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmvojtkovszky%2Fproperbaseadapter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmvojtkovszky%2Fproperbaseadapter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmvojtkovszky%2Fproperbaseadapter/lists"}