Skip to content

Commit cdfee5a

Browse files
authored
Merge pull request #4 from manneohlund/rc-2.1.0
Rc 2.1.0
2 parents a5430a6 + 3169ba6 commit cdfee5a

34 files changed

+1377
-771
lines changed

Diff for: .idea/caches/build_file_checksums.ser

0 Bytes
Binary file not shown.

Diff for: README.md

+87-42
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,23 @@ allprojects {
2323
#### Step 2. Add the dependency
2424
```groovy
2525
dependencies {
26-
implementation 'com.github.manneohlund:smart-recycler-adapter:2.0.1'
26+
implementation 'com.github.manneohlund:smart-recycler-adapter:2.1.0'
2727
}
2828
```
2929

30-
# New complex SmartRecyclerAdapter v2.0.0
30+
# Basic
31+
### Basic adapter creation
32+
33+
```java
34+
SmartRecyclerAdapter
35+
.items(items)
36+
.map(MoviePosterModel.class, PosterViewHolder.class)
37+
.map(MovieBannerModel.class, BannerViewHolder.class)
38+
.map(TopNewsModel.class, TopNewsViewHolder.class)
39+
.into(recyclerView);
40+
```
41+
42+
# New nested SmartRecyclerAdapter from v2.0.0
3143

3244
New in `SmartRecyclerAdapter` v2.0.0 is support for nested recycler adapter.
3345
Now you can easily build complex nested adapters without hustle and have full control of the adapter in your view controlling `Fragment` or `Activity`.
@@ -62,40 +74,33 @@ SmartRecyclerAdapter
6274

6375
```java
6476
class MyWatchListViewHolder
65-
extends SmartAutoEventViewHolder<MyWatchListModel>
66-
implements SmartAdapterHolder {
77+
extends SmartAutoEventViewHolder<MyWatchListModel>
78+
implements SmartAdapterHolder {
6779

68-
// Constructor here
80+
// Constructor here
6981

70-
@Override
71-
public void setSmartRecyclerAdapter(SmartRecyclerAdapter smartRecyclerAdapter) {
72-
recyclerView.setLayoutManager(LinearLayoutManager(recyclerView.context, HORIZONTAL, false);
73-
recyclerView.adapter = (RecyclerView.Adapter) smartRecyclerAdapter;
74-
}
75-
76-
public void bind(MyWatchListModel myWatchListModel) {
77-
// bind model data to views
78-
}
82+
@Override
83+
public void setSmartRecyclerAdapter(SmartRecyclerAdapter smartRecyclerAdapter) {
84+
recyclerView.setLayoutManager(new LinearLayoutManager(context, HORIZONTAL, false));
85+
recyclerView.setAdapter(smartRecyclerAdapter);
86+
}
87+
88+
public void bind(MyWatchListModel myWatchListModel) {
89+
// bind model data to views
90+
}
91+
92+
public void unbind() {
93+
// optional unbinding of view data model
94+
}
7995
}
8096
```
8197

82-
# Basic
83-
### Basic adapter creation
84-
85-
```java
86-
SmartRecyclerAdapter
87-
.items(items)
88-
.map(MoviePosterModel.class, PosterViewHolder.class)
89-
.map(MovieBannerModel.class, BannerViewHolder.class)
90-
.map(TopNewsModel.class, TopNewsViewHolder.class)
91-
.into(recyclerView);
92-
```
93-
9498
### ViewHolder
9599

96100
Just extend your ViewHolder class with SmartViewHolder and pass in the target type ex `SmartViewHolder<Mail>`.
97-
Note that the constructor must take `ViewGroup` as parameter, in this case `PosterViewHolder(ViewGroup parentView)`.
101+
Note that the constructor can both take `View` or `ViewGroup` as parameter, in this case `PosterViewHolder(ViewGroup parentView)` to avoid casting to ViewGroup while inflating.
98102
The `parentView` is the recyclerView.<br/>
103+
The method `unbind` has an default implementation and is optional.
99104
##### Works with Android DataBinding! Just add the DataBinding LayoutInflater in `super` call. 🚀
100105

101106
```java
@@ -111,10 +116,15 @@ public class PosterViewHolder extends SmartViewHolder<MoviePosterModel> {
111116
.load(model.icon)
112117
.into(imageView);
113118
}
119+
120+
@Override
121+
public void unbind() {
122+
Glide.with(imageView).clear(imageView);
123+
}
114124
}
115125
```
116126

117-
### View event listener
127+
### View event listener
118128

119129
You can easily assign events to views and add an `ViewEventListener` to the SmartRecyclerAdapter for easy handling.<br/>
120130
You must extend your `ViewHolder` with `SmartEventViewHolder`.
@@ -135,10 +145,10 @@ Your `ViewHolder` must extend `SmartEventViewHolder`.
135145

136146
```java
137147
class MovieViewHolder extends SmartEventViewHolder<MovieModel> {
138-
@Override
139-
public void bind(MovieModel movieModel) {
140-
imageView.setOnClickListener(view -> notifyOnItemEvent(view, R.id.action_play_movie));
141-
}
148+
@Override
149+
public void bind(MovieModel movieModel) {
150+
imageView.setOnClickListener(view -> notifyOnItemEvent(view, R.id.action_play_movie));
151+
}
142152
}
143153
```
144154

@@ -166,8 +176,7 @@ SmartRecyclerAdapter
166176
### Adapter creation with ViewTypeResolver
167177

168178
If you want to bind one data type with different view holders depending on some attribute you can set a ViewTypeResolver.
169-
Note .map() call not needed in this case but you can combine if you want to.
170-
You can also set an OnViewDetachedFromWindowListener for immediate view holder detach handling.
179+
Note .map() call not needed in this case but you can combine if you want to.
171180

172181
```java
173182
SmartRecyclerAdapter
@@ -179,21 +188,57 @@ SmartRecyclerAdapter
179188
return RMovieViewHolder.class;
180189
} return MovieViewHolder.class; // Add default view if needed, else SmartRecyclerAdapter will look at the base `.map` mapping
181190
})
182-
.setOnViewDetachedFromWindowListener(holder -> {
183-
if (holder instanceof ImageViewHolder) {
184-
ImageCacheManager.getInstance().cancelAsyncTask(holder);
185-
}
186-
})
187191
.into(recyclerView);
188192
```
189193

194+
### RecyclableViewHolder
195+
196+
Sometimes a ViewHolder created by the Adapter cannot be recycled due to its transient state.
197+
In order to fix this is to implement `Re` in your `SmartViewHolder` extension so that upon receiving this callback,
198+
Adapter can clear the animation(s) that effect the View's transient state and return <code>true</code> so that the View can be recycled.
199+
200+
```java
201+
class MovieViewHolder
202+
extends SmartViewHolder
203+
implements RecyclableViewHolder {
204+
@Override
205+
public boolean onFailedToRecycleView() {
206+
// Clear animations or other stuff
207+
return true;
208+
}
209+
}
210+
```
211+
212+
### OnViewAttachedToWindowListener and OnViewDetachedFromWindowListener
213+
214+
If you want to catch when the view is attached and detached from the window in your ViewHolder you can implement `OnViewAttachedToWindowListener` and `OnViewDetachedFromWindowListener` in your `SmartViewHolder` extension.
215+
Becoming detached from the window is not necessarily a permanent condition the consumer of an Adapter's views may choose to cache views offscreen while they are not visible, attaching and detaching them as appropriate.
216+
217+
```java
218+
public class MovieViewHolder
219+
extends SmartViewHolder
220+
implements OnViewAttachedToWindowListener,
221+
OnViewDetachedFromWindowListener {
222+
223+
@Override
224+
public void onViewAttachedToWindow() {
225+
// Restore
226+
}
227+
228+
@Override
229+
public void onViewDetachedFromWindow() {
230+
// Cache
231+
}
232+
}
233+
```
234+
190235
### More SmartRecyclerAdapter features
191236

192237
```java
193238
SmartRecyclerAdapter adapter = SmartRecyclerAdapter
194-
.items(items)
195-
.map(MovieModel.class, MovieViewHolder.class)
196-
.into(recyclerView);
239+
.items(items)
240+
.map(MovieModel.class, MovieViewHolder.class)
241+
.into(recyclerView);
197242

198243
// We can add more data
199244
adapter.addItems(items);

Diff for: build.gradle

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ buildscript {
1212
google()
1313
}
1414
dependencies {
15-
classpath 'com.android.tools.build:gradle:3.4.1'
15+
classpath 'com.android.tools.build:gradle:3.4.2'
1616

1717
// NOTE: Do not place your application dependencies here; they belong
1818
// in the individual module build.gradle files
@@ -22,8 +22,8 @@ buildscript {
2222
allprojects {
2323
// Smart Adapter global version code and name
2424
ext {
25-
VERSION_CODE = 6
26-
VERSION_NAME = '2.0.1'
25+
VERSION_CODE = 7
26+
VERSION_NAME = '2.1.0'
2727
TARGET_SDK_VERSION = 28
2828
MIN_SDK_VERSION = 14
2929
}

Diff for: sample/src/main/java/com/example/smartrecycleradapter/DemoActivity.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ private void initSmartRecyclerAdapter() {
8282
items.add(new SciFiMoviesModel("Sci-Fi"));
8383
items.add(new MovieBannerModel("Promotion", MovieDataItems.INSTANCE.getRandomBanner()));
8484
items.add(new RecentlyPlayedMoviesModel("Recently played"));
85-
items.add(new CopyrightModel("SmartRecyclerAdapter v2.0.1\n\nDeveloped by Manne Öhlund"));
85+
items.add(new CopyrightModel(String.format("SmartRecyclerAdapter v%s\n\nDeveloped by Manne Öhlund", BuildConfig.VERSION_NAME)));
8686

8787
mainSmartMovieAdapter = SmartRecyclerAdapter
8888
.items(items)

Diff for: sample/src/main/java/com/example/smartrecycleradapter/data/MovieDataItems.kt

+1-4
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,12 @@ object MovieDataItems {
113113
MovieModel("Abominable", "abominable"),
114114
MovieModel("How to train your dragon 2", "how_to_train_your_dragon_two"),
115115
MovieModel("Incredibles 2", "incredibles"),
116-
MovieModel("Angry birds 2", "angry_birds_movie_two")
117-
118-
)
116+
MovieModel("Angry birds 2", "angry_birds_movie_two"))
119117

120118
// Recent viewed items
121119
var nestedRecentViewedItems = ArrayList<Any>()
122120
init {
123121
nestedRecentViewedItems.addAll(comingSoonItems)
124-
nestedRecentViewedItems.add(MovieModel("Dumb and dumber 2", "dumb_and_dumber_two"))
125122
nestedRecentViewedItems.add(MovieModel("Her", "her"))
126123
nestedRecentViewedItems.add(MovieModel("Imitation game", "imitation_game"))
127124
nestedRecentViewedItems.add(MovieModel("Interview", "interview"))

Diff for: sample/src/main/java/com/example/smartrecycleradapter/viewholder/PosterViewHolder.kt

+7-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package com.example.smartrecycleradapter.viewholder
66
*/
77

88
import android.view.LayoutInflater
9+
import android.view.View
910
import android.view.ViewGroup
1011
import android.widget.ImageView
1112
import com.bumptech.glide.Glide
@@ -16,9 +17,9 @@ import com.example.smartrecycleradapter.utils.displayHeight
1617
import com.example.smartrecycleradapter.utils.displayWidth
1718
import smartadapter.viewholder.SmartAutoEventViewHolder
1819

19-
class PosterViewHolder(parentView: ViewGroup) : SmartAutoEventViewHolder<MovieModel>(
20+
class PosterViewHolder(parentView: View) : SmartAutoEventViewHolder<MovieModel>(
2021
LayoutInflater.from(parentView.context)
21-
.inflate(R.layout.poster_item, parentView, false)) {
22+
.inflate(R.layout.poster_item, parentView as ViewGroup, false)) {
2223

2324
private val imageView: ImageView = itemView.findViewById(R.id.imageView)
2425

@@ -34,4 +35,8 @@ class PosterViewHolder(parentView: ViewGroup) : SmartAutoEventViewHolder<MovieMo
3435
.centerInside()
3536
.into(imageView)
3637
}
38+
39+
override fun unbind() {
40+
Glide.with(imageView).clear(imageView)
41+
}
3742
}

Diff for: sample/src/main/java/com/example/smartrecycleradapter/viewholder/ThumbViewHolder.kt

+14-2
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,15 @@ class SmallThumbViewHolder(parentView: ViewGroup) : SmartAutoEventViewHolder<Mov
2525
private val imageView: ImageView = itemView as ImageView
2626

2727
override fun bind(movie: MovieModel) {
28-
Glide.with(itemView.context)
28+
Glide.with(itemView)
2929
.load(movie.iconUrl)
3030
.apply(requestOption)
3131
.into(imageView)
3232
}
33+
34+
override fun unbind() {
35+
Glide.with(itemView).clear(itemView)
36+
}
3337
}
3438

3539
class ThumbViewHolder(parentView: ViewGroup) : SmartAutoEventViewHolder<MovieModel>(
@@ -44,6 +48,10 @@ class ThumbViewHolder(parentView: ViewGroup) : SmartAutoEventViewHolder<MovieMod
4448
.apply(requestOption)
4549
.into(imageView)
4650
}
51+
52+
override fun unbind() {
53+
Glide.with(itemView).clear(itemView)
54+
}
4755
}
4856

4957
class LargeThumbViewHolder(parentView: ViewGroup) : SmartAutoEventViewHolder<MovieModel>(
@@ -53,9 +61,13 @@ class LargeThumbViewHolder(parentView: ViewGroup) : SmartAutoEventViewHolder<Mov
5361
private val imageView: ImageView = itemView as ImageView
5462

5563
override fun bind(movie: MovieModel) {
56-
Glide.with(itemView.context)
64+
Glide.with(itemView)
5765
.load(movie.iconUrl)
5866
.apply(requestOption)
5967
.into(imageView)
6068
}
69+
70+
override fun unbind() {
71+
Glide.with(itemView).clear(itemView)
72+
}
6173
}

Diff for: smartadapter/build.gradle

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ dependencies {
3131
})
3232
testImplementation 'junit:junit:4.12'
3333
testImplementation 'org.mockito:mockito-core:1.9.5'
34+
testImplementation 'org.robolectric:robolectric:4.3'
35+
3436
implementation 'com.android.support:appcompat-v7:28.0.0'
3537
implementation 'com.android.support:recyclerview-v7:28.0.0'
3638
}

0 commit comments

Comments
 (0)