summaryrefslogtreecommitdiff
path: root/library/recyclerview/src/com/android/setupwizardlib/template/RecyclerMixin.java
diff options
context:
space:
mode:
Diffstat (limited to 'library/recyclerview/src/com/android/setupwizardlib/template/RecyclerMixin.java')
-rw-r--r--library/recyclerview/src/com/android/setupwizardlib/template/RecyclerMixin.java393
1 files changed, 188 insertions, 205 deletions
diff --git a/library/recyclerview/src/com/android/setupwizardlib/template/RecyclerMixin.java b/library/recyclerview/src/com/android/setupwizardlib/template/RecyclerMixin.java
index 32e7bd8..a6c6526 100644
--- a/library/recyclerview/src/com/android/setupwizardlib/template/RecyclerMixin.java
+++ b/library/recyclerview/src/com/android/setupwizardlib/template/RecyclerMixin.java
@@ -21,16 +21,14 @@ import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Build.VERSION_CODES;
-import android.util.AttributeSet;
-import android.view.View;
-
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.Adapter;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
-
+import android.util.AttributeSet;
+import android.view.View;
import com.android.setupwizardlib.DividerItemDecoration;
import com.android.setupwizardlib.R;
import com.android.setupwizardlib.TemplateLayout;
@@ -51,223 +49,208 @@ import com.android.setupwizardlib.view.HeaderRecyclerView.HeaderAdapter;
*/
public class RecyclerMixin implements Mixin {
- private TemplateLayout mTemplateLayout;
+ private final TemplateLayout templateLayout;
- @NonNull
- private final RecyclerView mRecyclerView;
+ @NonNull private final RecyclerView recyclerView;
- @Nullable
- private View mHeader;
+ @Nullable private View header;
- @NonNull
- private DividerItemDecoration mDividerDecoration;
+ @NonNull private DividerItemDecoration dividerDecoration;
- private Drawable mDefaultDivider;
- private Drawable mDivider;
+ private Drawable defaultDivider;
+ private Drawable divider;
- private int mDividerInsetStart;
- private int mDividerInsetEnd;
+ private int dividerInsetStart;
+ private int dividerInsetEnd;
- /**
- * Creates the RecyclerMixin. Unlike typical mixins which are created in the constructor, this
- * mixin should be called in {@link TemplateLayout#onTemplateInflated()}, which is called by
- * the super constructor, because the recycler view and the header needs to be made available
- * before other mixins from the super class.
- *
- * @param layout The layout this mixin belongs to.
- */
- public RecyclerMixin(@NonNull TemplateLayout layout, @NonNull RecyclerView recyclerView) {
- mTemplateLayout = layout;
+ /**
+ * Creates the RecyclerMixin. Unlike typical mixins which are created in the constructor, this
+ * mixin should be called in {@link TemplateLayout#onTemplateInflated()}, which is called by the
+ * super constructor, because the recycler view and the header needs to be made available before
+ * other mixins from the super class.
+ *
+ * @param layout The layout this mixin belongs to.
+ */
+ public RecyclerMixin(@NonNull TemplateLayout layout, @NonNull RecyclerView recyclerView) {
+ templateLayout = layout;
- mDividerDecoration = new DividerItemDecoration(mTemplateLayout.getContext());
+ dividerDecoration = new DividerItemDecoration(templateLayout.getContext());
- // The recycler view needs to be available
- mRecyclerView = recyclerView;
- mRecyclerView.setLayoutManager(new LinearLayoutManager(mTemplateLayout.getContext()));
+ // The recycler view needs to be available
+ this.recyclerView = recyclerView;
+ this.recyclerView.setLayoutManager(new LinearLayoutManager(templateLayout.getContext()));
- if (recyclerView instanceof HeaderRecyclerView) {
- mHeader = ((HeaderRecyclerView) recyclerView).getHeader();
- }
-
- mRecyclerView.addItemDecoration(mDividerDecoration);
+ if (recyclerView instanceof HeaderRecyclerView) {
+ header = ((HeaderRecyclerView) recyclerView).getHeader();
}
- /**
- * Parse XML attributes and configures this mixin and the recycler view accordingly. This should
- * be called from the constructor of the layout.
- *
- * @param attrs The {@link AttributeSet} as passed into the constructor. Can be null if the
- * layout was not created from XML.
- * @param defStyleAttr The default style attribute as passed into the layout constructor. Can be
- * 0 if it is not needed.
- */
- public void parseAttributes(@Nullable AttributeSet attrs, int defStyleAttr) {
- final Context context = mTemplateLayout.getContext();
- final TypedArray a = context.obtainStyledAttributes(
- attrs, R.styleable.SuwRecyclerMixin, defStyleAttr, 0);
-
- final int entries = a.getResourceId(R.styleable.SuwRecyclerMixin_android_entries, 0);
- if (entries != 0) {
- final ItemHierarchy inflated = new ItemInflater(context).inflate(entries);
- final RecyclerItemAdapter adapter = new RecyclerItemAdapter(inflated);
- adapter.setHasStableIds(a.getBoolean(
- R.styleable.SuwRecyclerMixin_suwHasStableIds, false));
- setAdapter(adapter);
- }
- int dividerInset =
- a.getDimensionPixelSize(R.styleable.SuwRecyclerMixin_suwDividerInset, -1);
- if (dividerInset != -1) {
- setDividerInset(dividerInset);
- } else {
- int dividerInsetStart =
- a.getDimensionPixelSize(R.styleable.SuwRecyclerMixin_suwDividerInsetStart, 0);
- int dividerInsetEnd =
- a.getDimensionPixelSize(R.styleable.SuwRecyclerMixin_suwDividerInsetEnd, 0);
- setDividerInsets(dividerInsetStart, dividerInsetEnd);
- }
-
- a.recycle();
+ this.recyclerView.addItemDecoration(dividerDecoration);
+ }
+
+ /**
+ * Parse XML attributes and configures this mixin and the recycler view accordingly. This should
+ * be called from the constructor of the layout.
+ *
+ * @param attrs The {@link AttributeSet} as passed into the constructor. Can be null if the layout
+ * was not created from XML.
+ * @param defStyleAttr The default style attribute as passed into the layout constructor. Can be 0
+ * if it is not needed.
+ */
+ public void parseAttributes(@Nullable AttributeSet attrs, int defStyleAttr) {
+ final Context context = templateLayout.getContext();
+ final TypedArray a =
+ context.obtainStyledAttributes(attrs, R.styleable.SuwRecyclerMixin, defStyleAttr, 0);
+
+ final int entries = a.getResourceId(R.styleable.SuwRecyclerMixin_android_entries, 0);
+ if (entries != 0) {
+ final ItemHierarchy inflated = new ItemInflater(context).inflate(entries);
+ final RecyclerItemAdapter adapter = new RecyclerItemAdapter(inflated);
+ adapter.setHasStableIds(a.getBoolean(R.styleable.SuwRecyclerMixin_suwHasStableIds, false));
+ setAdapter(adapter);
}
-
- /**
- * @return The recycler view contained in the layout, as marked by
- * {@code @id/suw_recycler_view}. This will return {@code null} if the recycler view
- * doesn't exist in the layout.
- */
- @SuppressWarnings("NullableProblems") // If clients guarantee that the template has a recycler
- // view, and call this after the template is inflated,
- // this will not return null.
- public RecyclerView getRecyclerView() {
- return mRecyclerView;
+ int dividerInset = a.getDimensionPixelSize(R.styleable.SuwRecyclerMixin_suwDividerInset, -1);
+ if (dividerInset != -1) {
+ setDividerInset(dividerInset);
+ } else {
+ int dividerInsetStart =
+ a.getDimensionPixelSize(R.styleable.SuwRecyclerMixin_suwDividerInsetStart, 0);
+ int dividerInsetEnd =
+ a.getDimensionPixelSize(R.styleable.SuwRecyclerMixin_suwDividerInsetEnd, 0);
+ setDividerInsets(dividerInsetStart, dividerInsetEnd);
}
- /**
- * Gets the header view of the recycler layout. This is useful for other mixins if they need to
- * access views within the header, usually via {@link TemplateLayout#findManagedViewById(int)}.
- */
- @SuppressWarnings("NullableProblems") // If clients guarantee that the template has a header,
- // this call will not return null.
- public View getHeader() {
- return mHeader;
+ a.recycle();
+ }
+
+ /**
+ * @return The recycler view contained in the layout, as marked by {@code @id/suw_recycler_view}.
+ * This will return {@code null} if the recycler view doesn't exist in the layout.
+ */
+ @SuppressWarnings("NullableProblems") // If clients guarantee that the template has a recycler
+ // view, and call this after the template is inflated,
+ // this will not return null.
+ public RecyclerView getRecyclerView() {
+ return recyclerView;
+ }
+
+ /**
+ * Gets the header view of the recycler layout. This is useful for other mixins if they need to
+ * access views within the header, usually via {@link TemplateLayout#findManagedViewById(int)}.
+ */
+ @SuppressWarnings("NullableProblems") // If clients guarantee that the template has a header,
+ // this call will not return null.
+ public View getHeader() {
+ return header;
+ }
+
+ /**
+ * Recycler mixin needs to update the dividers if the layout direction has changed. This method
+ * should be called when {@link View#onLayout(boolean, int, int, int, int)} of the template is
+ * called.
+ */
+ public void onLayout() {
+ if (divider == null) {
+ // Update divider in case layout direction has just been resolved
+ updateDivider();
}
-
- /**
- * Recycler mixin needs to update the dividers if the layout direction has changed. This method
- * should be called when {@link View#onLayout(boolean, int, int, int, int)} of the template
- * is called.
- */
- public void onLayout() {
- if (mDivider == null) {
- // Update divider in case layout direction has just been resolved
- updateDivider();
- }
+ }
+
+ /**
+ * Gets the adapter of the recycler view in this layout. If the adapter includes a header, this
+ * method will unwrap it and return the underlying adapter.
+ *
+ * @return The adapter, or {@code null} if the recycler view has no adapter.
+ */
+ public Adapter<? extends ViewHolder> getAdapter() {
+ @SuppressWarnings("unchecked") // RecyclerView.getAdapter returns raw type :(
+ final RecyclerView.Adapter<? extends ViewHolder> adapter = recyclerView.getAdapter();
+ if (adapter instanceof HeaderAdapter) {
+ return ((HeaderAdapter<? extends ViewHolder>) adapter).getWrappedAdapter();
}
-
- /**
- * Gets the adapter of the recycler view in this layout. If the adapter includes a header,
- * this method will unwrap it and return the underlying adapter.
- *
- * @return The adapter, or {@code null} if the recycler view has no adapter.
- */
- public Adapter<? extends ViewHolder> getAdapter() {
- @SuppressWarnings("unchecked") // RecyclerView.getAdapter returns raw type :(
- final RecyclerView.Adapter<? extends ViewHolder> adapter = mRecyclerView.getAdapter();
- if (adapter instanceof HeaderAdapter) {
- return ((HeaderAdapter<? extends ViewHolder>) adapter).getWrappedAdapter();
- }
- return adapter;
+ return adapter;
+ }
+
+ /** Sets the adapter on the recycler view in this layout. */
+ public void setAdapter(Adapter<? extends ViewHolder> adapter) {
+ recyclerView.setAdapter(adapter);
+ }
+
+ /** @deprecated Use {@link #setDividerInsets(int, int)} instead. */
+ @Deprecated
+ public void setDividerInset(int inset) {
+ setDividerInsets(inset, 0);
+ }
+
+ /**
+ * Sets the start inset of the divider. This will use the default divider drawable set in the
+ * theme and apply insets to it.
+ *
+ * @param start The number of pixels to inset on the "start" side of the list divider. Typically
+ * this will be either {@code @dimen/suw_items_glif_icon_divider_inset} or
+ * {@code @dimen/suw_items_glif_text_divider_inset}.
+ * @param end The number of pixels to inset on the "end" side of the list divider.
+ */
+ public void setDividerInsets(int start, int end) {
+ dividerInsetStart = start;
+ dividerInsetEnd = end;
+ updateDivider();
+ }
+
+ /**
+ * @return The number of pixels inset on the start side of the divider.
+ * @deprecated This is the same as {@link #getDividerInsetStart()}. Use that instead.
+ */
+ @Deprecated
+ public int getDividerInset() {
+ return getDividerInsetStart();
+ }
+
+ /** @return The number of pixels inset on the start side of the divider. */
+ public int getDividerInsetStart() {
+ return dividerInsetStart;
+ }
+
+ /** @return The number of pixels inset on the end side of the divider. */
+ public int getDividerInsetEnd() {
+ return dividerInsetEnd;
+ }
+
+ private void updateDivider() {
+ boolean shouldUpdate = true;
+ if (Build.VERSION.SDK_INT >= VERSION_CODES.KITKAT) {
+ shouldUpdate = templateLayout.isLayoutDirectionResolved();
}
-
- /**
- * Sets the adapter on the recycler view in this layout.
- */
- public void setAdapter(Adapter<? extends ViewHolder> adapter) {
- mRecyclerView.setAdapter(adapter);
- }
-
- /**
- * @deprecated Use {@link #setDividerInsets(int, int)} instead.
- */
- @Deprecated
- public void setDividerInset(int inset) {
- setDividerInsets(inset, 0);
- }
-
- /**
- * Sets the start inset of the divider. This will use the default divider drawable set in the
- * theme and apply insets to it.
- *
- * @param start The number of pixels to inset on the "start" side of the list divider. Typically
- * this will be either {@code @dimen/suw_items_glif_icon_divider_inset} or
- * {@code @dimen/suw_items_glif_text_divider_inset}.
- * @param end The number of pixels to inset on the "end" side of the list divider.
- */
- public void setDividerInsets(int start, int end) {
- mDividerInsetStart = start;
- mDividerInsetEnd = end;
- updateDivider();
- }
-
- /**
- * @return The number of pixels inset on the start side of the divider.
- * @deprecated This is the same as {@link #getDividerInsetStart()}. Use that instead.
- */
- @Deprecated
- public int getDividerInset() {
- return getDividerInsetStart();
- }
-
- /**
- * @return The number of pixels inset on the start side of the divider.
- */
- public int getDividerInsetStart() {
- return mDividerInsetStart;
- }
-
- /**
- * @return The number of pixels inset on the end side of the divider.
- */
- public int getDividerInsetEnd() {
- return mDividerInsetEnd;
- }
-
- private void updateDivider() {
- boolean shouldUpdate = true;
- if (Build.VERSION.SDK_INT >= VERSION_CODES.KITKAT) {
- shouldUpdate = mTemplateLayout.isLayoutDirectionResolved();
- }
- if (shouldUpdate) {
- if (mDefaultDivider == null) {
- mDefaultDivider = mDividerDecoration.getDivider();
- }
- mDivider = DrawableLayoutDirectionHelper.createRelativeInsetDrawable(
- mDefaultDivider,
- mDividerInsetStart /* start */,
- 0 /* top */,
- mDividerInsetEnd /* end */,
- 0 /* bottom */,
- mTemplateLayout);
- mDividerDecoration.setDivider(mDivider);
- }
- }
-
- /**
- * @return The drawable used as the divider.
- */
- public Drawable getDivider() {
- return mDivider;
- }
-
- /**
- * Sets the divider item decoration directly. This is a low level method which should be used
- * only if custom divider behavior is needed, for example if the divider should be shown /
- * hidden in some specific cases for view holders that cannot implement
- * {@link com.android.setupwizardlib.DividerItemDecoration.DividedViewHolder}.
- */
- public void setDividerItemDecoration(@NonNull DividerItemDecoration decoration) {
- mRecyclerView.removeItemDecoration(mDividerDecoration);
- mDividerDecoration = decoration;
- mRecyclerView.addItemDecoration(mDividerDecoration);
- updateDivider();
+ if (shouldUpdate) {
+ if (defaultDivider == null) {
+ defaultDivider = dividerDecoration.getDivider();
+ }
+ divider =
+ DrawableLayoutDirectionHelper.createRelativeInsetDrawable(
+ defaultDivider,
+ dividerInsetStart /* start */,
+ 0 /* top */,
+ dividerInsetEnd /* end */,
+ 0 /* bottom */,
+ templateLayout);
+ dividerDecoration.setDivider(divider);
}
+ }
+
+ /** @return The drawable used as the divider. */
+ public Drawable getDivider() {
+ return divider;
+ }
+
+ /**
+ * Sets the divider item decoration directly. This is a low level method which should be used only
+ * if custom divider behavior is needed, for example if the divider should be shown / hidden in
+ * some specific cases for view holders that cannot implement {@link
+ * com.android.setupwizardlib.DividerItemDecoration.DividedViewHolder}.
+ */
+ public void setDividerItemDecoration(@NonNull DividerItemDecoration decoration) {
+ recyclerView.removeItemDecoration(dividerDecoration);
+ dividerDecoration = decoration;
+ recyclerView.addItemDecoration(dividerDecoration);
+ updateDivider();
+ }
}