Skip to content

Commit

Permalink
Merge pull request #4 from manneohlund/rc-2.1.0
Browse files Browse the repository at this point in the history
Rc 2.1.0
  • Loading branch information
manneohlund authored Jul 23, 2019
2 parents a5430a6 + 3169ba6 commit cdfee5a
Show file tree
Hide file tree
Showing 34 changed files with 1,377 additions and 771 deletions.
Binary file modified .idea/caches/build_file_checksums.ser
Binary file not shown.
129 changes: 87 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,23 @@ allprojects {
#### Step 2. Add the dependency
```groovy
dependencies {
implementation 'com.github.manneohlund:smart-recycler-adapter:2.0.1'
implementation 'com.github.manneohlund:smart-recycler-adapter:2.1.0'
}
```

# New complex SmartRecyclerAdapter v2.0.0
# Basic
### Basic adapter creation

```java
SmartRecyclerAdapter
.items(items)
.map(MoviePosterModel.class, PosterViewHolder.class)
.map(MovieBannerModel.class, BannerViewHolder.class)
.map(TopNewsModel.class, TopNewsViewHolder.class)
.into(recyclerView);
```

# New nested SmartRecyclerAdapter from v2.0.0

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

```java
class MyWatchListViewHolder
extends SmartAutoEventViewHolder<MyWatchListModel>
implements SmartAdapterHolder {
extends SmartAutoEventViewHolder<MyWatchListModel>
implements SmartAdapterHolder {

// Constructor here
// Constructor here

@Override
public void setSmartRecyclerAdapter(SmartRecyclerAdapter smartRecyclerAdapter) {
recyclerView.setLayoutManager(LinearLayoutManager(recyclerView.context, HORIZONTAL, false);
recyclerView.adapter = (RecyclerView.Adapter) smartRecyclerAdapter;
}

public void bind(MyWatchListModel myWatchListModel) {
// bind model data to views
}
@Override
public void setSmartRecyclerAdapter(SmartRecyclerAdapter smartRecyclerAdapter) {
recyclerView.setLayoutManager(new LinearLayoutManager(context, HORIZONTAL, false));
recyclerView.setAdapter(smartRecyclerAdapter);
}

public void bind(MyWatchListModel myWatchListModel) {
// bind model data to views
}

public void unbind() {
// optional unbinding of view data model
}
}
```

# Basic
### Basic adapter creation

```java
SmartRecyclerAdapter
.items(items)
.map(MoviePosterModel.class, PosterViewHolder.class)
.map(MovieBannerModel.class, BannerViewHolder.class)
.map(TopNewsModel.class, TopNewsViewHolder.class)
.into(recyclerView);
```

### ViewHolder

Just extend your ViewHolder class with SmartViewHolder and pass in the target type ex `SmartViewHolder<Mail>`.
Note that the constructor must take `ViewGroup` as parameter, in this case `PosterViewHolder(ViewGroup parentView)`.
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.
The `parentView` is the recyclerView.<br/>
The method `unbind` has an default implementation and is optional.
##### Works with Android DataBinding! Just add the DataBinding LayoutInflater in `super` call. 🚀

```java
Expand All @@ -111,10 +116,15 @@ public class PosterViewHolder extends SmartViewHolder<MoviePosterModel> {
.load(model.icon)
.into(imageView);
}

@Override
public void unbind() {
Glide.with(imageView).clear(imageView);
}
}
```

### View event listener
### View event listener

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

```java
class MovieViewHolder extends SmartEventViewHolder<MovieModel> {
@Override
public void bind(MovieModel movieModel) {
imageView.setOnClickListener(view -> notifyOnItemEvent(view, R.id.action_play_movie));
}
@Override
public void bind(MovieModel movieModel) {
imageView.setOnClickListener(view -> notifyOnItemEvent(view, R.id.action_play_movie));
}
}
```

Expand Down Expand Up @@ -166,8 +176,7 @@ SmartRecyclerAdapter
### Adapter creation with ViewTypeResolver

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

```java
SmartRecyclerAdapter
Expand All @@ -179,21 +188,57 @@ SmartRecyclerAdapter
return RMovieViewHolder.class;
} return MovieViewHolder.class; // Add default view if needed, else SmartRecyclerAdapter will look at the base `.map` mapping
})
.setOnViewDetachedFromWindowListener(holder -> {
if (holder instanceof ImageViewHolder) {
ImageCacheManager.getInstance().cancelAsyncTask(holder);
}
})
.into(recyclerView);
```

### RecyclableViewHolder

Sometimes a ViewHolder created by the Adapter cannot be recycled due to its transient state.
In order to fix this is to implement `Re` in your `SmartViewHolder` extension so that upon receiving this callback,
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.

```java
class MovieViewHolder
extends SmartViewHolder
implements RecyclableViewHolder {
@Override
public boolean onFailedToRecycleView() {
// Clear animations or other stuff
return true;
}
}
```

### OnViewAttachedToWindowListener and OnViewDetachedFromWindowListener

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

```java
public class MovieViewHolder
extends SmartViewHolder
implements OnViewAttachedToWindowListener,
OnViewDetachedFromWindowListener {

@Override
public void onViewAttachedToWindow() {
// Restore
}

@Override
public void onViewDetachedFromWindow() {
// Cache
}
}
```

### More SmartRecyclerAdapter features

```java
SmartRecyclerAdapter adapter = SmartRecyclerAdapter
.items(items)
.map(MovieModel.class, MovieViewHolder.class)
.into(recyclerView);
.items(items)
.map(MovieModel.class, MovieViewHolder.class)
.into(recyclerView);

// We can add more data
adapter.addItems(items);
Expand Down
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ buildscript {
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.1'
classpath 'com.android.tools.build:gradle:3.4.2'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
Expand All @@ -22,8 +22,8 @@ buildscript {
allprojects {
// Smart Adapter global version code and name
ext {
VERSION_CODE = 6
VERSION_NAME = '2.0.1'
VERSION_CODE = 7
VERSION_NAME = '2.1.0'
TARGET_SDK_VERSION = 28
MIN_SDK_VERSION = 14
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ private void initSmartRecyclerAdapter() {
items.add(new SciFiMoviesModel("Sci-Fi"));
items.add(new MovieBannerModel("Promotion", MovieDataItems.INSTANCE.getRandomBanner()));
items.add(new RecentlyPlayedMoviesModel("Recently played"));
items.add(new CopyrightModel("SmartRecyclerAdapter v2.0.1\n\nDeveloped by Manne Öhlund"));
items.add(new CopyrightModel(String.format("SmartRecyclerAdapter v%s\n\nDeveloped by Manne Öhlund", BuildConfig.VERSION_NAME)));

mainSmartMovieAdapter = SmartRecyclerAdapter
.items(items)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,15 +113,12 @@ object MovieDataItems {
MovieModel("Abominable", "abominable"),
MovieModel("How to train your dragon 2", "how_to_train_your_dragon_two"),
MovieModel("Incredibles 2", "incredibles"),
MovieModel("Angry birds 2", "angry_birds_movie_two")

)
MovieModel("Angry birds 2", "angry_birds_movie_two"))

// Recent viewed items
var nestedRecentViewedItems = ArrayList<Any>()
init {
nestedRecentViewedItems.addAll(comingSoonItems)
nestedRecentViewedItems.add(MovieModel("Dumb and dumber 2", "dumb_and_dumber_two"))
nestedRecentViewedItems.add(MovieModel("Her", "her"))
nestedRecentViewedItems.add(MovieModel("Imitation game", "imitation_game"))
nestedRecentViewedItems.add(MovieModel("Interview", "interview"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package com.example.smartrecycleradapter.viewholder
*/

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import com.bumptech.glide.Glide
Expand All @@ -16,9 +17,9 @@ import com.example.smartrecycleradapter.utils.displayHeight
import com.example.smartrecycleradapter.utils.displayWidth
import smartadapter.viewholder.SmartAutoEventViewHolder

class PosterViewHolder(parentView: ViewGroup) : SmartAutoEventViewHolder<MovieModel>(
class PosterViewHolder(parentView: View) : SmartAutoEventViewHolder<MovieModel>(
LayoutInflater.from(parentView.context)
.inflate(R.layout.poster_item, parentView, false)) {
.inflate(R.layout.poster_item, parentView as ViewGroup, false)) {

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

Expand All @@ -34,4 +35,8 @@ class PosterViewHolder(parentView: ViewGroup) : SmartAutoEventViewHolder<MovieMo
.centerInside()
.into(imageView)
}

override fun unbind() {
Glide.with(imageView).clear(imageView)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,15 @@ class SmallThumbViewHolder(parentView: ViewGroup) : SmartAutoEventViewHolder<Mov
private val imageView: ImageView = itemView as ImageView

override fun bind(movie: MovieModel) {
Glide.with(itemView.context)
Glide.with(itemView)
.load(movie.iconUrl)
.apply(requestOption)
.into(imageView)
}

override fun unbind() {
Glide.with(itemView).clear(itemView)
}
}

class ThumbViewHolder(parentView: ViewGroup) : SmartAutoEventViewHolder<MovieModel>(
Expand All @@ -44,6 +48,10 @@ class ThumbViewHolder(parentView: ViewGroup) : SmartAutoEventViewHolder<MovieMod
.apply(requestOption)
.into(imageView)
}

override fun unbind() {
Glide.with(itemView).clear(itemView)
}
}

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

override fun bind(movie: MovieModel) {
Glide.with(itemView.context)
Glide.with(itemView)
.load(movie.iconUrl)
.apply(requestOption)
.into(imageView)
}

override fun unbind() {
Glide.with(itemView).clear(itemView)
}
}
2 changes: 2 additions & 0 deletions smartadapter/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ dependencies {
})
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:1.9.5'
testImplementation 'org.robolectric:robolectric:4.3'

implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
}
Loading

0 comments on commit cdfee5a

Please sign in to comment.