Created
September 3, 2016 15:00
-
-
Save sevar83/35b1d49f688fec92f4f6fd7a5a89d54c to your computer and use it in GitHub Desktop.
Binding adapter for https://github.com/evant/binding-collection-adapter which assigns common parameters to a List/Grid RecyclerView. Automatically restores the state of the old LayoutManager into the new one.
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
public class LMBindingAdapter { | |
// TODO the creation and modification of a layout manager must be done in one class. The creation is in a factory, but the modification is here. | |
@BindingAdapter(value = {"viewMode", "orientation", "reverseLayout", "spanCount", "spanSizeLookup"}, requireAll = false) | |
public static void setLayoutManager(RecyclerView recyclerView, | |
RecyclerViewMode viewMode, | |
@LayoutManagers.Orientation int orientation, | |
boolean reverseLayout, | |
int spanCount, | |
final SpanSizeLookup spanSizeLookup) { | |
if (viewMode == null) { | |
throw new IllegalArgumentException("viewMode must not be null"); | |
} | |
LayoutManagers.LayoutManagerFactory layoutManagerFactory; | |
RecyclerView.LayoutManager oldLayoutManager = recyclerView.getLayoutManager(); | |
Parcelable oldLayoutManagerState = null; | |
if (oldLayoutManager != null) { | |
oldLayoutManagerState = oldLayoutManager.onSaveInstanceState(); | |
} | |
switch (viewMode) { | |
case LIST: | |
if (oldLayoutManager instanceof LinearLayoutManager | |
&& !(oldLayoutManager instanceof GridLayoutManager)) { | |
((LinearLayoutManager) oldLayoutManager).setOrientation(orientation); | |
((LinearLayoutManager) oldLayoutManager).setReverseLayout(reverseLayout); | |
} else { | |
if (orientation != LinearLayoutManager.VERTICAL) { | |
layoutManagerFactory = LayoutManagers.linear(orientation, reverseLayout); | |
} else { | |
layoutManagerFactory = LayoutManagers.linear(); | |
} | |
RecyclerView.LayoutManager newLayoutManager = layoutManagerFactory.create(recyclerView); | |
recyclerView.setLayoutManager(newLayoutManager); | |
// Attempt to transfer the saved state of the old LM into the new one | |
if (oldLayoutManagerState != null && oldLayoutManager instanceof LinearLayoutManager) { | |
newLayoutManager.onRestoreInstanceState(oldLayoutManagerState); | |
} | |
} | |
break; | |
case GRID: | |
if (spanCount < 1) { | |
throw new IllegalArgumentException("spanCount must be defined"); | |
} | |
final GridLayoutManager gridLayoutManager; | |
if (oldLayoutManager instanceof GridLayoutManager) { | |
gridLayoutManager = (GridLayoutManager) oldLayoutManager; | |
gridLayoutManager.setSpanCount(spanCount); | |
} else { | |
if (orientation != GridLayoutManager.VERTICAL) { | |
layoutManagerFactory = LayoutManagers.grid(spanCount, orientation, reverseLayout); | |
} else { | |
layoutManagerFactory = LayoutManagers.grid(spanCount); | |
} | |
gridLayoutManager = (GridLayoutManager) layoutManagerFactory.create(recyclerView); | |
recyclerView.setLayoutManager(gridLayoutManager); | |
// Attempt to transfer the saved state of the old LM into the new one | |
if (oldLayoutManagerState != null && oldLayoutManager instanceof LinearLayoutManager) { | |
gridLayoutManager.onRestoreInstanceState(oldLayoutManagerState); | |
} | |
} | |
final GridLayoutManager.SpanSizeLookup lookup; | |
if (spanSizeLookup == null) { | |
lookup = new GridLayoutManager.DefaultSpanSizeLookup(); | |
} else { | |
lookup = new GridLayoutManager.SpanSizeLookup() { | |
@Override | |
public int getSpanSize(int position) { | |
int spanSize = spanSizeLookup.getSpanSize(position); | |
return spanSize > 0 ? spanSize : gridLayoutManager.getSpanCount(); | |
} | |
}; | |
} | |
gridLayoutManager.setSpanSizeLookup(lookup); | |
break; | |
/*case STAGGERED_GRID: | |
if (spanCount < 1) { | |
throw new IllegalArgumentException("spanCount must be defined"); | |
} | |
layoutManagerFactory = LayoutManagers.staggeredGrid(spanCount, orientation); | |
recyclerView.setLayoutManager(layoutManagerFactory.create(recyclerView)); | |
break;*/ | |
default: | |
throw new IllegalArgumentException("Unsupported view mode"); | |
} | |
} | |
} |
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
public enum RecyclerViewMode { | |
LIST(R.string.compact_list, R.drawable.ic_view_list_white_24dp), | |
GRID(R.string.grid, R.drawable.ic_view_module_white_24dp), | |
STAGGERED_GRID(R.string.staggered_grid, R.drawable.ic_dashboard_white_24dp); | |
private final int title; | |
private final int icon; | |
RecyclerViewMode(@StringRes int title, @DrawableRes int icon) { | |
this.title = title; | |
this.icon = icon; | |
} | |
public int getTitle() { | |
return title; | |
} | |
public int getIcon() { | |
return icon; | |
} | |
} |
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
public interface SpanSizeLookup { | |
/** | |
* Gets the number of span positions occupied by the item | |
* @param itemPosition the adapter position of the item | |
* @return The span count or -1 to occupy all available spans. | |
*/ | |
int getSpanSize(int itemPosition); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment