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
This commit is contained in:
Fan Zhang
2016-03-24 13:01:05 -07:00
parent 87da294262
commit d42e233bf0
7 changed files with 227 additions and 4 deletions

View File

@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2016 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@android:id/title"
android:textAllCaps="true"
android:textAppearance="@style/TextAppearance.StatusTileTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/material_grey_300"
android:padding="@dimen/dashboard_status_item_padding"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/dashboard_status_item_padding"
android:orientation="horizontal"
android:gravity="center_vertical">
<ImageView
android:id="@android:id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="@dimen/dashboard_status_item_padding"/>
<TextView
android:id="@android:id/summary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.Small"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/dashboard_status_item_padding"
android:orientation="horizontal"
android:gravity="center_vertical">
<ImageView
android:id="@android:id/icon2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="@dimen/dashboard_status_item_padding"/>
<TextView
android:id="@android:id/text2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.Small"/>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>

View File

@@ -301,4 +301,8 @@
<!-- Padding between the radio buttons/checkbox and text on the redaction interstitial -->
<dimen name="redaction_padding_start">16dp</dimen>
<!-- Dashboard status cards -->
<dimen name="dashboard_status_item_padding">16dp</dimen>
<dimen name="dashboard_status_title_size">14sp</dimen>
<dimen name="dashboard_status_summary_size">12sp</dimen>
</resources>

View File

@@ -7376,4 +7376,13 @@
<!-- Title of developer options to set the smallest width of the screen [CHAR LIMIT=60]-->
<string name="developer_smallest_width">Smallest width</string>
<!-- Title for connection status, containing information about connected wifi, mobile data usage etc [CHAR LIMIT=20] -->
<string name="status_title_connection">Connection</string>
<!-- Title for storage status, containing information about storage left, auto backup status etc [CHAR LIMIT=20] -->
<string name="status_title_storage">Storage</string>
<!-- Title for battery status, containing information about battery left, apps that uses most battery etc [CHAR LIMIT=20] -->
<string name="status_title_battery">Battery</string>
<!-- Title for security status, containing information about how secure the current system is [CHAR LIMIT=20] -->
<string name="status_title_security">Security</string>
</resources>

View File

@@ -392,4 +392,8 @@
<item name="android:textAppearance">@android:style/TextAppearance.Material.Subhead</item>
</style>
<style name="TextAppearance.StatusTileTitle" parent="TextAppearance.TileTitle">
<item name="android:textAllCaps">true</item>
</style>
</resources>

View File

@@ -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<Condition> mConditions;
private Condition mExpandedCondition = null;
private List<StatusCategory> 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<Condition> 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);
}
}
}

View File

@@ -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;
}

View File

@@ -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;
}
}