From d42e233bf0e5132cc1592fe9932532474e3fb84b Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Thu, 24 Mar 2016 13:01:05 -0700 Subject: [PATCH] Dashboard status cards UI. Bug: 27907841 This adds a card view type to display status in Settings dashboard. Also added necessary pieces to layout status and condition views properly. The data for status is not wired up yet. Change-Id: I8ed624177645f389ec0bb71420f073c6dbc03ccb --- res/layout/dashboard_status_card.xml | 81 +++++++++++++++++ res/values/dimens.xml | 4 + res/values/strings.xml | 9 ++ res/values/styles.xml | 4 + .../dashboard/DashboardStatusAdapter.java | 89 ++++++++++++++++++- .../dashboard/DashboardStatusFragment.java | 1 + .../dashboard/status/StatusCategory.java | 43 +++++++++ 7 files changed, 227 insertions(+), 4 deletions(-) create mode 100644 res/layout/dashboard_status_card.xml create mode 100644 src/com/android/settings/dashboard/status/StatusCategory.java diff --git a/res/layout/dashboard_status_card.xml b/res/layout/dashboard_status_card.xml new file mode 100644 index 00000000000..babbfcaedac --- /dev/null +++ b/res/layout/dashboard_status_card.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/values/dimens.xml b/res/values/dimens.xml index cfa1009c336..8bba63b2e43 100755 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -301,4 +301,8 @@ 16dp + + 16dp + 14sp + 12sp diff --git a/res/values/strings.xml b/res/values/strings.xml index f431fa695c9..2cb2a9069a6 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -7376,4 +7376,13 @@ Smallest width + + Connection + + Storage + + Battery + + Security + diff --git a/res/values/styles.xml b/res/values/styles.xml index 45d2c1178a6..e711396541a 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -392,4 +392,8 @@ @android:style/TextAppearance.Material.Subhead + + diff --git a/src/com/android/settings/dashboard/DashboardStatusAdapter.java b/src/com/android/settings/dashboard/DashboardStatusAdapter.java index 4c68cb79245..a5829599b14 100644 --- a/src/com/android/settings/dashboard/DashboardStatusAdapter.java +++ b/src/com/android/settings/dashboard/DashboardStatusAdapter.java @@ -17,6 +17,8 @@ package com.android.settings.dashboard; import android.content.Context; +import android.graphics.Rect; +import android.support.annotation.LayoutRes; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; @@ -28,6 +30,7 @@ import android.widget.TextView; import com.android.settings.R; import com.android.settings.dashboard.conditional.Condition; import com.android.settings.dashboard.conditional.ConditionAdapterUtils; +import com.android.settings.dashboard.status.StatusCategory; import java.util.ArrayList; import java.util.List; @@ -42,10 +45,14 @@ public final class DashboardStatusAdapter public static final int GRID_COLUMN_COUNT = 2; // Namespaces - private static final int NS_CONDITION = 0; + private static final int NS_SPACER = 0; + private static final int NS_CONDITION = 1000; + private static final int NS_STATUS = 2000; // Item types + private static final int TYPE_SPACER = R.layout.dashboard_spacer; private static final int TYPE_CONDITION = R.layout.condition_card; + private static final int TYPE_STATUS = R.layout.dashboard_status_card; // Multi namespace support. private final Context mContext; @@ -56,13 +63,16 @@ public final class DashboardStatusAdapter // Layout control private final SpanSizeLookup mSpanSizeLookup; + private final ItemDecoration mItemDecoration; private List mConditions; private Condition mExpandedCondition = null; + private List mStatus; public DashboardStatusAdapter(Context context) { mContext = context; mSpanSizeLookup = new SpanSizeLookup(); + mItemDecoration = new ItemDecoration(context); setHasStableIds(true); } @@ -70,6 +80,7 @@ public final class DashboardStatusAdapter public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return new ViewHolder( LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false)); + } @Override @@ -84,6 +95,11 @@ public final class DashboardStatusAdapter onExpandClick(v); } }); + break; + case TYPE_STATUS: + final StatusCategory status = (StatusCategory) mItems.get(position); + status.bindToViewHolder(holder); + break; } } @@ -116,6 +132,10 @@ public final class DashboardStatusAdapter return mSpanSizeLookup; } + public ItemDecoration getItemDecoration() { + return mItemDecoration; + } + public void setConditions(List conditions) { mConditions = conditions; recountItems(); @@ -130,7 +150,7 @@ public final class DashboardStatusAdapter return null; } - private void countItem(Object object, int type, boolean add, int nameSpace) { + private void countItem(Object object, @LayoutRes int type, boolean add, int nameSpace) { if (add) { mItems.add(object); mTypes.add(type); @@ -153,9 +173,16 @@ public final class DashboardStatusAdapter private void recountItems() { reset(); + countItem(null, TYPE_SPACER, true /* add */, NS_SPACER); + boolean hasCondition = false; for (int i = 0; mConditions != null && i < mConditions.size(); i++) { boolean shouldShow = mConditions.get(i).shouldShow(); countItem(mConditions.get(i), TYPE_CONDITION, shouldShow, NS_CONDITION); + hasCondition |= shouldShow; + } + countItem(null, TYPE_SPACER, hasCondition, NS_SPACER); + for (int i = 0; mStatus != null && i < mStatus.size(); i++) { + countItem(mStatus.get(i), TYPE_STATUS, true, NS_STATUS); } notifyDataSetChanged(); } @@ -169,12 +196,16 @@ public final class DashboardStatusAdapter notifyDataSetChanged(); } + /** + * {@link GridLayoutManager.SpanSizeLookup} that assigns column span for different item types. + */ private final class SpanSizeLookup extends GridLayoutManager.SpanSizeLookup { @Override public int getSpanSize(int position) { final int viewType = getItemViewType(position); switch (viewType) { case TYPE_CONDITION: + case TYPE_SPACER: return 2; default: return 1; @@ -182,16 +213,66 @@ public final class DashboardStatusAdapter } } + /** + * {@link ItemDecoration} that adds padding around different types of views during layout. + */ + private static final class ItemDecoration extends RecyclerView.ItemDecoration { + + private final int mItemSpacing; + + public ItemDecoration(Context context) { + mItemSpacing = context.getResources() + .getDimensionPixelSize(R.dimen.dashboard_status_item_padding); + } + + @Override + public void getItemOffsets(Rect outRect, View view, RecyclerView parent, + RecyclerView.State state) { + GridLayoutManager.LayoutParams layoutParams + = (GridLayoutManager.LayoutParams) view.getLayoutParams(); + final int position = layoutParams.getViewLayoutPosition(); + if (position == RecyclerView.NO_POSITION) { + super.getItemOffsets(outRect, view, parent, state); + return; + } + final int viewType = parent.getChildViewHolder(view).getItemViewType(); + switch (viewType) { + case TYPE_SPACER: + // No padding for spacer. + super.getItemOffsets(outRect, view, parent, state); + return; + case TYPE_CONDITION: + // Adds padding horizontally. + outRect.left = mItemSpacing; + outRect.right = mItemSpacing; + return; + default: + // Adds padding around status card. + final int spanIndex = layoutParams.getSpanIndex(); + outRect.left = spanIndex == 0 ? mItemSpacing : mItemSpacing / 2; + outRect.right = spanIndex + layoutParams.getSpanSize() == GRID_COLUMN_COUNT + ? mItemSpacing : mItemSpacing / 2; + outRect.top = mItemSpacing; + outRect.bottom = 0; + break; + } + } + } + public static class ViewHolder extends RecyclerView.ViewHolder { - public final ImageView icon; public final TextView title; + public final ImageView icon; public final TextView summary; + public final ImageView icon2; + public final TextView summary2; public ViewHolder(View itemView) { super(itemView); - icon = (ImageView) itemView.findViewById(android.R.id.icon); title = (TextView) itemView.findViewById(android.R.id.title); + icon = (ImageView) itemView.findViewById(android.R.id.icon); summary = (TextView) itemView.findViewById(android.R.id.summary); + icon2 = (ImageView) itemView.findViewById(android.R.id.icon2); + summary2 = (TextView) itemView.findViewById(android.R.id.text2); } } } \ No newline at end of file diff --git a/src/com/android/settings/dashboard/DashboardStatusFragment.java b/src/com/android/settings/dashboard/DashboardStatusFragment.java index 38f06293166..27b02969cf8 100644 --- a/src/com/android/settings/dashboard/DashboardStatusFragment.java +++ b/src/com/android/settings/dashboard/DashboardStatusFragment.java @@ -71,6 +71,7 @@ public final class DashboardStatusFragment extends InstrumentedFragment mRecyclerView.setHasFixedSize(true); mRecyclerView.setListener(this); mRecyclerView.setAdapter(mAdapter); + mRecyclerView.addItemDecoration(mAdapter.getItemDecoration()); ConditionAdapterUtils.addDismiss(mRecyclerView); return content; } diff --git a/src/com/android/settings/dashboard/status/StatusCategory.java b/src/com/android/settings/dashboard/status/StatusCategory.java new file mode 100644 index 00000000000..5314c774695 --- /dev/null +++ b/src/com/android/settings/dashboard/status/StatusCategory.java @@ -0,0 +1,43 @@ +package com.android.settings.dashboard.status; + +import android.annotation.StringRes; +import android.content.Context; +import android.graphics.drawable.Icon; + +import com.android.settings.dashboard.DashboardStatusAdapter; + +/** + * Data item for status category in dashboard. + */ +public final class StatusCategory { + + private final String mTitle; + + public StatusCategory(Context context, @StringRes int titleResId) { + mTitle = context.getString(titleResId); + } + + public void bindToViewHolder(DashboardStatusAdapter.ViewHolder viewHolder) { + viewHolder.title.setText(mTitle); + viewHolder.icon.setImageIcon(getIcon()); + viewHolder.summary.setText(getSummary()); + viewHolder.icon2.setImageIcon(getSecondaryIcon()); + viewHolder.summary2.setText(getSecondarySummary()); + } + + private Icon getIcon() { + return null; + } + + private String getSummary() { + return null; + } + + private Icon getSecondaryIcon() { + return null; + } + + private String getSecondarySummary() { + return null; + } +}