diff options
Diffstat (limited to 'library/main/src/com/android/setupwizardlib/template/ListMixin.java')
-rw-r--r-- | library/main/src/com/android/setupwizardlib/template/ListMixin.java | 328 |
1 files changed, 154 insertions, 174 deletions
diff --git a/library/main/src/com/android/setupwizardlib/template/ListMixin.java b/library/main/src/com/android/setupwizardlib/template/ListMixin.java index cbc29b5..066141e 100644 --- a/library/main/src/com/android/setupwizardlib/template/ListMixin.java +++ b/library/main/src/com/android/setupwizardlib/template/ListMixin.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 androidx.annotation.AttrRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import android.util.AttributeSet; import android.view.View; import android.widget.HeaderViewListAdapter; import android.widget.ListAdapter; import android.widget.ListView; - -import androidx.annotation.AttrRes; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - import com.android.setupwizardlib.R; import com.android.setupwizardlib.TemplateLayout; import com.android.setupwizardlib.items.ItemAdapter; @@ -38,188 +36,170 @@ import com.android.setupwizardlib.items.ItemGroup; import com.android.setupwizardlib.items.ItemInflater; import com.android.setupwizardlib.util.DrawableLayoutDirectionHelper; -/** - * A {@link Mixin} for interacting with ListViews. - */ +/** A {@link Mixin} for interacting with ListViews. */ public class ListMixin implements Mixin { - private TemplateLayout mTemplateLayout; - - @Nullable - private ListView mListView; - - private Drawable mDivider; - private Drawable mDefaultDivider; - - private int mDividerInsetStart; - private int mDividerInsetEnd; - - /** - * @param layout The layout this mixin belongs to. - */ - public ListMixin(@NonNull TemplateLayout layout, @Nullable AttributeSet attrs, - @AttrRes int defStyleAttr) { - mTemplateLayout = layout; - - final Context context = layout.getContext(); - final TypedArray a = context.obtainStyledAttributes( - attrs, R.styleable.SuwListMixin, defStyleAttr, 0); - - final int entries = a.getResourceId(R.styleable.SuwListMixin_android_entries, 0); - if (entries != 0) { - final ItemGroup inflated = - (ItemGroup) new ItemInflater(context).inflate(entries); - setAdapter(new ItemAdapter(inflated)); - } - int dividerInset = - a.getDimensionPixelSize(R.styleable.SuwListMixin_suwDividerInset, -1); - if (dividerInset != -1) { - setDividerInset(dividerInset); - } else { - int dividerInsetStart = - a.getDimensionPixelSize(R.styleable.SuwListMixin_suwDividerInsetStart, 0); - int dividerInsetEnd = - a.getDimensionPixelSize(R.styleable.SuwListMixin_suwDividerInsetEnd, 0); - setDividerInsets(dividerInsetStart, dividerInsetEnd); - } - a.recycle(); - } + private final TemplateLayout templateLayout; - /** - * @return The list view contained in the layout, as marked by {@code @android:id/list}. This - * will return {@code null} if the list doesn't exist in the layout. - */ - public ListView getListView() { - return getListViewInternal(); - } + @Nullable private ListView listView; - // Client code can assume getListView() will not be null if they know their template contains - // the list, but this mixin cannot. Any usages of getListView in this mixin needs null checks. - @Nullable - private ListView getListViewInternal() { - if (mListView == null) { - final View list = mTemplateLayout.findManagedViewById(android.R.id.list); - if (list instanceof ListView) { - mListView = (ListView) list; - } - } - return mListView; - } + private Drawable divider; + private Drawable defaultDivider; - /** - * List 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(); - } - } + private int dividerInsetStart; + private int dividerInsetEnd; - /** - * Gets the adapter of the list view in this layout. If the adapter is a HeaderViewListAdapter, - * this method will unwrap it and return the underlying adapter. - * - * @return The adapter, or {@code null} if there is no list, or if the list has no adapter. - */ - public ListAdapter getAdapter() { - final ListView listView = getListViewInternal(); - if (listView != null) { - final ListAdapter adapter = listView.getAdapter(); - if (adapter instanceof HeaderViewListAdapter) { - return ((HeaderViewListAdapter) adapter).getWrappedAdapter(); - } - return adapter; - } - return null; - } + /** @param layout The layout this mixin belongs to. */ + public ListMixin( + @NonNull TemplateLayout layout, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) { + templateLayout = layout; - /** - * Sets the adapter on the list view in this layout. - */ - public void setAdapter(ListAdapter adapter) { - final ListView listView = getListViewInternal(); - if (listView != null) { - listView.setAdapter(adapter); - } - } + final Context context = layout.getContext(); + final TypedArray a = + context.obtainStyledAttributes(attrs, R.styleable.SuwListMixin, defStyleAttr, 0); - /** - * @deprecated Use {@link #setDividerInsets(int, int)} instead. - */ - @Deprecated - public void setDividerInset(int inset) { - setDividerInsets(inset, 0); + final int entries = a.getResourceId(R.styleable.SuwListMixin_android_entries, 0); + if (entries != 0) { + final ItemGroup inflated = (ItemGroup) new ItemInflater(context).inflate(entries); + setAdapter(new ItemAdapter(inflated)); } - - /** - * 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(); + int dividerInset = a.getDimensionPixelSize(R.styleable.SuwListMixin_suwDividerInset, -1); + if (dividerInset != -1) { + setDividerInset(dividerInset); + } else { + int dividerInsetStart = + a.getDimensionPixelSize(R.styleable.SuwListMixin_suwDividerInsetStart, 0); + int dividerInsetEnd = a.getDimensionPixelSize(R.styleable.SuwListMixin_suwDividerInsetEnd, 0); + setDividerInsets(dividerInsetStart, dividerInsetEnd); } - - /** - * @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(); + a.recycle(); + } + + /** + * @return The list view contained in the layout, as marked by {@code @android:id/list}. This will + * return {@code null} if the list doesn't exist in the layout. + */ + public ListView getListView() { + return getListViewInternal(); + } + + // Client code can assume getListView() will not be null if they know their template contains + // the list, but this mixin cannot. Any usages of getListView in this mixin needs null checks. + @Nullable + private ListView getListViewInternal() { + if (listView == null) { + final View list = templateLayout.findManagedViewById(android.R.id.list); + if (list instanceof ListView) { + listView = (ListView) list; + } } - - /** - * @return The number of pixels inset on the start side of the divider. - */ - public int getDividerInsetStart() { - return mDividerInsetStart; + return listView; + } + + /** + * List 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(); } - - /** - * @return The number of pixels inset on the end side of the divider. - */ - public int getDividerInsetEnd() { - return mDividerInsetEnd; + } + + /** + * Gets the adapter of the list view in this layout. If the adapter is a HeaderViewListAdapter, + * this method will unwrap it and return the underlying adapter. + * + * @return The adapter, or {@code null} if there is no list, or if the list has no adapter. + */ + public ListAdapter getAdapter() { + final ListView listView = getListViewInternal(); + if (listView != null) { + final ListAdapter adapter = listView.getAdapter(); + if (adapter instanceof HeaderViewListAdapter) { + return ((HeaderViewListAdapter) adapter).getWrappedAdapter(); + } + return adapter; } - - private void updateDivider() { - final ListView listView = getListViewInternal(); - if (listView == null) { - return; - } - boolean shouldUpdate = true; - if (Build.VERSION.SDK_INT >= VERSION_CODES.KITKAT) { - shouldUpdate = mTemplateLayout.isLayoutDirectionResolved(); - } - if (shouldUpdate) { - if (mDefaultDivider == null) { - mDefaultDivider = listView.getDivider(); - } - mDivider = DrawableLayoutDirectionHelper.createRelativeInsetDrawable( - mDefaultDivider, - mDividerInsetStart /* start */, - 0 /* top */, - mDividerInsetEnd /* end */, - 0 /* bottom */, - mTemplateLayout); - listView.setDivider(mDivider); - } + return null; + } + + /** Sets the adapter on the list view in this layout. */ + public void setAdapter(ListAdapter adapter) { + final ListView listView = getListViewInternal(); + if (listView != null) { + listView.setAdapter(adapter); } - - /** - * @return The drawable used as the divider. - */ - public Drawable getDivider() { - return mDivider; + } + + /** @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() { + final ListView listView = getListViewInternal(); + if (listView == null) { + return; } + boolean shouldUpdate = true; + if (Build.VERSION.SDK_INT >= VERSION_CODES.KITKAT) { + shouldUpdate = templateLayout.isLayoutDirectionResolved(); + } + if (shouldUpdate) { + if (defaultDivider == null) { + defaultDivider = listView.getDivider(); + } + divider = + DrawableLayoutDirectionHelper.createRelativeInsetDrawable( + defaultDivider, + dividerInsetStart /* start */, + 0 /* top */, + dividerInsetEnd /* end */, + 0 /* bottom */, + templateLayout); + listView.setDivider(divider); + } + } + + /** @return The drawable used as the divider. */ + public Drawable getDivider() { + return divider; + } } |