diff options
Diffstat (limited to 'library/recyclerview/src/com/android/setupwizardlib/DividerItemDecoration.java')
-rw-r--r-- | library/recyclerview/src/com/android/setupwizardlib/DividerItemDecoration.java | 356 |
1 files changed, 170 insertions, 186 deletions
diff --git a/library/recyclerview/src/com/android/setupwizardlib/DividerItemDecoration.java b/library/recyclerview/src/com/android/setupwizardlib/DividerItemDecoration.java index 2db17f8..128ed6b 100644 --- a/library/recyclerview/src/com/android/setupwizardlib/DividerItemDecoration.java +++ b/library/recyclerview/src/com/android/setupwizardlib/DividerItemDecoration.java @@ -21,223 +21,207 @@ import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; -import android.view.View; - import androidx.annotation.IntDef; import androidx.core.view.ViewCompat; import androidx.recyclerview.widget.RecyclerView; - +import android.view.View; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * An {@link androidx.recyclerview.widget.RecyclerView.ItemDecoration} for RecyclerView to draw - * dividers between items. This ItemDecoration will draw the drawable specified by - * {@link #setDivider(android.graphics.drawable.Drawable)} as the divider in between each item by - * default, and the behavior of whether the divider is shown can be customized by subclassing - * {@link com.android.setupwizardlib.DividerItemDecoration.DividedViewHolder}. + * dividers between items. This ItemDecoration will draw the drawable specified by {@link + * #setDivider(android.graphics.drawable.Drawable)} as the divider in between each item by default, + * and the behavior of whether the divider is shown can be customized by subclassing {@link + * com.android.setupwizardlib.DividerItemDecoration.DividedViewHolder}. * * <p>Modified from v14 PreferenceFragment.DividerDecoration. */ public class DividerItemDecoration extends RecyclerView.ItemDecoration { - /* static section */ + /* static section */ + + /** + * An interface to be implemented by a {@link RecyclerView.ViewHolder} which controls whether + * dividers should be shown above and below that item. + */ + public interface DividedViewHolder { /** - * An interface to be implemented by a {@link RecyclerView.ViewHolder} which controls whether - * dividers should be shown above and below that item. + * Returns whether divider is allowed above this item. A divider will be shown only if both + * items immediately above and below it allows this divider. */ - public interface DividedViewHolder { - - /** - * Returns whether divider is allowed above this item. A divider will be shown only if both - * items immediately above and below it allows this divider. - */ - boolean isDividerAllowedAbove(); - - /** - * Returns whether divider is allowed below this item. A divider will be shown only if both - * items immediately above and below it allows this divider. - */ - boolean isDividerAllowedBelow(); - } - - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - DIVIDER_CONDITION_EITHER, - DIVIDER_CONDITION_BOTH}) - public @interface DividerCondition {} - - public static final int DIVIDER_CONDITION_EITHER = 0; - public static final int DIVIDER_CONDITION_BOTH = 1; + boolean isDividerAllowedAbove(); /** - * @deprecated Use {@link #DividerItemDecoration(android.content.Context)} + * Returns whether divider is allowed below this item. A divider will be shown only if both + * items immediately above and below it allows this divider. */ - @Deprecated - public static DividerItemDecoration getDefault(Context context) { - return new DividerItemDecoration(context); - } - - /* non-static section */ - - private Drawable mDivider; - private int mDividerHeight; - private int mDividerIntrinsicHeight; - @DividerCondition - private int mDividerCondition; + boolean isDividerAllowedBelow(); + } - public DividerItemDecoration() { - } + @Retention(RetentionPolicy.SOURCE) + @IntDef({DIVIDER_CONDITION_EITHER, DIVIDER_CONDITION_BOTH}) + public @interface DividerCondition {} - public DividerItemDecoration(Context context) { - final TypedArray a = context.obtainStyledAttributes(R.styleable.SuwDividerItemDecoration); - final Drawable divider = a.getDrawable( - R.styleable.SuwDividerItemDecoration_android_listDivider); - final int dividerHeight = a.getDimensionPixelSize( - R.styleable.SuwDividerItemDecoration_android_dividerHeight, 0); - @DividerCondition final int dividerCondition = a.getInt( - R.styleable.SuwDividerItemDecoration_suwDividerCondition, - DIVIDER_CONDITION_EITHER); - a.recycle(); - - setDivider(divider); - setDividerHeight(dividerHeight); - setDividerCondition(dividerCondition); - } + public static final int DIVIDER_CONDITION_EITHER = 0; + public static final int DIVIDER_CONDITION_BOTH = 1; - @Override - public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { - if (mDivider == null) { - return; - } - final int childCount = parent.getChildCount(); - final int width = parent.getWidth(); - final int dividerHeight = mDividerHeight != 0 ? mDividerHeight : mDividerIntrinsicHeight; - for (int childViewIndex = 0; childViewIndex < childCount; childViewIndex++) { - final View view = parent.getChildAt(childViewIndex); - if (shouldDrawDividerBelow(view, parent)) { - final int top = (int) ViewCompat.getY(view) + view.getHeight(); - mDivider.setBounds(0, top, width, top + dividerHeight); - mDivider.draw(c); - } - } - } + /** @deprecated Use {@link #DividerItemDecoration(android.content.Context)} */ + @Deprecated + public static DividerItemDecoration getDefault(Context context) { + return new DividerItemDecoration(context); + } - @Override - public void getItemOffsets(Rect outRect, View view, RecyclerView parent, - RecyclerView.State state) { - if (shouldDrawDividerBelow(view, parent)) { - outRect.bottom = mDividerHeight != 0 ? mDividerHeight : mDividerIntrinsicHeight; - } - } + /* non-static section */ - private boolean shouldDrawDividerBelow(View view, RecyclerView parent) { - final RecyclerView.ViewHolder holder = parent.getChildViewHolder(view); - final int index = holder.getLayoutPosition(); - final int lastItemIndex = parent.getAdapter().getItemCount() - 1; - if (isDividerAllowedBelow(holder)) { - if (mDividerCondition == DIVIDER_CONDITION_EITHER) { - // Draw the divider without consulting the next item if we only - // need permission for either above or below. - return true; - } - } else if (mDividerCondition == DIVIDER_CONDITION_BOTH || index == lastItemIndex) { - // Don't draw if the current view holder doesn't allow drawing below - // and the current theme requires permission for both the item below and above. - // Also, if this is the last item, there is no item below to ask permission - // for whether to draw a divider above, so don't draw it. - return false; - } - // Require permission from index below to draw the divider. - if (index < lastItemIndex) { - final RecyclerView.ViewHolder nextHolder = - parent.findViewHolderForLayoutPosition(index + 1); - if (!isDividerAllowedAbove(nextHolder)) { - // Don't draw if the next view holder doesn't allow drawing above - return false; - } - } - return true; - } - - /** - * Whether a divider is allowed above the view holder. The allowed values will be combined - * according to {@link #getDividerCondition()}. The default implementation delegates to - * {@link com.android.setupwizardlib.DividerItemDecoration.DividedViewHolder}, or simply allows - * the divider if the view holder doesn't implement {@code DividedViewHolder}. Subclasses can - * override this to give more information to decide whether a divider should be drawn. - * - * @return True if divider is allowed above this view holder. - */ - protected boolean isDividerAllowedAbove(RecyclerView.ViewHolder viewHolder) { - return !(viewHolder instanceof DividedViewHolder) - || ((DividedViewHolder) viewHolder).isDividerAllowedAbove(); - } + private Drawable divider; + private int dividerHeight; + private int dividerIntrinsicHeight; + @DividerCondition private int dividerCondition; - /** - * Whether a divider is allowed below the view holder. The allowed values will be combined - * according to {@link #getDividerCondition()}. The default implementation delegates to - * {@link com.android.setupwizardlib.DividerItemDecoration.DividedViewHolder}, or simply allows - * the divider if the view holder doesn't implement {@code DividedViewHolder}. Subclasses can - * override this to give more information to decide whether a divider should be drawn. - * - * @return True if divider is allowed below this view holder. - */ - protected boolean isDividerAllowedBelow(RecyclerView.ViewHolder viewHolder) { - return !(viewHolder instanceof DividedViewHolder) - || ((DividedViewHolder) viewHolder).isDividerAllowedBelow(); - } + public DividerItemDecoration() {} - /** - * Sets the drawable to be used as the divider. - */ - public void setDivider(Drawable divider) { - if (divider != null) { - mDividerIntrinsicHeight = divider.getIntrinsicHeight(); - } else { - mDividerIntrinsicHeight = 0; - } - mDivider = divider; + public DividerItemDecoration(Context context) { + final TypedArray a = context.obtainStyledAttributes(R.styleable.SuwDividerItemDecoration); + final Drawable divider = + a.getDrawable(R.styleable.SuwDividerItemDecoration_android_listDivider); + final int dividerHeight = + a.getDimensionPixelSize(R.styleable.SuwDividerItemDecoration_android_dividerHeight, 0); + @DividerCondition + final int dividerCondition = + a.getInt( + R.styleable.SuwDividerItemDecoration_suwDividerCondition, DIVIDER_CONDITION_EITHER); + a.recycle(); + + setDivider(divider); + setDividerHeight(dividerHeight); + setDividerCondition(dividerCondition); + } + + @Override + public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { + if (divider == null) { + return; } - - /** - * Gets the drawable currently used as the divider. - */ - public Drawable getDivider() { - return mDivider; + final int childCount = parent.getChildCount(); + final int width = parent.getWidth(); + final int dividerHeight = this.dividerHeight != 0 ? this.dividerHeight : dividerIntrinsicHeight; + for (int childViewIndex = 0; childViewIndex < childCount; childViewIndex++) { + final View view = parent.getChildAt(childViewIndex); + if (shouldDrawDividerBelow(view, parent)) { + final int top = (int) ViewCompat.getY(view) + view.getHeight(); + divider.setBounds(0, top, width, top + dividerHeight); + divider.draw(c); + } } + } - /** - * Sets the divider height, in pixels. - */ - public void setDividerHeight(int dividerHeight) { - mDividerHeight = dividerHeight; + @Override + public void getItemOffsets( + Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { + if (shouldDrawDividerBelow(view, parent)) { + outRect.bottom = dividerHeight != 0 ? dividerHeight : dividerIntrinsicHeight; } - - /** - * Gets the divider height, in pixels. - */ - public int getDividerHeight() { - return mDividerHeight; + } + + private boolean shouldDrawDividerBelow(View view, RecyclerView parent) { + final RecyclerView.ViewHolder holder = parent.getChildViewHolder(view); + final int index = holder.getLayoutPosition(); + final int lastItemIndex = parent.getAdapter().getItemCount() - 1; + if (isDividerAllowedBelow(holder)) { + if (dividerCondition == DIVIDER_CONDITION_EITHER) { + // Draw the divider without consulting the next item if we only + // need permission for either above or below. + return true; + } + } else if (dividerCondition == DIVIDER_CONDITION_BOTH || index == lastItemIndex) { + // Don't draw if the current view holder doesn't allow drawing below + // and the current theme requires permission for both the item below and above. + // Also, if this is the last item, there is no item below to ask permission + // for whether to draw a divider above, so don't draw it. + return false; } - - /** - * Sets whether the divider needs permission from both the item view holder below - * and above from where the divider would draw itself or just needs permission from - * one or the other before drawing itself. - */ - public void setDividerCondition(@DividerCondition int dividerCondition) { - mDividerCondition = dividerCondition; + // Require permission from index below to draw the divider. + if (index < lastItemIndex) { + final RecyclerView.ViewHolder nextHolder = parent.findViewHolderForLayoutPosition(index + 1); + if (!isDividerAllowedAbove(nextHolder)) { + // Don't draw if the next view holder doesn't allow drawing above + return false; + } } - - /** - * Gets whether the divider needs permission from both the item view holder below - * and above from where the divider would draw itself or just needs permission from - * one or the other before drawing itself. - */ - @DividerCondition - public int getDividerCondition() { - return mDividerCondition; + return true; + } + + /** + * Whether a divider is allowed above the view holder. The allowed values will be combined + * according to {@link #getDividerCondition()}. The default implementation delegates to {@link + * com.android.setupwizardlib.DividerItemDecoration.DividedViewHolder}, or simply allows the + * divider if the view holder doesn't implement {@code DividedViewHolder}. Subclasses can override + * this to give more information to decide whether a divider should be drawn. + * + * @return True if divider is allowed above this view holder. + */ + protected boolean isDividerAllowedAbove(RecyclerView.ViewHolder viewHolder) { + return !(viewHolder instanceof DividedViewHolder) + || ((DividedViewHolder) viewHolder).isDividerAllowedAbove(); + } + + /** + * Whether a divider is allowed below the view holder. The allowed values will be combined + * according to {@link #getDividerCondition()}. The default implementation delegates to {@link + * com.android.setupwizardlib.DividerItemDecoration.DividedViewHolder}, or simply allows the + * divider if the view holder doesn't implement {@code DividedViewHolder}. Subclasses can override + * this to give more information to decide whether a divider should be drawn. + * + * @return True if divider is allowed below this view holder. + */ + protected boolean isDividerAllowedBelow(RecyclerView.ViewHolder viewHolder) { + return !(viewHolder instanceof DividedViewHolder) + || ((DividedViewHolder) viewHolder).isDividerAllowedBelow(); + } + + /** Sets the drawable to be used as the divider. */ + public void setDivider(Drawable divider) { + if (divider != null) { + dividerIntrinsicHeight = divider.getIntrinsicHeight(); + } else { + dividerIntrinsicHeight = 0; } + this.divider = divider; + } + + /** Gets the drawable currently used as the divider. */ + public Drawable getDivider() { + return divider; + } + + /** Sets the divider height, in pixels. */ + public void setDividerHeight(int dividerHeight) { + this.dividerHeight = dividerHeight; + } + + /** Gets the divider height, in pixels. */ + public int getDividerHeight() { + return dividerHeight; + } + + /** + * Sets whether the divider needs permission from both the item view holder below and above from + * where the divider would draw itself or just needs permission from one or the other before + * drawing itself. + */ + public void setDividerCondition(@DividerCondition int dividerCondition) { + this.dividerCondition = dividerCondition; + } + + /** + * Gets whether the divider needs permission from both the item view holder below and above from + * where the divider would draw itself or just needs permission from one or the other before + * drawing itself. + */ + @DividerCondition + public int getDividerCondition() { + return dividerCondition; + } } |