• Stars
    star
    522
  • Rank 81,667 (Top 2 %)
  • Language
    Kotlin
  • License
    Apache License 2.0
  • Created almost 6 years ago
  • Updated 6 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A DSL library for rendering RecyclerView and ViewPager.

Yasha

A DSL library for rendering RecyclerView and ViewPager.

Read this in other languages: ไธญๆ–‡, English, Changelog

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

Prepare

  1. Add jitpack to build.gradle
allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}
  1. Add Dependencies
dependencies {
	implementation 'com.github.ssseasonnn:Yasha:1.1.5'
}

Basic usage

1. Render RecyclerView

//Create data class
class RecyclerViewItem(val i: Int, val text: String = "") : YashaItem

//Create DataSource
val dataSource = YashaDataSource()

//Render RecyclerView
recyclerView.linear(dataSource){
    renderBindingItem<RecyclerViewItem, ViewHolderNormalBinding> {
        onBind {
            itemBinding.tvNormalContent.text = "position: $position, data: $data"
        }
    }
}

2. Render ViewPager

//Create data class
class ViewPagerItem(val i: Int, val text: String = "") : YashaItem

//Create DataSource
val dataSource = YashaDataSource()

//Render ViewPager
viewPager.vertical(dataSource){
    renderBindingItem<ViewPagerItem, ViewHolderNormalBinding> {
        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

//Render List
recyclerView.linear(dataSource){
	//Set the direction to vertical list or horizontal list
	orientation(RecyclerView.VERTICAL)
	renderBindingItem<NormalItem, ViewHolderNormalBinding> {}
}

//Render Grid
recyclerView.grid(dataSource){
	//Set the number of columns
	spanCount(2)  
	renderBindingItem<NormalItem, ViewHolderNormalBinding> {  
		//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<NormalItem, ViewHolderNormalBinding> {  
	    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

class CustomDataSource(coroutineScope: CoroutineScope) : YashaDataSource(coroutineScope) {
    var page = 0

    // Called when initializing the load
    override suspend fun loadInitial(): List<YashaItem>? {
        page = 0
    
        val items = mutableListOf<YashaItem>()
        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<YashaItem>? {
        page++

        if (page % 5 == 0) {
            // Return null to trigger loading failure
            return null  
        }

        val items = mutableListOf<YashaItem>()
        for (i in 0 until 10) {
            items.add(NormalItem(i))
        }

        // Return to the empty list to trigger no more
        return items
    }
}

3. Render MultiType

//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<AItem, AItemBinding> {
        onBind {
            //render
            ...
        }
    }
    //Render Type B
    renderBindingItem<BItem, BItemBinding> {
        onBind {
            //render
            ...
        }
    }
}

4. Header and Footer

DataSource supports the following methods for adding headers and footers:

//Headers
fun addHeader(t: T, position: Int = -1, delay: Boolean = false)
fun addHeaders(list: List<T>, 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<T>, 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:

//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<NormalItem, ViewHolderNormalBinding> {
        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

//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<CustomStateItem, CustomStateItemBinding> {
        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:

-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.

More Repositories

1

RxDownload

A multi-threaded download tool written with RxJava and Kotlin
Kotlin
4,135
star
2

RxJava2Demo

็ป™ๅˆๅญฆ่€…็š„RxJava2.0็ณปๅˆ—ๆ•™็จ‹็š„demo
Java
344
star
3

RxRouter

A lightweight, simple, smart and powerful Android routing library.
Kotlin
323
star
4

Butterfly

Butterfly is a versatile component-based navigation framework based on Coroutine + Annotation + Ksp. Not only does it support navigation for Activity, Fragment, and DialogFragment, but it also supports navigation for Compose pages.
Kotlin
215
star
5

PracticalRecyclerView

Java
188
star
6

DownloadX

Download tool based on kotlin and coroutine.
Kotlin
160
star
7

AnimatorX

Animation and coroutines
Kotlin
69
star
8

Bracer

Pass parameters safely and quickly between activities or fragments.
Kotlin
67
star
9

MobidMask

A library for fast and safe delivery of parameters for Activities and Fragments.
Kotlin
67
star
10

KeyboardX

Monitor keyboard height tools
Kotlin
40
star
11

RxErrorHandler

Java
39
star
12

PermissionX

Android permission with coroutine
Kotlin
37
star
13

Sange

A powerful Recyclerview Adapter
Kotlin
37
star
14

BackgroundView

Java
22
star
15

CircularRevealMenu

Java
11
star
16

KeyBoardDetector

Keyboard height detection tool
Kotlin
9
star
17

IronBranch

Simple, powerful thread pool
Kotlin
7
star
18

ClarityPotion

Get Context, Application, Current Activity at anywhere
Kotlin
6
star
19

Desolator

Kotlin
2
star
20

Tango

Kotlin
2
star
21

ssseasonnn.github.io

HTML
2
star
22

GlovesOfHaste

Kotlin
2
star
23

Cloak

Kotlin
2
star
24

WindowsTools

Win10 tools
AutoHotkey
1
star
25

Android31Demo

Kotlin
1
star