├── .gitignore
├── LICENSE
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── list
│ │ └── rados
│ │ └── recyclerviewlibrary
│ │ └── MainActivity.kt
│ └── res
│ ├── drawable-v24
│ └── ic_launcher_foreground.xml
│ ├── drawable
│ └── ic_launcher_background.xml
│ ├── layout
│ ├── activity_main.xml
│ ├── item.xml
│ ├── item_custom.xml
│ └── item_second.xml
│ ├── mipmap-anydpi-v26
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-mdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ └── values
│ ├── colors.xml
│ ├── strings.xml
│ └── styles.xml
├── build.gradle
├── fast-list
├── .gitignore
├── build.gradle
├── deploy.gradle
├── keystore.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── list
│ │ └── rados
│ │ └── fast_list
│ │ └── BaseList.kt
│ └── res
│ └── values
│ └── strings.xml
├── gradle.properties
├── logo.png
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 | .idea/
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Radoslav Yankov
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 |
4 | Create dynamic, fast and easy recycler view lists (including ViewPager2). **No adapters, no view holders**.
5 |
6 | [](https://jitpack.io/#dev-labs-bg/fast-list) [](http://twitter.com/devlabsbg)
7 |
8 |
9 | ## Usage
10 |
11 | FastList supports 2 types of lists- single layout lists and dynamic lists.
12 |
13 | - Here's how to create a simple single layout list:
14 |
15 | ```kotlin
16 | val list = listOf(Item("fast", 1), Item("recycler", 2), Item("view", 1))
17 |
18 | recycler_view.bind(list, R.layout.item) { it : Item, position: Int ->
19 | item_text.text = it.value
20 | }
21 | ```
22 | That's it (for ViewPager2, just replace recycler_view with the ViewPager2 instance)! The first parameter is the list you want to show, the second is the ID of the layout and the third one is a function for binding each element. It uses Kotlin Extensions, so you can directly address the XML views and set them up.
23 |
24 |
25 | - The second type is dynamic lists with multiple layouts:
26 |
27 | ```kotlin
28 | val list = listOf(Item("fast", 1), Item("recycler", 2), Item("view", 1))
29 |
30 | recycler_view.bind(list)
31 | .map(layout = R.layout.item, predicate = { it: Item, _ -> it.type == 1}) { item: Item, p: Int ->
32 | item_text.text = it.value
33 | }
34 | .map(layout = R.layout.item_second, predicate = { it: Item, _ -> it.type == 2}) { item: Item, p: Int ->
35 | item_second_text.text = it.value
36 | }
37 | .layoutManager(LinearLayoutManager(this))
38 | ```
39 | The map function accepts 3 parameters. The first is the ID of the layout for the type. The second is the predicate function by which you want to sort your items. The last one is the "view holder" binding function for each element. It uses Kotlin Extensions, so you can directly address the XML views and set them up.
40 |
41 | If you need control over your view's creation, you can pass a factory that allows you to create your own view:
42 | ```kotlin
43 | val list = listOf(Item("fast", 1), Item("recycler", 2), Item("view", 1))
44 |
45 | recycler_view.bind(list)
46 | .map(layoutFactory = LocalFactory(this), predicate = { it: Item, _ -> it.type == 1}) { item: Item, p: Int ->
47 | item_text.text = it.value
48 | }
49 | .map(layout = R.layout.item_second, predicate = { it: Item, _ -> it.type == 2}) { item: Item, p: Int ->
50 | item_second_text.text = it.value
51 | }
52 | .layoutManager(LinearLayoutManager(this))
53 | ...
54 | class LocalFactory(val activity: AppCompatActivity) : LayoutFactory {
55 | override fun createView(parent: ViewGroup, type: Int): View {
56 | val view = LayoutInflater.from(activity).inflate(R.layout.item,
57 | parent, false)
58 | //Manipulate view as needed
59 | return view
60 | }
61 | }
62 | ```
63 |
64 |
65 |
66 | You can also update a list in a shown recycler view with this DiffUtils update function:
67 | ```kotlin
68 | ...
69 | val list2 = listOf(Item("fast", 1))
70 |
71 | recycler_view.update(list2)
72 | ```
73 |
74 | ## Download
75 |
76 | ### Manually
77 |
78 | The recommended way to download is to copy the [the library class](https://github.com/dev-labs-bg/fast-list/blob/master/fast-list/src/main/java/com/list/rados/fast_list/BaseList.kt) and use it in your application.
79 |
80 | **Important**: For the manual download you need Kotlin extensions to be enabled. To turn them on, simply place "apply plugin: 'kotlin-android-extensions'" inside of your app build.gradle
81 |
82 | ### Gradle
83 |
84 | ```gradle
85 | dependencies {
86 | implementation 'bg.devlabs.fastlist:fast-list:$latest_version'
87 | }
88 | ```
89 |
90 | ## Getting help
91 |
92 | Dev Labs [@devlabsbg](https://twitter.com/devlabsbg)
93 |
94 | Radoslav Yankov [@rado__yankov](https://twitter.com/rado__yankov/)
95 |
96 | Under [MIT License](https://github.com/dev-labs-bg/fast-list/blob/master/LICENSE).
97 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | apply plugin: 'kotlin-android'
4 | apply plugin: 'kotlin-android-extensions'
5 |
6 | androidExtensions {
7 | experimental = true
8 | }
9 |
10 | android {
11 | compileSdkVersion 29
12 | defaultConfig {
13 | applicationId "bg.devlabs.fastlist"
14 | minSdkVersion 19
15 | targetSdkVersion 29
16 | versionCode 1
17 | versionName "1.0"
18 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
19 | }
20 | buildTypes {
21 | release {
22 | minifyEnabled false
23 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
24 | }
25 | }
26 | }
27 |
28 | dependencies {
29 | implementation fileTree(dir: 'libs', include: ['*.jar'])
30 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
31 | implementation 'com.android.support.constraint:constraint-layout:1.1.3'
32 | implementation 'androidx.appcompat:appcompat:1.1.0'
33 | implementation "androidx.recyclerview:recyclerview:1.1.0"
34 |
35 | implementation 'androidx.core:core-ktx:1.2.0'
36 |
37 | implementation project(path: ':fast-list')
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/list/rados/recyclerviewlibrary/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.list.rados.recyclerviewlibrary
2 |
3 | import android.os.Bundle
4 | import android.os.Handler
5 | import android.view.LayoutInflater
6 | import android.view.View
7 | import android.view.ViewGroup
8 | import android.widget.Toast
9 | import androidx.appcompat.app.AppCompatActivity
10 | import androidx.core.view.children
11 | import androidx.recyclerview.widget.LinearLayoutManager
12 | import com.list.rados.fast_list.LayoutFactory
13 | import com.list.rados.fast_list.bind
14 | import com.list.rados.fast_list.update
15 | import kotlinx.android.synthetic.main.activity_main.*
16 | import kotlinx.android.synthetic.main.item.view.*
17 | import kotlinx.android.synthetic.main.item_custom.view.*
18 | import kotlinx.android.synthetic.main.item_second.view.*
19 |
20 | class MainActivity : AppCompatActivity() {
21 |
22 | data class Item(val value: String, val type: Int)
23 |
24 | override fun onCreate(savedInstanceState: Bundle?) {
25 | super.onCreate(savedInstanceState)
26 | setContentView(R.layout.activity_main)
27 |
28 | val list = listOf(Item("first", 2), Item("second", 2), Item("third", 1), Item("fourth", 1), Item("fifth", 1))
29 | val list2 = listOf(Item("first", 2), Item("third", 1), Item("fifth", 1), Item("sixth", 3))
30 |
31 | recycler_view.bind(list, R.layout.item) { item: Item, position: Int ->
32 | item_text.text = item.value
33 | container.setOnClickListener {
34 | toast(item.value)
35 | }
36 | }
37 |
38 | recycler_view.bind(list)
39 | .map(layout = R.layout.item, predicate = { it: Item, _ -> it.type == 1 }) { item: Item, position: Int ->
40 | item_text.text = item.value
41 | container.setOnClickListener {
42 | toast(item.value)
43 | }
44 | }
45 | .map(layout = R.layout.item_second, predicate = { it: Item, _ -> it.type == 2 }) { item: Item, position: Int ->
46 | item_second_text.text = item.value
47 | container_second.setOnClickListener {
48 | toast(item.value)
49 | }
50 | }
51 | .map(layoutFactory = LocalFactory(this), predicate = { it: Item, _ -> it.type == 3 }) { item: Item, position: Int ->
52 | item_custom_text.text = item.value
53 | container_custom.setOnClickListener {
54 | toast(item.value)
55 | }
56 | }
57 | .layoutManager(LinearLayoutManager(this))
58 |
59 | delay(2000) {
60 | recycler_view.update(list2)
61 | }
62 |
63 | }
64 |
65 | private fun toast(value: String) {
66 | Toast.makeText(this, value, Toast.LENGTH_SHORT).show()
67 | }
68 | }
69 |
70 | class LocalFactory(val activity: AppCompatActivity) : LayoutFactory {
71 | override fun createView(parent: ViewGroup, type: Int): View {
72 | return LayoutInflater.from(activity).inflate(R.layout.item_custom,
73 | parent, false)
74 | }
75 | }
76 |
77 | fun delay(delay: Long, func: () -> Unit) {
78 | val handler = Handler()
79 | handler.postDelayed({
80 | try {
81 | func()
82 | } catch (e: Exception) {
83 | println(e.toString())
84 | }
85 | }, delay)
86 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
11 |
16 |
21 |
26 |
31 |
36 |
41 |
46 |
51 |
56 |
61 |
66 |
71 |
76 |
81 |
86 |
91 |
96 |
101 |
106 |
111 |
116 |
121 |
126 |
131 |
136 |
141 |
146 |
151 |
156 |
161 |
166 |
171 |
172 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_custom.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_second.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-labs-bg/fast-list/14766800fff24cdd2797bf63580e7fb61cda5294/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-labs-bg/fast-list/14766800fff24cdd2797bf63580e7fb61cda5294/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-labs-bg/fast-list/14766800fff24cdd2797bf63580e7fb61cda5294/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-labs-bg/fast-list/14766800fff24cdd2797bf63580e7fb61cda5294/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-labs-bg/fast-list/14766800fff24cdd2797bf63580e7fb61cda5294/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-labs-bg/fast-list/14766800fff24cdd2797bf63580e7fb61cda5294/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-labs-bg/fast-list/14766800fff24cdd2797bf63580e7fb61cda5294/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-labs-bg/fast-list/14766800fff24cdd2797bf63580e7fb61cda5294/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-labs-bg/fast-list/14766800fff24cdd2797bf63580e7fb61cda5294/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-labs-bg/fast-list/14766800fff24cdd2797bf63580e7fb61cda5294/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | FastList
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.kotlin_version = '1.3.72'
5 | ext.dokka_version = '0.9.16'
6 | repositories {
7 | google()
8 | jcenter()
9 | }
10 | dependencies {
11 | classpath 'com.android.tools.build:gradle:4.1.0-alpha02'
12 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
13 |
14 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.0'
15 | classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
16 | classpath "org.jetbrains.dokka:dokka-android-gradle-plugin:${dokka_version}"
17 | }
18 | }
19 |
20 | allprojects {
21 | repositories {
22 | google()
23 | jcenter()
24 | }
25 | }
26 |
27 | task clean(type: Delete) {
28 | delete rootProject.buildDir
29 | }
30 |
--------------------------------------------------------------------------------
/fast-list/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/fast-list/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | apply plugin: 'com.jfrog.bintray'
5 | apply plugin: 'org.jetbrains.dokka-android'
6 | apply plugin: 'maven-publish'
7 |
8 | androidExtensions {
9 | experimental = true
10 | }
11 |
12 | android {
13 | compileSdkVersion 29
14 |
15 | defaultConfig {
16 | minSdkVersion 19
17 | targetSdkVersion 29
18 | versionCode 4
19 | versionName "1.4"
20 |
21 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
22 |
23 | }
24 |
25 | buildTypes {
26 | release {
27 | minifyEnabled false
28 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
29 | }
30 | }
31 |
32 | }
33 |
34 | dokka {
35 | outputFormat = 'html'
36 | outputDirectory = "$buildDir/javadoc"
37 | }
38 |
39 | dependencies {
40 | implementation fileTree(dir: 'libs', include: ['*.jar'])
41 |
42 | implementation 'com.android.support.constraint:constraint-layout:1.1.3'
43 | implementation 'androidx.recyclerview:recyclerview:1.1.0'
44 | implementation 'androidx.viewpager2:viewpager2:1.0.0'
45 | testImplementation 'junit:junit:4.12'
46 | compileOnly 'androidx.core:core-ktx:1.2.0'
47 |
48 | }
49 |
50 | apply from: 'deploy.gradle'
--------------------------------------------------------------------------------
/fast-list/deploy.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.github.dcendents.android-maven'
2 | apply plugin: 'com.jfrog.bintray'
3 | apply from: 'keystore.gradle'//the file, containing the bintray API key
4 | ext {
5 | // This configuration will result in:
6 | // compile '::'
7 | groupId = 'bg.devlabs.fastlist' // package name of the project
8 | artifactId = "fast-list" // module name of the library
9 | libVersion = "1.4"
10 | }
11 | version = libVersion
12 | group = groupId
13 | //take a look at https://github.com/bintray/gradle-bintray-plugin#buildgradle
14 | bintray {
15 | user = 'radoslav' // Your bintray User
16 | key = bintray_key // Defined in keystore.gradle file
17 | configurations = ['archives']
18 | publish = true //[Default: false] Whether version should be auto published after an upload
19 | override = false //[Default: false] Whether to override version artifacts already published
20 | // Package configuration. The plugin will use the repo and name properties to check if the
21 | // package already exists. In that case, there's no need to configure the other package
22 | // properties (like userOrg, desc, etc).
23 | pkg {
24 | repo = "maven" //bintray repo
25 | name = "fast-list" //bintray package
26 | version {
27 | name = libVersion
28 | }
29 | }
30 | }
31 | install {
32 | repositories.mavenInstaller {
33 | pom.project {
34 | packaging 'aar'
35 | groupId groupId
36 | artifactId artifactId
37 | version libVersion
38 | name artifactId // pom.project.name must be same as bintray.pkg.name
39 | }
40 | }
41 | }
42 |
43 | //just copy paste the lines below
44 | if (project.hasProperty("kotlin")) { //Kotlin libraries
45 | task sourcesJar(type: Jar) {
46 | classifier = 'sources'
47 | from android.sourceSets.main.java.srcDirs
48 | }
49 |
50 | task javadoc(type: Javadoc, dependsOn: dokka) {
51 |
52 | }
53 | } else if (project.hasProperty("android")) {
54 | task sourcesJar(type: Jar) {
55 | classifier = 'sources'
56 | from android.sourceSets.main.java.srcDirs
57 | }
58 |
59 | task javadoc(type: Javadoc) {
60 | source = android.sourceSets.main.java.srcDirs
61 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
62 | }
63 | } else { // Java libraries
64 | task sourcesJar(type: Jar, dependsOn: classes) {
65 | classifier = 'sources'
66 | from sourceSets.main.allSource
67 | }
68 | }
69 |
70 | task javadocJar(type: Jar, dependsOn: javadoc) {
71 | classifier = 'javadoc'
72 | from javadoc.destinationDir
73 | // options.encoding = 'UTF-8'
74 | }
75 |
76 | artifacts {
77 | archives javadocJar
78 | archives sourcesJar
79 | }
--------------------------------------------------------------------------------
/fast-list/keystore.gradle:
--------------------------------------------------------------------------------
1 | ext{
2 | bintray_key = '-'
3 | }
--------------------------------------------------------------------------------
/fast-list/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/fast-list/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/fast-list/src/main/java/com/list/rados/fast_list/BaseList.kt:
--------------------------------------------------------------------------------
1 | package com.list.rados.fast_list
2 |
3 | import android.view.LayoutInflater
4 | import android.view.View
5 | import android.view.ViewGroup
6 | import androidx.annotation.LayoutRes
7 | import androidx.recyclerview.widget.DiffUtil
8 | import androidx.recyclerview.widget.LinearLayoutManager
9 | import androidx.recyclerview.widget.RecyclerView
10 | import androidx.viewpager2.widget.ViewPager2
11 | import kotlinx.android.extensions.LayoutContainer
12 |
13 | /**
14 | * Created by Radoslav Yankov on 29.06.2018
15 | * radoslavyankov@gmail.com
16 | */
17 |
18 | typealias BindingClosure = (View.(item: T, position: Int) -> Unit)
19 |
20 | /**
21 | * Dynamic list bind function. It should be followed by one or multiple .map calls.
22 | * @param items - Generic list of the items to be displayed in the list
23 | */
24 | fun RecyclerView.bind(items: List): FastListAdapter {
25 | layoutManager = LinearLayoutManager(context)
26 | return FastListAdapter(items.toMutableList(), this)
27 | }
28 |
29 | /**
30 | * ViewPager2 update
31 | * Dynamic list bind function. It should be followed by one or multiple .map calls.
32 | * @param items - Generic list of the items to be displayed in the list
33 | */
34 | fun ViewPager2.bind(items: List): FastListAdapter {
35 | return FastListAdapter(items.toMutableList(), vpList = this)
36 | }
37 |
38 | /**
39 | * Simple list bind function.
40 | * @param items - Generic list of the items to be displayed in the list
41 | * @param singleLayout - The layout that will be used in the list
42 | * @param singleBind - The "binding" function between the item and the layout. This is the standard "bind" function in traditional ViewHolder classes. It uses Kotlin Extensions
43 | * so you can just use the XML names of the views inside your layout to address them.
44 | */
45 | fun RecyclerView.bind(items: List, @LayoutRes singleLayout: Int = 0, singleBind: BindingClosure): FastListAdapter {
46 | layoutManager = LinearLayoutManager(context)
47 | return FastListAdapter(items.toMutableList(), this
48 | ).map(singleLayout, { item: T, position: Int -> true }, singleBind)
49 | }
50 |
51 | /**
52 | * ViewPager2 update
53 | * Simple list bind function.
54 | * @param items - Generic list of the items to be displayed in the list
55 | * @param singleLayout - The layout that will be used in the list
56 | * @param singleBind - The "binding" function between the item and the layout. This is the standard "bind" function in traditional ViewHolder classes. It uses Kotlin Extensions
57 | * so you can just use the XML names of the views inside your layout to address them.
58 | */
59 | fun ViewPager2.bind(items: List, @LayoutRes singleLayout: Int = 0, singleBind: BindingClosure): FastListAdapter {
60 | return FastListAdapter(items.toMutableList(), vpList = this
61 | ).map(singleLayout, { item: T, position: Int -> true }, singleBind)
62 | }
63 |
64 | /**
65 | * Updates the list using DiffUtils.
66 | * @param newItems the new list which is to replace the old one.
67 | *
68 | * NOTICE: The comparator currently checks if items are literally the same. You can change that if you want,
69 | * by changing the lambda in the function
70 | */
71 | fun RecyclerView.update(newItems: List) {
72 | (adapter as? FastListAdapter)?.update(newItems) { o, n, _ -> o == n }
73 | }
74 |
75 | /**
76 | * ViewPager2 update
77 | * Updates the list using DiffUtils.
78 | * @param newItems the new list which is to replace the old one.
79 | *
80 | * NOTICE: The comparator currently checks if items are literally the same. You can change that if you want,
81 | * by changing the lambda in the function
82 | */
83 | fun ViewPager2.update(newItems: List) {
84 | (adapter as? FastListAdapter)?.update(newItems) { o, n, _ -> o == n }
85 | }
86 |
87 | open class FastListAdapter(private var items: MutableList, private var list: RecyclerView? = null, private var vpList: ViewPager2? = null)
88 | : RecyclerView.Adapter>() {
89 |
90 | init {
91 | if (vpList != null && list != null)
92 | throw IllegalArgumentException("You can only use either the Recycler(list) or the Pager(vpList)")
93 | if (vpList == null && list == null)
94 | throw IllegalArgumentException("You have to use either the Recycler(list) or the Pager(vpList)")
95 |
96 | }
97 |
98 | private inner class BindMap(val layout: Int, var type: Int = 0, val bind: BindingClosure, val predicate: (item: T, position: Int) -> Boolean) {
99 | constructor(lf: LayoutFactory, type: Int = 0, bind: BindingClosure, predicate: (item: T, position: Int) -> Boolean) : this(0, type, bind, predicate) {
100 | layoutFactory = lf
101 | }
102 |
103 | var layoutFactory: LayoutFactory? = null
104 | }
105 |
106 | private var bindMap = mutableListOf()
107 | private var typeCounter = 0
108 |
109 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FastListViewHolder {
110 | return bindMap.first { it.type == viewType }.let {
111 | it.layoutFactory?.let {
112 | return FastListViewHolder(it.createView(parent, viewType), viewType)
113 | } ?: run {
114 | return FastListViewHolder(LayoutInflater.from(parent.context).inflate(it.layout,
115 | parent, false), viewType)
116 | }
117 | }
118 | }
119 |
120 | override fun onBindViewHolder(holder: FastListViewHolder, position: Int) {
121 | val item = items.get(position)
122 | holder.bind(item, position, bindMap.first { it.type == holder.holderType }.bind)
123 | }
124 |
125 | override fun getItemCount() = items.size
126 |
127 | override fun getItemViewType(position: Int) = try {
128 | bindMap.first { it.predicate(items[position], position) }.type
129 | } catch (e: Exception) {
130 | 0
131 | }
132 |
133 | /**
134 | * The function used for mapping types to layouts
135 | * @param layout - The ID of the XML layout of the given type
136 | * @param predicate - Function used to sort the items. For example, a Type field inside your items class with different values for different types.
137 | * @param bind - The "binding" function between the item and the layout. This is the standard "bind" function in traditional ViewHolder classes. It uses Kotlin Extensions
138 | * so you can just use the XML names of the views inside your layout to address them.
139 | */
140 | fun map(@LayoutRes layout: Int, predicate: (item: T, position: Int) -> Boolean, bind: BindingClosure): FastListAdapter {
141 | bindMap.add(BindMap(layout, typeCounter++, bind, predicate))
142 | list?.adapter = this
143 | vpList?.adapter = this
144 | return this
145 | }
146 |
147 | /**
148 | * The function used for mapping types to layouts
149 | * @param layoutFactory - factory that creates the view for this adapter
150 | * @param predicate - Function used to sort the items. For example, a Type field inside your items class with different values for different types.
151 | * @param bind - The "binding" function between the item and the layout. This is the standard "bind" function in traditional ViewHolder classes. It uses Kotlin Extensions
152 | * so you can just use the XML names of the views inside your layout to address them.
153 | */
154 | fun map(layoutFactory: LayoutFactory, predicate: (item: T, position: Int) -> Boolean, bind: BindingClosure): FastListAdapter {
155 | bindMap.add(BindMap(layoutFactory, typeCounter++, bind, predicate))
156 | list?.adapter = this
157 | vpList?.adapter = this
158 | return this
159 | }
160 |
161 | /**
162 | * Sets up a layout manager for the recycler view.
163 | */
164 | fun layoutManager(manager: RecyclerView.LayoutManager): FastListAdapter {
165 | vpList?.let { throw UnsupportedOperationException("layoumanager not needed for ViewPager2") }
166 | list!!.layoutManager = manager
167 | return this
168 | }
169 |
170 | fun update(newList: List, compare: (T, T, Boolean) -> Boolean) {
171 | val diff = DiffUtil.calculateDiff(object : DiffUtil.Callback() {
172 |
173 | override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
174 | return compare(items[oldItemPosition], newList[newItemPosition], false)
175 | }
176 |
177 | override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
178 | return compare(items[oldItemPosition], newList[newItemPosition], true)
179 | }
180 |
181 | override fun getOldListSize() = items.size
182 |
183 | override fun getNewListSize() = newList.size
184 | })
185 | if (newList is MutableList)
186 | items = newList
187 | else
188 | items = newList.toMutableList()
189 | diff.dispatchUpdatesTo(this)
190 | }
191 |
192 | }
193 |
194 | interface LayoutFactory {
195 | fun createView(parent: ViewGroup, type: Int): View
196 | }
197 |
198 | class FastListViewHolder(override val containerView: View, val holderType: Int) : RecyclerView.ViewHolder(containerView), LayoutContainer {
199 | fun bind(entry: T, position: Int, func: BindingClosure) {
200 | containerView.apply {
201 | func(entry, position)
202 | }
203 | }
204 | }
--------------------------------------------------------------------------------
/fast-list/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | FastList
3 |
4 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | android.useAndroidX=true
--------------------------------------------------------------------------------
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-labs-bg/fast-list/14766800fff24cdd2797bf63580e7fb61cda5294/logo.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':fast-list'
2 |
--------------------------------------------------------------------------------