-
Notifications
You must be signed in to change notification settings - Fork 139
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b6fd6e5
commit b367087
Showing
15 changed files
with
1,045 additions
and
11 deletions.
There are no files selected for viewing
177 changes: 177 additions & 0 deletions
177
ByRecyclerview/src/main/java/me/jingbin/library/skeleton/ByRVItemSkeletonScreen.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
package me.jingbin.library.skeleton; | ||
|
||
|
||
import android.support.annotation.ArrayRes; | ||
import android.support.annotation.ColorRes; | ||
import android.support.annotation.IntRange; | ||
import android.support.annotation.LayoutRes; | ||
import android.support.v4.content.ContextCompat; | ||
import android.support.v7.widget.RecyclerView; | ||
|
||
import me.jingbin.library.ByRecyclerView; | ||
import me.jingbin.library.R; | ||
|
||
|
||
/** | ||
* @author jingbin | ||
* item 骨架图显示 | ||
*/ | ||
public class ByRVItemSkeletonScreen implements SkeletonScreen { | ||
|
||
private final RecyclerView mRecyclerView; | ||
private final RecyclerView.Adapter mActualAdapter; | ||
private final SkeletonAdapter mSkeletonAdapter; | ||
private final boolean mRecyclerViewFrozen; | ||
private boolean isShow = false; | ||
private boolean loadMoreEnabled = false; | ||
private boolean refreshEnabled = false; | ||
|
||
private ByRVItemSkeletonScreen(Builder builder) { | ||
mRecyclerView = builder.mRecyclerView; | ||
mActualAdapter = builder.mActualAdapter; | ||
mSkeletonAdapter = new SkeletonAdapter(); | ||
mSkeletonAdapter.setItemCount(builder.mItemCount); | ||
mSkeletonAdapter.setLayoutReference(builder.mItemResID); | ||
mSkeletonAdapter.setArrayOfLayoutReferences(builder.mItemsResIDArray); | ||
mSkeletonAdapter.shimmer(builder.mShimmer); | ||
mSkeletonAdapter.setShimmerColor(builder.mShimmerColor); | ||
mSkeletonAdapter.setShimmerAngle(builder.mShimmerAngle); | ||
mSkeletonAdapter.setShimmerDuration(builder.mShimmerDuration); | ||
mRecyclerViewFrozen = builder.mFrozen; | ||
} | ||
|
||
/** | ||
* 只能显示一次 | ||
*/ | ||
@Override | ||
public void show() { | ||
mRecyclerView.setAdapter(mSkeletonAdapter); | ||
if (!mRecyclerView.isComputingLayout() && mRecyclerViewFrozen) { | ||
mRecyclerView.setLayoutFrozen(true); | ||
} | ||
if (!mRecyclerViewFrozen && mRecyclerView instanceof ByRecyclerView) { | ||
ByRecyclerView byRecyclerView = (ByRecyclerView) this.mRecyclerView; | ||
loadMoreEnabled = byRecyclerView.isLoadMoreEnabled(); | ||
refreshEnabled = byRecyclerView.isRefreshEnabled(); | ||
byRecyclerView.setLoadMoreEnabled(false); | ||
byRecyclerView.setRefreshEnabled(false); | ||
} | ||
isShow = true; | ||
} | ||
|
||
/** | ||
* 只能显示一次 | ||
*/ | ||
@Override | ||
public void hide() { | ||
if (isShow) { | ||
mRecyclerView.setAdapter(mActualAdapter); | ||
if (!mRecyclerViewFrozen && mRecyclerView instanceof ByRecyclerView) { | ||
ByRecyclerView byRecyclerView = (ByRecyclerView) this.mRecyclerView; | ||
byRecyclerView.setRefreshEnabled(refreshEnabled); | ||
byRecyclerView.setLoadMoreEnabled(loadMoreEnabled); | ||
} | ||
isShow = false; | ||
} | ||
} | ||
|
||
public static class Builder { | ||
private RecyclerView.Adapter mActualAdapter; | ||
private final RecyclerView mRecyclerView; | ||
private boolean mShimmer = true; | ||
private int mItemCount = 10; | ||
private int mItemResID = R.layout.layout_by_default_item_skeleton; | ||
private int[] mItemsResIDArray; | ||
private int mShimmerColor; | ||
private int mShimmerDuration = 1000; | ||
private int mShimmerAngle = 20; | ||
private boolean mFrozen = true; | ||
|
||
public Builder(RecyclerView recyclerView) { | ||
this.mRecyclerView = recyclerView; | ||
this.mShimmerColor = ContextCompat.getColor(recyclerView.getContext(), R.color.by_skeleton_shimmer_color); | ||
} | ||
|
||
/** | ||
* @param adapter the target recyclerView actual adapter | ||
*/ | ||
public Builder adapter(RecyclerView.Adapter adapter) { | ||
this.mActualAdapter = adapter; | ||
return this; | ||
} | ||
|
||
/** | ||
* @param itemCount the child item count in recyclerView | ||
*/ | ||
public Builder count(int itemCount) { | ||
this.mItemCount = itemCount; | ||
return this; | ||
} | ||
|
||
/** | ||
* @param shimmer whether show shimmer animation | ||
*/ | ||
public Builder shimmer(boolean shimmer) { | ||
this.mShimmer = shimmer; | ||
return this; | ||
} | ||
|
||
/** | ||
* the duration of the animation , the time it will take for the highlight to move from one end of the layout | ||
* to the other. | ||
* | ||
* @param shimmerDuration Duration of the shimmer animation, in milliseconds | ||
*/ | ||
public Builder duration(int shimmerDuration) { | ||
this.mShimmerDuration = shimmerDuration; | ||
return this; | ||
} | ||
|
||
/** | ||
* @param shimmerColor the shimmer color | ||
*/ | ||
public Builder color(@ColorRes int shimmerColor) { | ||
this.mShimmerColor = ContextCompat.getColor(mRecyclerView.getContext(), shimmerColor); | ||
return this; | ||
} | ||
|
||
/** | ||
* @param shimmerAngle the angle of the shimmer effect in clockwise direction in degrees. | ||
*/ | ||
public Builder angle(@IntRange(from = 0, to = 30) int shimmerAngle) { | ||
this.mShimmerAngle = shimmerAngle; | ||
return this; | ||
} | ||
|
||
/** | ||
* @param skeletonLayoutResID the loading skeleton layoutResID | ||
*/ | ||
public Builder load(@LayoutRes int skeletonLayoutResID) { | ||
this.mItemResID = skeletonLayoutResID; | ||
return this; | ||
} | ||
|
||
/** | ||
* @param skeletonLayoutResIDs the loading array of skeleton layoutResID | ||
*/ | ||
public Builder loadArrayOfLayouts(@ArrayRes int[] skeletonLayoutResIDs) { | ||
this.mItemsResIDArray = skeletonLayoutResIDs; | ||
return this; | ||
} | ||
|
||
/** | ||
* @param frozen whether frozen recyclerView during skeleton showing | ||
* @return | ||
*/ | ||
public Builder frozen(boolean frozen) { | ||
this.mFrozen = frozen; | ||
return this; | ||
} | ||
|
||
public ByRVItemSkeletonScreen show() { | ||
ByRVItemSkeletonScreen recyclerViewSkeleton = new ByRVItemSkeletonScreen(this); | ||
recyclerViewSkeleton.show(); | ||
return recyclerViewSkeleton; | ||
} | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
ByRecyclerview/src/main/java/me/jingbin/library/skeleton/BySkeleton.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package me.jingbin.library.skeleton; | ||
|
||
|
||
import android.support.v7.widget.RecyclerView; | ||
|
||
import me.jingbin.library.ByRecyclerView; | ||
|
||
/** | ||
* Created by jingbin on 2020-03-06. | ||
* 骨架图处理,在设置完 ByRV 的一切配置后执行 | ||
*/ | ||
public class BySkeleton { | ||
|
||
/** | ||
* 设置item骨架图:通过额外setAdapter实现 【在之前 不能 setAdapter()】 | ||
* 配置方法: | ||
* adapter 必须! | ||
* load item骨架图 默认 layout_by_default_item_skeleton | ||
* shimmer 是否有微光动画 默认 true | ||
* angle 微光角度 默认 20 | ||
* frozen 是否不可滑动 默认 true不可滑动 | ||
* color 微光的颜色 默认 R.color.by_skeleton_shimmer_color | ||
* duration 微光一次显示时间 默认 1000 | ||
* count item个数 默认 10 | ||
*/ | ||
public static ByRVItemSkeletonScreen.Builder bindItem(RecyclerView recyclerView) { | ||
return new ByRVItemSkeletonScreen.Builder(recyclerView); | ||
} | ||
|
||
/** | ||
* 设置view骨架图:通过setStateView实现 【在之前 需要 setAdapter()】 | ||
* 配置方法: | ||
* load 必须!view骨架图 | ||
* shimmer 是否有微光动画 默认 true | ||
* angle 微光角度 默认 20 | ||
* color 微光的颜色 默认 R.color.by_skeleton_shimmer_color | ||
* duration 微光一次显示时间 默认 1000 | ||
*/ | ||
public static ByStateViewSkeletonScreen.Builder bindView(ByRecyclerView recyclerView) { | ||
return new ByStateViewSkeletonScreen.Builder(recyclerView); | ||
} | ||
|
||
} |
166 changes: 166 additions & 0 deletions
166
ByRecyclerview/src/main/java/me/jingbin/library/skeleton/ByStateViewSkeletonScreen.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
package me.jingbin.library.skeleton; | ||
|
||
import android.support.annotation.ColorRes; | ||
import android.support.annotation.IntRange; | ||
import android.support.annotation.LayoutRes; | ||
import android.support.v4.content.ContextCompat; | ||
import android.util.Log; | ||
import android.view.LayoutInflater; | ||
import android.view.View; | ||
import android.view.ViewGroup; | ||
import android.view.ViewParent; | ||
|
||
import me.jingbin.library.ByRecyclerView; | ||
import me.jingbin.library.R; | ||
|
||
/** | ||
* Created by jingbin on 2020/03/07. | ||
* view 骨架图显示,通过StateView处理 | ||
*/ | ||
public class ByStateViewSkeletonScreen implements SkeletonScreen { | ||
|
||
private static final String TAG = ByStateViewSkeletonScreen.class.getName(); | ||
private final ByRecyclerView mByRecyclerView; | ||
private final int mSkeletonResID; | ||
private final int mShimmerColor; | ||
private final boolean mShimmer; | ||
private final int mShimmerDuration; | ||
private final int mShimmerAngle; | ||
private boolean loadMoreEnabled; | ||
private boolean refreshEnabled; | ||
private boolean isShow = false; | ||
|
||
private ByStateViewSkeletonScreen(Builder builder) { | ||
mByRecyclerView = builder.mByRecyclerView; | ||
mSkeletonResID = builder.mSkeletonLayoutResID; | ||
mShimmer = builder.mShimmer; | ||
mShimmerDuration = builder.mShimmerDuration; | ||
mShimmerAngle = builder.mShimmerAngle; | ||
mShimmerColor = builder.mShimmerColor; | ||
} | ||
|
||
private ShimmerLayout generateShimmerContainerLayout(ViewGroup parentView) { | ||
final ShimmerLayout shimmerLayout = (ShimmerLayout) LayoutInflater.from(mByRecyclerView.getContext()).inflate(R.layout.layout_by_skeleton_shimmer, parentView, false); | ||
shimmerLayout.setShimmerColor(mShimmerColor); | ||
shimmerLayout.setShimmerAngle(mShimmerAngle); | ||
shimmerLayout.setShimmerAnimationDuration(mShimmerDuration); | ||
View innerView = LayoutInflater.from(mByRecyclerView.getContext()).inflate(mSkeletonResID, shimmerLayout, false); | ||
ViewGroup.LayoutParams lp = innerView.getLayoutParams(); | ||
if (lp != null) { | ||
shimmerLayout.setLayoutParams(lp); | ||
} | ||
shimmerLayout.addView(innerView); | ||
shimmerLayout.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { | ||
@Override | ||
public void onViewAttachedToWindow(View v) { | ||
shimmerLayout.startShimmerAnimation(); | ||
} | ||
|
||
@Override | ||
public void onViewDetachedFromWindow(View v) { | ||
shimmerLayout.stopShimmerAnimation(); | ||
} | ||
}); | ||
shimmerLayout.startShimmerAnimation(); | ||
return shimmerLayout; | ||
} | ||
|
||
private View generateSkeletonLoadingView() { | ||
ViewParent viewParent = mByRecyclerView.getParent(); | ||
if (viewParent == null) { | ||
Log.e(TAG, "the source view have not attach to any view"); | ||
return null; | ||
} | ||
ViewGroup parentView = (ViewGroup) viewParent; | ||
if (mShimmer) { | ||
return generateShimmerContainerLayout(parentView); | ||
} | ||
return LayoutInflater.from(mByRecyclerView.getContext()).inflate(mSkeletonResID, parentView, false); | ||
} | ||
|
||
@Override | ||
public void show() { | ||
loadMoreEnabled = mByRecyclerView.isLoadMoreEnabled(); | ||
refreshEnabled = mByRecyclerView.isRefreshEnabled(); | ||
|
||
mByRecyclerView.setRefreshEnabled(false); | ||
mByRecyclerView.setLoadMoreEnabled(false); | ||
mByRecyclerView.setStateView(generateSkeletonLoadingView()); | ||
isShow = true; | ||
} | ||
|
||
@Override | ||
public void hide() { | ||
if (isShow) { | ||
mByRecyclerView.setStateViewEnabled(false); | ||
mByRecyclerView.setLoadMoreEnabled(loadMoreEnabled); | ||
mByRecyclerView.setRefreshEnabled(refreshEnabled); | ||
isShow = false; | ||
} | ||
} | ||
|
||
|
||
public static class Builder { | ||
private final ByRecyclerView mByRecyclerView; | ||
private int mSkeletonLayoutResID; | ||
private boolean mShimmer = true; | ||
private int mShimmerColor; | ||
private int mShimmerDuration = 1000; | ||
private int mShimmerAngle = 20; | ||
|
||
public Builder(ByRecyclerView byRecyclerView) { | ||
this.mByRecyclerView = byRecyclerView; | ||
this.mShimmerColor = ContextCompat.getColor(mByRecyclerView.getContext(), R.color.by_skeleton_shimmer_color); | ||
} | ||
|
||
/** | ||
* @param skeletonLayoutResID the loading skeleton layoutResID | ||
*/ | ||
public Builder load(@LayoutRes int skeletonLayoutResID) { | ||
this.mSkeletonLayoutResID = skeletonLayoutResID; | ||
return this; | ||
} | ||
|
||
/** | ||
* @param shimmerColor the shimmer color | ||
*/ | ||
public Builder color(@ColorRes int shimmerColor) { | ||
this.mShimmerColor = ContextCompat.getColor(mByRecyclerView.getContext(), shimmerColor); | ||
return this; | ||
} | ||
|
||
/** | ||
* @param shimmer whether show shimmer animation | ||
*/ | ||
public Builder shimmer(boolean shimmer) { | ||
this.mShimmer = shimmer; | ||
return this; | ||
} | ||
|
||
/** | ||
* the duration of the animation , the time it will take for the highlight to move from one end of the layout | ||
* to the other. | ||
* | ||
* @param shimmerDuration Duration of the shimmer animation, in milliseconds | ||
*/ | ||
public Builder duration(int shimmerDuration) { | ||
this.mShimmerDuration = shimmerDuration; | ||
return this; | ||
} | ||
|
||
/** | ||
* @param shimmerAngle the angle of the shimmer effect in clockwise direction in degrees. | ||
*/ | ||
public Builder angle(@IntRange(from = 0, to = 30) int shimmerAngle) { | ||
this.mShimmerAngle = shimmerAngle; | ||
return this; | ||
} | ||
|
||
public ByStateViewSkeletonScreen show() { | ||
ByStateViewSkeletonScreen skeletonScreen = new ByStateViewSkeletonScreen(this); | ||
skeletonScreen.show(); | ||
return skeletonScreen; | ||
} | ||
|
||
} | ||
} |
Oops, something went wrong.