Skip to content

Commit

Permalink
add new change viewType support for ShimmerAdapter and some easy acce…
Browse files Browse the repository at this point in the history
…ss xml attributes.
  • Loading branch information
Omkar Todkar committed Apr 25, 2019
2 parents cd1c4db + e91bce5 commit 8817e6a
Show file tree
Hide file tree
Showing 26 changed files with 648 additions and 133 deletions.
51 changes: 44 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
# ShimmerRecyclerView

[![Build Status](https://travis-ci.com/omtodkar/ShimmerRecyclerView.svg?branch=master)](https://travis-ci.com/omtodkar/ShimmerRecyclerView) [ ![Download](https://api.bintray.com/packages/todkars/android/shimmer-recyclerview/images/download.svg?version=0.2.0) ](https://bintray.com/todkars/android/shimmer-recyclerview/0.2.0/link) ![GitHub](https://img.shields.io/github/license/omtodkar/ShimmerRecyclerView.svg?label=License) [![API](https://img.shields.io/badge/API-14%2B-brightgreen.svg?style=flat)](https://android-arsenal.com/api?level=14) [![Android Arsenal]( https://img.shields.io/badge/Android%20Arsenal-ShimmerRecyclerView-green.svg?style=flat )]( https://android-arsenal.com/details/1/7612 )
[ ![Build Status](https://travis-ci.com/omtodkar/ShimmerRecyclerView.svg?branch=master) ](https://travis-ci.com/omtodkar/ShimmerRecyclerView) [ ![Download](https://api.bintray.com/packages/todkars/android/shimmer-recyclerview/images/download.svg?version=0.3.0) ](https://bintray.com/todkars/android/shimmer-recyclerview/0.3.0/link) ![GitHub](https://img.shields.io/github/license/omtodkar/ShimmerRecyclerView.svg?label=License) [![API](https://img.shields.io/badge/API-14%2B-brightgreen.svg?style=flat)](https://android-arsenal.com/api?level=14) [![Android Arsenal]( https://img.shields.io/badge/Android%20Arsenal-ShimmerRecyclerView-green.svg?style=flat )]( https://android-arsenal.com/details/1/7612 )

ShimmerRecyclerView is an custom RecyclerView library based on Facebook's [Shimmer](https://github.com/facebook/shimmer-android) effect for Android library and inspired from [Sharish's ShimmerRecyclerView](https://github.com/sharish/ShimmerRecyclerView).

There is reason behind creating a separate library for ShimmerRecyclerView, most of libraries doesn't not support runtime switching of `LayoutManager` or shimmer `layout` resources. Secondly the other similar library is build upon [Supercharge's ShimmerLayout](https://github.com/team-supercharge/ShimmerLayout) which is I feel very less active in terms of release. So I came up with an alternative.

## Switching List and Grid layout demo

Change layout manager in runtime `LinearLayoutManager` to `GridLayoutManager` and Shimmer will adopt accordingly.

<img src='demo/list-grid-demo.gif' height=480 width=240 />

## Multiple view type demo

Setup `mShimmerRecyclerView.setItemViewType(ShimmerAdapter.ItemViewType)` to change view type of Shimmer adapter.

| List Demo | Grid Demo |
| ---------------------------- | ----------------------------- |
| <img src='demo/list-demo.gif' height=480 width=240 /> | <img src='demo/grid-demo.gif' height=480 width=240 /> |

## Download

To include `ShimmerRecyclerView` in your project, add the following to your dependencies:
Expand All @@ -27,8 +41,10 @@ The following snippet shows how you can use Shimmer RecyclerView in your project
android:id="@+id/shimmer_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:shimmer_recycler_colored="true"
app:shimmer_recycler_duration="1000" />
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:shimmer_recycler_layout="@layout/list_item_shimmer_layout"
app:shimmer_recycler_item_count="10" />
```

**Activity**
Expand All @@ -45,13 +61,32 @@ public class MainActivity extends Activity {
super.onCreate(savedInstanceState);

mShimmerRecyclerView = findViewById(R.id.shimmer_recycler_view);
mShimmerRecyclerView.setLayoutManager(new LinearLayoutManager(this), R.layout.list_item_shimmer_layout);

mShimmerRecyclerView.setLayoutManager(new LinearLayoutManager(this),
R.layout.list_item_shimmer_layout);

mShimmerRecyclerView.setAdapter(adapter);

// This is optional, use if no attributes are mentioned in layout xml resource.
// WARNING: Setting Shimmer programmatically will obsolete all xml attributes.
// WARNING: Setting Shimmer programmatically will obsolete all shimmer attributes.
/* mShimmerRecyclerView.setShimmer(mShimmer); */

/* Shimmer layout view type depending on List / Gird */
mShimmerRecyclerView.setItemViewType((type, position) -> {
switch (type) {
case ShimmerRecyclerView.LAYOUT_GRID:
return position % 2 == 0
? R.layout.list_item_shimmer_grid
: R.layout.list_item_shimmer_grid_alternate;

default:
case ShimmerRecyclerView.LAYOUT_LIST:
return position == 0 || position % 2 == 0
? R.layout.list_item_shimmer
: R.layout.list_item_shimmer_alternate;
}
});

mShimmerRecyclerView.showShimmer(); // to start showing shimmer

// To stimulate long running work using android.os.Handler
Expand All @@ -60,14 +95,16 @@ public class MainActivity extends Activity {
}, 3000);
}
}
```
```

## Attributes

All attributes used for **ShimmerRecyclerView** are same as Facebook's ***ShimmerFrameLayout*** below is detail table:
Most of the attributes used for **ShimmerRecyclerView** are same as Facebook's ***ShimmerFrameLayout*** below is detail table:

| Name | Attribute | Description |
|---|---|---|
| Shimmer Layout | shimmer_recycler_layout | Layout reference used for as shimmer base. |
| Shimmer Item Count | shimmer_recycler_item_count | Number of shimmers to be shown in list, default is 9. |
| Clip to Children | `shimmer_recycler_clip_to_children` | Whether to clip the shimmering effect to the children, or to opaquely draw the shimmer on top of the children. Use this if your overall layout contains transparency. |
| Colored | `shimmer_recycler_colored` | Whether you want the shimmer to affect just the alpha or draw colors on-top of the children. |
| Base Color | `shimmer_recycler_base_color` | If colored is specified, the base color of the content. |
Expand Down
7 changes: 7 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

ShimmerRecyclerView is an custom RecyclerView library based on Facebook's [Shimmer](https://github.com/facebook/shimmer-android) effect for Android library

### v0.3.0
Now you can set xml attributes for shimmer layout reference and number of shimmer to be shown while loading. Also now you can able to change view type of `ShimmerAdapter`.

- New `ItemViewType` contract to setup viewType for `ShimmerAdapter` based on `layoutType` and `position`, use `ShimmerRecyclerView.setItemViewType`.
- Use `shimmer_recycler_layout` xml attribute to set shimmer layout reference.
- Use `shimmer_recycler_item_count` xml attribute to set number of shimmer items.

### v0.2.0

Bug fixes and minor changes.
Expand Down
77 changes: 57 additions & 20 deletions app/src/main/java/com/todkars/ExampleActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;

import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
Expand All @@ -37,40 +37,63 @@

import java.util.List;

public class ExampleActivity extends AppCompatActivity implements UserRetrievalTask.UserRetrievalResult {
public class ExampleActivity extends AppCompatActivity
implements UserRetrievalTask.UserRetrievalResult {

@VisibleForTesting
public UserRetrievalTask userRetrievalTask;

private UserAdapter adapter = new UserAdapter();
private Button mReloadButton;

private Button mToggleButton;

private CheckBox mOrientationButton;

private ShimmerRecyclerView mShimmerRecyclerView;

private boolean buttonsEnabled = true;

private UserAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_example);

/* initialize empty adapter */
adapter = new UserAdapter();

setupViews();
}

/**
* Initial view and recycler list setup.
*/
private void setupViews() {
ViewDataBinding binder = DataBindingUtil.setContentView(this, R.layout.activity_example);
ViewDataBinding binder = DataBindingUtil.setContentView(this,
R.layout.activity_example);
binder.setVariable(BR.activity, this);
binder.setVariable(BR.active, buttonsEnabled);

mReloadButton = binder.getRoot().findViewById(R.id.toggle_loading);
mToggleButton = binder.getRoot().findViewById(R.id.toggle_shimmer);
mOrientationButton = binder.getRoot().findViewById(R.id.change_layout_orientation);

mShimmerRecyclerView = binder.getRoot().findViewById(R.id.user_listing);
mShimmerRecyclerView.setItemViewType((type, position) -> {
switch (type) {
case ShimmerRecyclerView.LAYOUT_GRID:
return position % 2 == 0
? R.layout.list_item_shimmer_grid
: R.layout.list_item_shimmer_grid_alternate;

default:
case ShimmerRecyclerView.LAYOUT_LIST:
return position == 0 || position % 2 == 0
? R.layout.list_item_shimmer
: R.layout.list_item_shimmer_alternate;
}
});
mShimmerRecyclerView.setAdapter(adapter);
mShimmerRecyclerView.setShimmerLayout(R.layout.list_item_vertical_shimmer);
mShimmerRecyclerView.setShimmerItemCount(10);
mShimmerRecyclerView.setLayoutManager(new LinearLayoutManager(this));

onReload(null /* initial call to load data */);
}
Expand All @@ -79,18 +102,18 @@ private void setupViews() {
* When layout orientation {@link android.widget.CheckBox} is checked,
* set list orientation to gird else vice versa.
*
* @param button checkbox.
* @param grid isChecked value.
* @param button view.
* @param isGrid isChecked value.
*/
public void onLayoutOrientationChange(CompoundButton button, boolean grid) {
public void onLayoutOrientationChange(CompoundButton button, boolean isGrid) {
mShimmerRecyclerView.setLayoutManager(
grid
isGrid
? new GridLayoutManager(this, 2)
: new LinearLayoutManager(this),
grid
? R.layout.list_item_grid_shimmer
: R.layout.list_item_vertical_shimmer);
adapter.changeOrientation(grid);
isGrid
? R.layout.list_item_shimmer_grid
: R.layout.list_item_shimmer);
adapter.changeOrientation(isGrid);
mShimmerRecyclerView.setAdapter(adapter);
}

Expand All @@ -107,6 +130,9 @@ public void onToggleShimmer(View view) {
mShimmerRecyclerView.showShimmer();
((Button) view).setText(R.string.toggle_shimmer_hide);
}

mOrientationButton.setEnabled(!mShimmerRecyclerView.isShimmerShowing());
mReloadButton.setEnabled(!mShimmerRecyclerView.isShimmerShowing());
}

/**
Expand All @@ -117,9 +143,12 @@ public void onToggleShimmer(View view) {
*/
public void onReload(View view) {
buttonsEnabled = false;
mShimmerRecyclerView.showShimmer();
mToggleButton.setVisibility(View.INVISIBLE);

generateUserRetrievalTask().execute();

mShimmerRecyclerView.showShimmer();
mOrientationButton.setEnabled(false);
mToggleButton.setEnabled(false);
}

/**
Expand All @@ -129,14 +158,22 @@ public void onReload(View view) {
* @param users list of {@link User}s
*/
@Override
@VisibleForTesting
public void onResult(List<User> users) {
adapter.updateData(users);

mShimmerRecyclerView.hideShimmer();
mOrientationButton.setEnabled(true);
mToggleButton.setEnabled(true);

buttonsEnabled = true;
mToggleButton.setVisibility(View.VISIBLE);
}

/**
* Generate new instance of {@link AsyncTask}
* if it is not instantiated or already finished.
*
* @return instance of {@link AsyncTask}.
*/
private UserRetrievalTask generateUserRetrievalTask() {
if (userRetrievalTask == null || userRetrievalTask.getStatus() == AsyncTask.Status.FINISHED)
userRetrievalTask = new UserRetrievalTask(this, this);
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/todkars/adapters/UserAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public UserAdapter() {
@Override
public UserViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
ViewDataBinding binder = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), grid
? R.layout.list_item_grid_user : R.layout.list_item_vertical_user, parent, false);
? R.layout.list_item_user_grid : R.layout.list_item_user, parent, false);
return new UserViewHolder(binder);
}

Expand Down
9 changes: 9 additions & 0 deletions app/src/main/res/drawable/ic_view_list_disable.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#A09F9F"
android:pathData="M4,14h4v-4L4,10v4zM4,19h4v-4L4,15v4zM4,9h4L8,5L4,5v4zM9,14h12v-4L9,10v4zM9,19h12v-4L9,15v4zM9,5v4h12L21,5L9,5z" />
</vector>
9 changes: 9 additions & 0 deletions app/src/main/res/drawable/ic_view_module_disable.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#A09F9F"
android:pathData="M4,11h5L9,5L4,5v6zM4,18h5v-6L4,12v6zM10,18h5v-6h-5v6zM16,18h5v-6h-5v6zM10,11h5L15,5h-5v6zM16,5v6h5L21,5h-5z"/>
</vector>
5 changes: 5 additions & 0 deletions app/src/main/res/drawable/view_toggle.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- disable icons -->
<item android:drawable="@drawable/ic_view_list_disable" android:state_checked="true" android:state_enabled="false" />
<item android:drawable="@drawable/ic_view_module_disable" android:state_checked="false" android:state_enabled="false" />
<!-- focused icons -->
<item android:drawable="@drawable/ic_view_list" android:state_checked="true" android:state_focused="true" />
<item android:drawable="@drawable/ic_view_module" android:state_checked="false" android:state_focused="true" />
<!-- default -->
<item android:drawable="@drawable/ic_view_module" android:state_checked="false" />
<item android:drawable="@drawable/ic_view_list" android:state_checked="true" />
</selector>
9 changes: 7 additions & 2 deletions app/src/main/res/layout/activity_example.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,17 @@ https://github.com/omtodkar/ShimmerRecyclerView/blob/master/LICENSE.md
android:id="@+id/user_listing"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline"
app:shimmer_recycler_base_color="#03CCCC"
app:shimmer_recycler_colored="true" />
app:shimmer_recycler_base_color="@color/colorShimmer"
app:shimmer_recycler_colored="true"
app:shimmer_recycler_highlight_color="@color/colorShimmerHighlight"
app:shimmer_recycler_layout="@layout/list_item_shimmer"
tools:listitem="@layout/list_item_user" />

<Button
android:id="@+id/toggle_loading"
Expand Down
Loading

0 comments on commit 8817e6a

Please sign in to comment.