Skip to content

Commit

Permalink
Rework recycler view frame and utils
Browse files Browse the repository at this point in the history
Improve adapters, binders and staggered grid handling.
Update methods to control progress (show/hide) animation.
Update layout utils to better support full span by view type
and position.
  • Loading branch information
pranavpandey committed Mar 4, 2020
1 parent 65598b5 commit 55712ba
Show file tree
Hide file tree
Showing 18 changed files with 298 additions and 128 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019 Pranav Pandey
* Copyright 2020 Pranav Pandey
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -66,6 +66,7 @@
import com.pranavpandey.android.dynamic.utils.DynamicViewUtils;
import com.pranavpandey.android.dynamic.utils.DynamicWindowUtils;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
Expand Down Expand Up @@ -180,7 +181,7 @@ public abstract class DynamicSystemActivity extends AppCompatActivity implements
/**
* Hash map to store the shared elements map.
*/
private HashMap<String, Integer> mSharedElementMap;
private Map<String, Integer> mSharedElementMap;

/**
* Result code for the shared element transition.
Expand Down Expand Up @@ -397,7 +398,7 @@ public void onSaveInstanceState(@NonNull Bundle outState) {
outState.putInt(ADS_STATE_NAVIGATION_BAR_COLOR, mNavigationBarColor);
outState.putInt(ADS_STATE_TRANSITION_RESULT_CODE, mTransitionResultCode);
outState.putInt(ADS_STATE_TRANSITION_POSITION, mTransitionPosition);
outState.putSerializable(ADS_STATE_SHARED_ELEMENT_MAP, mSharedElementMap);
outState.putSerializable(ADS_STATE_SHARED_ELEMENT_MAP, (Serializable) mSharedElementMap);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019 Pranav Pandey
* Copyright 2020 Pranav Pandey
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -33,7 +33,7 @@
import com.pranavpandey.android.dynamic.theme.Theme;

/**
* A simple base adapter to hold an array of colors and displays them in a adapter view.
* A simple base adapter to hold an array of colors and displays them in an adapter view.
*/
public class DynamicColorsAdapter extends BaseAdapter {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019 Pranav Pandey
* Copyright 2020 Pranav Pandey
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -31,7 +31,7 @@
import com.pranavpandey.android.dynamic.support.R;

/**
* A simple base adapter to hold an array of char sequence and display them in a adapter view.
* A simple base adapter to hold an array of char sequence and display them in an adapter view.
*/
public class DynamicSpinnerChoiceAdapter extends BaseAdapter {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019 Pranav Pandey
* Copyright 2020 Pranav Pandey
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -36,17 +36,14 @@
import com.pranavpandey.android.dynamic.support.R;
import com.pranavpandey.android.dynamic.support.utils.DynamicLayoutUtils;

import static androidx.recyclerview.widget.StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS;

/**
* A RecyclerView inside a FrameLayout with some built-in functionality like
* swipe refresh layout, progress bar, etc. which can be initialized quickly.
*/
public abstract class DynamicRecyclerViewFrame extends FrameLayout {

/**
* State key for the fragment super state.
*/
private static final String ADS_RECYCLER_VIEW_SCROLL_OFFSET = "superState";

/**
* Swipe refresh layout to provide pull to refresh functionality.
*
Expand Down Expand Up @@ -166,19 +163,32 @@ public void setAdapter(@NonNull RecyclerView.Adapter adapter) {
}

/**
* Checks for the staggered grid layout manager to avoid the jumping of items by
* scrolling the recycler view to top.
* Handler to update the {@link StaggeredGridLayoutManager} o avoid the jumping of items.
*/
protected void checkForStaggeredGridLayoutManager() {
post(new Runnable() {
@Override
public void run() {
if (mRecyclerView.getLayoutManager() instanceof StaggeredGridLayoutManager) {
private final Runnable mStaggeredGridHandler = new Runnable() {
@Override
public void run() {
if (mRecyclerView.getLayoutManager() instanceof StaggeredGridLayoutManager) {
((StaggeredGridLayoutManager) mRecyclerViewLayoutManager).setGapStrategy(
((StaggeredGridLayoutManager) mRecyclerViewLayoutManager)
.getGapStrategy() | GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS);
((StaggeredGridLayoutManager) mRecyclerViewLayoutManager)
.invalidateSpanAssignments();

if (((StaggeredGridLayoutManager)
mRecyclerViewLayoutManager).getSpanCount() > 1) {
((StaggeredGridLayoutManager) mRecyclerViewLayoutManager)
.scrollToPositionWithOffset(0, 0);
}
}
});
}
};

/**
* Checks for the {@link StaggeredGridLayoutManager} to avoid the jumping of items.
*/
protected void checkForStaggeredGridLayoutManager() {
post(mStaggeredGridHandler);
}

/**
Expand Down Expand Up @@ -276,29 +286,55 @@ public void setOnRefreshListener(

/**
* Show progress bar and hide the recycler view.
*
* @param animate {@code true} to animate the changes.
*/
public void showProgress() {
public void showProgress(boolean animate) {
if (mProgressBar != null) {
TransitionManager.beginDelayedTransition(this);
if (animate) {
TransitionManager.beginDelayedTransition(this);
}

mProgressBar.setVisibility(VISIBLE);
mRecyclerView.setVisibility(GONE);
mProgressBar.show();
}
}

/**
* Show progress bar and hide the recycler view.
*
* @see #showProgress()
*/
public void showProgress() {
showProgress(true);
}

/**
* Hide progress bar and show the recycler view.
*
* @param animate {@code true} to animate the changes.
*/
public void hideProgress() {
public void hideProgress(boolean animate) {
if (mProgressBar != null) {
TransitionManager.beginDelayedTransition(this);
if (animate) {
TransitionManager.beginDelayedTransition(this);
}

mProgressBar.hide();
mRecyclerView.setVisibility(View.VISIBLE);
}
}

/**
* Hide progress bar and show the recycler view.
*
* @see #hideProgress()
*/
public void hideProgress() {
hideProgress(true);
}

/**
* Returns the root scrollable view for this frame layout.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019 Pranav Pandey
* Copyright 2020 Pranav Pandey
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -48,8 +48,8 @@ public abstract class DynamicBinderAdapter<VB extends DynamicRecyclerViewBinder>
@SuppressWarnings("unchecked")
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
int binderPosition = getBinderPosition(position);
getDataBinder(viewHolder.getItemViewType()).onBindViewHolder(viewHolder, binderPosition);
getDataBinder(viewHolder.getItemViewType()).onBindViewHolder(
viewHolder, getBinderPosition(position));
}

@Override
Expand Down Expand Up @@ -111,6 +111,15 @@ public RecyclerView getRecyclerView() {
*/
public abstract int getBinderPosition(int position);

/**
* This method will be called when the data set has been changed.
*/
public void notifyBinderDataSetChanged() {
if (!isComputingLayout()) {
notifyDataSetChanged();
}
}

/**
* This method will be called when an item has been changed in the data binder.
*
Expand Down Expand Up @@ -148,38 +157,36 @@ public void notifyBinderItemRemoved(@NonNull VB binder, int position) {
* @param fromPosition Initial position of the moved item.
* @param toPosition Final position of the moved item.
*/
public void notifyBinderItemMoved(@NonNull VB binder,
int fromPosition, int toPosition) {
notifyItemMoved(getPosition(binder, fromPosition),
getPosition(binder, toPosition));
public void notifyBinderItemMoved(@NonNull VB binder, int fromPosition, int toPosition) {
notifyItemMoved(getPosition(binder, fromPosition), getPosition(binder, toPosition));
}

/**
* This method will be called when the item range of a data binder has been changed.
*
* @param binder The data binder inside the recycler view.
* @param position The position at which the first item has been changed.
* @param itemCount Total no. of items has been changed.
* @param itemCount Total no. of items have been changed.
*/
public abstract void notifyBinderItemRangeChanged(
@NonNull VB binder, int position, int itemCount);

/**
* This method will be called when a set of items has been inserted in a data binder.
* This method will be called when a set of items have been inserted in a data binder.
*
* @param binder The data binder inside the recycler view.
* @param position The position at which the first item has been inserted.
* @param itemCount Total no. of items has been inserted.
* @param itemCount Total no. of items have been inserted.
*/
public abstract void notifyBinderItemRangeInserted(
@NonNull VB binder, int position, int itemCount);

/**
* This method will be called when a set of items has been removed in a data binder.
* This method will be called when a set of items have been removed in a data binder.
*
* @param binder The data binder inside the recycler view.
* @param position The position at which the first item has been removed.
* @param itemCount Total no. of items has been removed.
* @param itemCount Total no. of items have been removed.
*/
public abstract void notifyBinderItemRangeRemoved(
@NonNull VB binder, int position, int itemCount);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019 Pranav Pandey
* Copyright 2020 Pranav Pandey
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -50,15 +50,9 @@ public DynamicItemsAdapter(@NonNull Collection<? extends DynamicItem> dataSet) {
addDataBinder(new DynamicItemBinder(this));
}

@Override
public int getItemViewType(int position) {
return 0;
}

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
((DynamicItemBinder) getDataBinder(getItemViewType(position))).setData(getItem(position));

super.onBindViewHolder(viewHolder, position);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019 Pranav Pandey
* Copyright 2020 Pranav Pandey
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -40,8 +40,7 @@ public abstract class DynamicSimpleBinderAdapter<VB extends DynamicRecyclerViewB
@Override
public int getItemCount() {
int itemCount = 0;
for (int i = 0; i < mDataBinders.size(); i++) {
DynamicRecyclerViewBinder binder = mDataBinders.get(i);
for (VB binder : mDataBinders) {
itemCount += binder.getItemCount();
}

Expand All @@ -50,8 +49,12 @@ public int getItemCount() {

@Override
public int getItemViewType(int position) {
if (mDataBinders.size() == 1) {
return 0;
}

int itemCount = 0;
for (int i = 0; i < mDataBinders.size(); i++) {
for (int i = itemCount; i < mDataBinders.size(); i++) {
itemCount += mDataBinders.get(i).getItemCount();
if (position < itemCount) {
return i;
Expand Down Expand Up @@ -83,8 +86,8 @@ public int getPosition(@NonNull VB binder, int position) {
@Override
public int getBinderPosition(int position) {
int binderItemCount;
for (int i = 0; i < mDataBinders.size(); i++) {
binderItemCount = mDataBinders.get(i).getItemCount();
for (VB binder : mDataBinders) {
binderItemCount = binder.getItemCount();
if (position - binderItemCount < 0) {
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public void notifyBinderItemRangeRemoved(@NonNull VB binder,
*
* @return The {@code enum} corresponding to the given position.
*/
public abstract E getEnumFromPosition(int position);
public abstract @NonNull E getEnumFromPosition(int position);

/**
* Get the item type enum according to the ordinal.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019 Pranav Pandey
* Copyright 2020 Pranav Pandey
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -100,9 +100,7 @@ public int getItemCount() {
public void setData(@Nullable DynamicInfo data) {
this.mData = data;

if (!getRecyclerViewAdapter().isComputingLayout()) {
notifyBinderDataSetChanged();
}
notifyBinderDataSetChanged();
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019 Pranav Pandey
* Copyright 2020 Pranav Pandey
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -98,9 +98,7 @@ public int getItemCount() {
public void setData(@Nullable DynamicInfo data) {
this.mData = data;

if (!getRecyclerViewAdapter().isComputingLayout()) {
notifyBinderDataSetChanged();
}
notifyBinderDataSetChanged();
}

/**
Expand Down
Loading

0 comments on commit 55712ba

Please sign in to comment.