{"id":28408716,"url":"https://github.com/ssseasonnn/yasha","last_synced_at":"2025-06-30T02:33:16.594Z","repository":{"id":62627752,"uuid":"135985766","full_name":"ssseasonnn/Yasha","owner":"ssseasonnn","description":"A DSL library for rendering RecyclerView and ViewPager.","archived":false,"fork":false,"pushed_at":"2023-11-02T09:42:12.000Z","size":3774,"stargazers_count":524,"open_issues_count":5,"forks_count":54,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-06-02T12:42:34.167Z","etag":null,"topics":["android","dsl","kotlin","recyclerview","viewpager"],"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/ssseasonnn.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2018-06-04T07:16:15.000Z","updated_at":"2025-04-26T14:08:11.000Z","dependencies_parsed_at":"2022-11-04T05:23:24.288Z","dependency_job_id":"f7d490c6-e786-49c4-9822-0d4a86c6e551","html_url":"https://github.com/ssseasonnn/Yasha","commit_stats":null,"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"purl":"pkg:github/ssseasonnn/Yasha","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssseasonnn%2FYasha","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssseasonnn%2FYasha/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssseasonnn%2FYasha/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssseasonnn%2FYasha/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ssseasonnn","download_url":"https://codeload.github.com/ssseasonnn/Yasha/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssseasonnn%2FYasha/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262698984,"owners_count":23350216,"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":["android","dsl","kotlin","recyclerview","viewpager"],"created_at":"2025-06-02T04:10:40.134Z","updated_at":"2025-06-30T02:33:16.583Z","avatar_url":"https://github.com/ssseasonnn.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"![](yasha.png)\n\n\u003cp align=\"left\"\u003e\n\t\u003cimg src=\"https://img.shields.io/badge/kotlin-1.8.0-green\"/\u003e\n\t\u003ca href=\"https://jitpack.io/#ssseasonnn/Yasha\"\u003e\n\t\t\u003cimg src=\"https://jitpack.io/v/ssseasonnn/Yasha.svg\"/\u003e\n\t\u003c/a\u003e\n\u003c/p\u003e\n\n# Yasha\n\nA DSL library for rendering RecyclerView and ViewPager and Compose List.\n\n\u003e *Read this in other languages: [中文](README.zh.md), [English](README.md), [Changelog](CHANGELOG.md)*\n\n## Feature introduction：\n\n✅ Support RecyclerView  \n✅ Support ViewPager  \n✅ Support MultiType  \n✅ Support Header and Footer  \n✅ Support automatic paging loading  \n✅ Support DiffUtil  \n✅ Support loading status display  \n✅ Support automatic clean up resources\n✅ Support Compose\n\n![](yasha_usage.png)\n\n## Prepare\n\n1. Add jitpack to build.gradle\n\n```gradle\nallprojects {\n    repositories {\n        maven { url 'https://jitpack.io' }\n    }\n}\n```\n\n2. Add Dependencies\n\n```gradle\ndependencies {\n\timplementation 'com.github.ssseasonnn:Yasha:1.2.0'\n\t\n\t// or\n\timplementation 'com.github.ssseasonnn.Yasha:yasha:1.2.0'  //only for recyclerview\n\timplementation 'com.github.ssseasonnn.Yasha:yasha-compose:1.2.0' //only for compose\n}\n```\n\n## Basic usage\n\n### 1. Render RecyclerView\n\n```kotlin\n//Create data class\nclass RecyclerViewItem(val i: Int, val text: String = \"\") : YashaItem\n\n//Create DataSource\nval dataSource = YashaDataSource()\n\n//Render RecyclerView\nrecyclerView.linear(dataSource) {\n    renderBindingItem\u003cRecyclerViewItem, ViewHolderNormalBinding\u003e {\n        onBind {\n            itemBinding.tvNormalContent.text = \"position: $position, data: $data\"\n        }\n    }\n}\n```\n\n### 2. Render ViewPager\n\n```kotlin\n//Create data class\nclass ViewPagerItem(val i: Int, val text: String = \"\") : YashaItem\n\n//Create DataSource\nval dataSource = YashaDataSource()\n\n//Render ViewPager\nviewPager.vertical(dataSource) {\n    renderBindingItem\u003cViewPagerItem, ViewHolderNormalBinding\u003e {\n        onBind {\n            itemBinding.tvNormalContent.text = \"position: $position, data: $data\"\n        }\n    }\n}\n```\n\n## Other configurations\n\n### 1. Render Type\n\nYasha supports multiple types of RecyclerView, such as list, Grid, Stagger, Pager and custom list types\n\n```kotlin\n//Render List\nrecyclerView.linear(dataSource) {\n    //Set the direction to vertical list or horizontal list\n    orientation(RecyclerView.VERTICAL)\n    renderBindingItem\u003cNormalItem, ViewHolderNormalBinding\u003e {}\n}\n\n//Render Grid\nrecyclerView.grid(dataSource) {\n    //Set the number of columns\n    spanCount(2)\n    renderBindingItem\u003cNormalItem, ViewHolderNormalBinding\u003e {\n        //Set the number of columns corresponding to this item\n        gridSpanSize(2)\n        onBind {}\n    }\n}\n\n//Render waterfall flow\nrecyclerView.stagger(dataSource) {\n    //Set the number of columns\n    spanCount(2)\n    renderBindingItem\u003cNormalItem, ViewHolderNormalBinding\u003e {\n        staggerFullSpan(true)\n        onBind {}\n    }\n}\n\n//Render Page\nrecyclerView.pager(dataSource) {\n    //Register page change callback\n    onPageChanged { position, yashaItem, view -\u003e\n        Toast.makeText(this, \"This is page $position\", Toast.LENGTH_SHORT).show()\n    }\n}\n\n//Render custom layout\nrecyclerView.custom(customLayoutManager, dataSource) {}\n```\n\n### 2. DataSource paging load\n\n```kotlin\nclass CustomDataSource(coroutineScope: CoroutineScope) : YashaDataSource(coroutineScope) {\n    var page = 0\n\n    // Called when initializing the load\n    override suspend fun loadInitial(): List\u003cYashaItem\u003e? {\n        page = 0\n\n        val items = mutableListOf\u003cYashaItem\u003e()\n        for (i in 0 until 10) {\n            items.add(NormalItem(i))\n        }\n\n        // Return null to trigger loading failure\n        // Return to the empty list to trigger no more\n        // Return init data\n        return items\n    }\n\n    // Called on paging load\n    override suspend fun loadAfter(): List\u003cYashaItem\u003e? {\n        page++\n\n        if (page % 5 == 0) {\n            // Return null to trigger loading failure\n            return null\n        }\n\n        val items = mutableListOf\u003cYashaItem\u003e()\n        for (i in 0 until 10) {\n            items.add(NormalItem(i))\n        }\n\n        // Return to the empty list to trigger no more\n        return items\n    }\n}\n```\n\n### 3. Render MultiType\n\n```kotlin\n\n//Define data type A\nclass AItem(val i: Int) : YashaItem\n\n//Define data type B\nclass BItem(val i: Int) : YashaItem\n\n//Render Items\nrecyclerView.linear(dataSource) {\n    //Render Type A\n    renderBindingItem\u003cAItem, AItemBinding\u003e {\n        onBind {\n            //render\n            ...\n        }\n    }\n    //Render Type B\n    renderBindingItem\u003cBItem, BItemBinding\u003e {\n        onBind {\n            //render\n            ...\n        }\n    }\n}\n```\n\n### 4. Header and Footer\n\nDataSource supports the following methods for adding headers and footers:\n\n```kotlin\n//Headers\nfun addHeader(t: T, position: Int = -1, delay: Boolean = false)\nfun addHeaders(list: List\u003cT\u003e, position: Int = -1, delay: Boolean = false)\nfun removeHeader(t: T, delay: Boolean = false)\nfun setHeader(old: T, new: T, delay: Boolean = false)\nfun getHeader(position: Int): T\nfun clearHeader(delay: Boolean = false)\n\n//Footers\nfun addFooter(t: T, position: Int = -1, delay: Boolean = false)\nfun addFooters(list: List\u003cT\u003e, position: Int = -1, delay: Boolean = false)\nfun removeFooter(t: T, delay: Boolean = false)\nfun setFooter(old: T, new: T, delay: Boolean = false)\nfun getFooter(position: Int): T\nfun clearFooter(delay: Boolean = false)\n```\n\n### 5. Partial refresh\n\nBy rewriting the Diff method of the data class, you can complete efficient local refresh:\n\n```kotlin\n//Override Diff method when defining data type\nclass NormalItem(val i: Int, val text: String = \"\") : YashaItem {\n\n    override fun areItemsTheSame(other: Differ): Boolean {\n        if (other !is NormalItem) return false\n        return other.i == i\n    }\n\n    override fun areContentsTheSame(other: Differ): Boolean {\n        if (other !is NormalItem) return false\n        return other.text == text\n    }\n\n    //Set up payload\n    override fun getChangePayload(other: Differ): Any? {\n        if (other !is NormalItem) return null\n        return other.text\n    }\n}\n\n//Use dataSource to update the new Item data\nval oldItem = NormalItem(1, \"1\")\nval newItem = NormalItem(2, \"2\")\ndataSource.setItem(oldItem, newItem)\n\n// Register onBindPayload at render time\nrecyclerView.linear(dataSource) {\n    renderBindingItem\u003cNormalItem, ViewHolderNormalBinding\u003e {\n        onBind {\n            itemBinding.tvNormalContent.text = \"position: $position, data: $data\"\n        }\n\n        //Partial refresh use\n        onBindPayload {\n            //Take out payload for partial refresh\n            val payload = it[0]\n            if (payload != null) {\n                itemBinding.tvNormalContent.text = payload.toString()\n            }\n        }\n    }\n}\n```\n\n### 6. Custom Load Status\n\n```kotlin\n//Use default load state\nval dataSource = YashaDataSource(enableDefaultState = true)\n\n//Custom LoadStateItem\nclass CustomStateItem(val state: Int) : YashaItem\nclass CustomDataSource : YashaDataSource(enableDefaultState = false) {\n\n    override fun onStateChanged(newState: Int) {\n        setState(CustomStateItem(newState))\n    }\n}\n\n//Render Custom State\nrecyclerView.linear(dataSource) {\n    ...\n    renderBindingItem\u003cCustomStateItem, CustomStateItemBinding\u003e {\n        onBind {\n            when (data.state) {\n                FetchingState.FETCHING -\u003e {\n                    //loading...\n                }\n                FetchingState.FETCHING_ERROR -\u003e {\n                    //loading failed\n                }\n                FetchingState.DONE_FETCHING -\u003e {\n                    //loading complete\n                }\n                else -\u003e {\n                    //other\n                }\n            }\n        }\n    }\n}\n```\n\n### 7. Proguard\n\nOnly when using reflection to create ViewBinding, you need to add the following guard rules:\n\n```pro\n-keepclassmembers class * implements androidx.viewbinding.ViewBinding {\n    public static ** inflate(...);\n}\n```\n\n## License\n\n\u003e ```\n\u003e Copyright 2021 Season.Zlc\n\u003e\n\u003e Licensed under the Apache License, Version 2.0 (the \"License\");\n\u003e you may not use this file except in compliance with the License.\n\u003e You may obtain a copy of the License at\n\u003e\n\u003e    http://www.apache.org/licenses/LICENSE-2.0\n\u003e\n\u003e Unless required by applicable law or agreed to in writing, software\n\u003e distributed under the License is distributed on an \"AS IS\" BASIS,\n\u003e WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\u003e See the License for the specific language governing permissions and\n\u003e limitations under the License.\n\u003e ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fssseasonnn%2Fyasha","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fssseasonnn%2Fyasha","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fssseasonnn%2Fyasha/lists"}