https://github.com/ssseasonnn/yasha
A DSL library for rendering RecyclerView and ViewPager.
https://github.com/ssseasonnn/yasha
android dsl kotlin recyclerview viewpager
Last synced: 4 months ago
JSON representation
A DSL library for rendering RecyclerView and ViewPager.
- Host: GitHub
- URL: https://github.com/ssseasonnn/yasha
- Owner: ssseasonnn
- License: apache-2.0
- Created: 2018-06-04T07:16:15.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2023-11-02T09:42:12.000Z (almost 2 years ago)
- Last Synced: 2025-06-02T12:42:34.167Z (5 months ago)
- Topics: android, dsl, kotlin, recyclerview, viewpager
- Language: Kotlin
- Homepage:
- Size: 3.6 MB
- Stars: 524
- Watchers: 12
- Forks: 54
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README

# Yasha
A DSL library for rendering RecyclerView and ViewPager and Compose List.
> *Read this in other languages: [中文](README.zh.md), [English](README.md), [Changelog](CHANGELOG.md)*
## Feature introduction:
✅ Support RecyclerView
✅ Support ViewPager
✅ Support MultiType
✅ Support Header and Footer
✅ Support automatic paging loading
✅ Support DiffUtil
✅ Support loading status display
✅ Support automatic clean up resources
✅ Support Compose
## Prepare
1. Add jitpack to build.gradle
```gradle
allprojects {
repositories {
maven { url 'https://jitpack.io' }
}
}
```2. Add Dependencies
```gradle
dependencies {
implementation 'com.github.ssseasonnn:Yasha:1.2.0'
// or
implementation 'com.github.ssseasonnn.Yasha:yasha:1.2.0' //only for recyclerview
implementation 'com.github.ssseasonnn.Yasha:yasha-compose:1.2.0' //only for compose
}
```## Basic usage
### 1. Render RecyclerView
```kotlin
//Create data class
class RecyclerViewItem(val i: Int, val text: String = "") : YashaItem//Create DataSource
val dataSource = YashaDataSource()//Render RecyclerView
recyclerView.linear(dataSource) {
renderBindingItem {
onBind {
itemBinding.tvNormalContent.text = "position: $position, data: $data"
}
}
}
```### 2. Render ViewPager
```kotlin
//Create data class
class ViewPagerItem(val i: Int, val text: String = "") : YashaItem//Create DataSource
val dataSource = YashaDataSource()//Render ViewPager
viewPager.vertical(dataSource) {
renderBindingItem {
onBind {
itemBinding.tvNormalContent.text = "position: $position, data: $data"
}
}
}
```## Other configurations
### 1. Render Type
Yasha supports multiple types of RecyclerView, such as list, Grid, Stagger, Pager and custom list types
```kotlin
//Render List
recyclerView.linear(dataSource) {
//Set the direction to vertical list or horizontal list
orientation(RecyclerView.VERTICAL)
renderBindingItem {}
}//Render Grid
recyclerView.grid(dataSource) {
//Set the number of columns
spanCount(2)
renderBindingItem {
//Set the number of columns corresponding to this item
gridSpanSize(2)
onBind {}
}
}//Render waterfall flow
recyclerView.stagger(dataSource) {
//Set the number of columns
spanCount(2)
renderBindingItem {
staggerFullSpan(true)
onBind {}
}
}//Render Page
recyclerView.pager(dataSource) {
//Register page change callback
onPageChanged { position, yashaItem, view ->
Toast.makeText(this, "This is page $position", Toast.LENGTH_SHORT).show()
}
}//Render custom layout
recyclerView.custom(customLayoutManager, dataSource) {}
```### 2. DataSource paging load
```kotlin
class CustomDataSource(coroutineScope: CoroutineScope) : YashaDataSource(coroutineScope) {
var page = 0// Called when initializing the load
override suspend fun loadInitial(): List? {
page = 0val items = mutableListOf()
for (i in 0 until 10) {
items.add(NormalItem(i))
}// Return null to trigger loading failure
// Return to the empty list to trigger no more
// Return init data
return items
}// Called on paging load
override suspend fun loadAfter(): List? {
page++if (page % 5 == 0) {
// Return null to trigger loading failure
return null
}val items = mutableListOf()
for (i in 0 until 10) {
items.add(NormalItem(i))
}// Return to the empty list to trigger no more
return items
}
}
```### 3. Render MultiType
```kotlin
//Define data type A
class AItem(val i: Int) : YashaItem//Define data type B
class BItem(val i: Int) : YashaItem//Render Items
recyclerView.linear(dataSource) {
//Render Type A
renderBindingItem {
onBind {
//render
...
}
}
//Render Type B
renderBindingItem {
onBind {
//render
...
}
}
}
```### 4. Header and Footer
DataSource supports the following methods for adding headers and footers:
```kotlin
//Headers
fun addHeader(t: T, position: Int = -1, delay: Boolean = false)
fun addHeaders(list: List, position: Int = -1, delay: Boolean = false)
fun removeHeader(t: T, delay: Boolean = false)
fun setHeader(old: T, new: T, delay: Boolean = false)
fun getHeader(position: Int): T
fun clearHeader(delay: Boolean = false)//Footers
fun addFooter(t: T, position: Int = -1, delay: Boolean = false)
fun addFooters(list: List, position: Int = -1, delay: Boolean = false)
fun removeFooter(t: T, delay: Boolean = false)
fun setFooter(old: T, new: T, delay: Boolean = false)
fun getFooter(position: Int): T
fun clearFooter(delay: Boolean = false)
```### 5. Partial refresh
By rewriting the Diff method of the data class, you can complete efficient local refresh:
```kotlin
//Override Diff method when defining data type
class NormalItem(val i: Int, val text: String = "") : YashaItem {override fun areItemsTheSame(other: Differ): Boolean {
if (other !is NormalItem) return false
return other.i == i
}override fun areContentsTheSame(other: Differ): Boolean {
if (other !is NormalItem) return false
return other.text == text
}//Set up payload
override fun getChangePayload(other: Differ): Any? {
if (other !is NormalItem) return null
return other.text
}
}//Use dataSource to update the new Item data
val oldItem = NormalItem(1, "1")
val newItem = NormalItem(2, "2")
dataSource.setItem(oldItem, newItem)// Register onBindPayload at render time
recyclerView.linear(dataSource) {
renderBindingItem {
onBind {
itemBinding.tvNormalContent.text = "position: $position, data: $data"
}//Partial refresh use
onBindPayload {
//Take out payload for partial refresh
val payload = it[0]
if (payload != null) {
itemBinding.tvNormalContent.text = payload.toString()
}
}
}
}
```### 6. Custom Load Status
```kotlin
//Use default load state
val dataSource = YashaDataSource(enableDefaultState = true)//Custom LoadStateItem
class CustomStateItem(val state: Int) : YashaItem
class CustomDataSource : YashaDataSource(enableDefaultState = false) {override fun onStateChanged(newState: Int) {
setState(CustomStateItem(newState))
}
}//Render Custom State
recyclerView.linear(dataSource) {
...
renderBindingItem {
onBind {
when (data.state) {
FetchingState.FETCHING -> {
//loading...
}
FetchingState.FETCHING_ERROR -> {
//loading failed
}
FetchingState.DONE_FETCHING -> {
//loading complete
}
else -> {
//other
}
}
}
}
}
```### 7. Proguard
Only when using reflection to create ViewBinding, you need to add the following guard rules:
```pro
-keepclassmembers class * implements androidx.viewbinding.ViewBinding {
public static ** inflate(...);
}
```## License
> ```
> Copyright 2021 Season.Zlc
>
> 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.
> ```