Skip to content

Commit

Permalink
rewrite adapters without implementing DiffUtilItem
Browse files Browse the repository at this point in the history
  • Loading branch information
D00mch committed Jun 28, 2020
1 parent edf7803 commit 4ee3d9e
Show file tree
Hide file tree
Showing 34 changed files with 279 additions and 828 deletions.
111 changes: 11 additions & 100 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,14 @@ This lib is inspired by Hannes Dorfmann [AdapterDelegates](https://github.com/so

## Dependencies

for java:
```groovy
implementation 'com.github.liverm0r:delegateadapters:v1.11'
```

for kotlin:
```groovy
android {
//...
androidExtensions {
experimental = true
}
}
implementation 'com.github.Liverm0r:delegateadapters:2.11'
implementation 'com.github.Liverm0r:delegateadapters:3.00'
```

You also have to add this in your project build.gradle
Expand All @@ -35,18 +29,14 @@ allprojects {

[![Build Status](https://travis-ci.org/sockeqwe/AdapterDelegates.svg?branch=master)](https://jitpack.io/#Liverm0r/delegateadapters)

## Kotlin examples
## Examples

Write a model, which represents ui data:

```kotlin
data class ImageItem(val title: String, @DrawableRes val imageRes: Int) : KDiffUtilItem {
override val id: Any = title
}
data class ImageItem(val title: String, @DrawableRes val imageRes: Int)
```

ImageItem is just a POJO, implementing DiffUtilItem to be able to animate it out of the box with DiffUtils.

Write a delegate adapter:

```kotlin
Expand All @@ -60,10 +50,11 @@ class ImageDelegateAdapter(private val clickListener: View.OnClickListener) : KD

override fun isForViewType(item: Any) = item is ImageItem
override fun getLayoutId(): Int = R.layout.image_item
override fun ImageItem.getItemId(): Any = title // DiffUtils will use this to know that items are the same
}
```

Check `KViewHolder.onBind` part. This works like the basic view holder without creating one. Just override onBind and onCreate methods. See the [View holder pattern support and caching options](
Check `KViewHolder.onBind` part. This works like the basic view holder without creating one. Just override onBind method. See the [View holder pattern support and caching options](
https://github.com/Kotlin/KEEP/blob/master/proposals/android-extensions-entity-caching.md
) for more information.

Expand All @@ -78,99 +69,19 @@ androidExtensions {
Now you can use DiffUtilCompositeAdapter just like the base RecyclerView.Adapter, composing it with whatever amount of delegate adapters:

```kotlin
adapter = DiffUtilCompositeAdapter.Builder()
.add(ImageDelegateAdapter(onImageClick))
.add(TextDelegateAdapter())
.add(CheckDelegateAdapter())
.build()
val adapter = CompositeDelegateAdapter(
TxtDelegateAdapter(),
CheckDelegateAdapter(),
GenerateItemsDelegateAdapter { generateNewData() }
)
```

![example](https://github.com/Liverm0r/DelegateAdapters/blob/master/feed_example.jpg)

See example in code: [KotlinBaseExampleActivity.kt][1]

[1]: https://github.com/Liverm0r/DelegateAdapters/blob/master/example/src/main/java/com/example/dumchev/delegateadapters/base/KotlinBaseExampleActivity.kt

## Java examples

Write a Model:

```java
public class TextItem implements IComparableItem {

@NonNull public final String title;
@NonNull public final String description;

public TextItem(@NonNull String title, @NonNull String description) {
this.title = title;
this.description = description;
}

@Override public Object id() {return title;}
@Override public Object content() {return title + description;}
}

```

Inherit from BaseDelegateAdapter:

```java
public class TextDelegateAdapter extends
BaseDelegateAdapter<TextDelegateAdapter.TextViewHolder, TextItem> {

@Override
protected void onBindViewHolder(@NonNull View view,
@NonNull TextItem item,
@NonNull TextViewHolder viewHolder) {
viewHolder.tvTitle.setText(item.title);
viewHolder.tvDescription.setText(item.description);
}

@Override
protected int getLayoutId() {
return R.layout.text_item;
}

@NonNull
@Override
protected TextViewHolder createViewHolder(View parent) {
return new TextViewHolder(parent);
}

@Override
public boolean isForViewType(@NonNull List<?> items, int position) {
return items.get(position) instanceof TextItem;
}

final static class TextViewHolder extends BaseViewHolder {

private TextView tvTitle;
private TextView tvDescription;

private TextViewHolder(View parent) {
super(parent);
tvTitle = parent.findViewById(R.id.tv_title);
tvDescription = parent.findViewById(R.id.tv_description);
}
}
}

```

And create your CompositeDelegateAdapter (RecyclerView.Adapter):

```java
adapter = new DiffUtilCompositeAdapter.Builder()
.add(new ImageDelegateAdapter(onImageClick))
.add(new TextDelegateAdapter())
.add(new CheckDelegateAdapter())
.build();
```


See code-example: [BaseExampleActivity.java][2]
[1]: https://github.com/Liverm0r/DelegateAdapters/blob/master/example/src/main/java/com/example/dumchev/delegateadapters/base/BaseExampleActivity.kt

[2]: https://github.com/Liverm0r/DelegateAdapters/blob/master/example/src/main/java/com/example/dumchev/delegateadapters/base/BaseExampleActivity.java

## License

Expand Down
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
ext.kotlin_version = '1.3.40'
ext.kotlin_version = '1.3.72'
repositories {
jcenter()
google()
}

dependencies {
classpath 'com.android.tools.build:gradle:3.4.1'
classpath 'com.android.tools.build:gradle:3.6.3'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'

classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.livermor.delegateadapter.delegate

/**
* Class to hold [CompositeDelegateAdapter]'s adapters and data.
*/
data class AdaptersState(
private val adapters: List<DelegateAdapter>,
val data: List<Any> = emptyList()
) {

private val adapterPositionsCache = Array<Int>(data.size) { -1 }

fun getAdapterPosition(itemPosition: Int): Int =
adapterPositionsCache[itemPosition].takeIf { it != -1 }
?: adapters.indexOfFirst { it.isForViewType(data, itemPosition) }
.takeIf { it != -1 }
?.also { adapterPositionsCache[itemPosition] = it }
?: error("Provide adapter for type ${data[itemPosition].javaClass} at position: $itemPosition")

fun getAdapter(adapterPosition: Int): DelegateAdapter = adapters[adapterPosition]

fun getAdapterByItemPosition(itemPosition: Int): DelegateAdapter =
adapters[getAdapterPosition(itemPosition)]
}

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit 4ee3d9e

Please sign in to comment.