Merge "Dashboard status cards UI."
This commit is contained in:
81
res/layout/dashboard_status_card.xml
Normal file
81
res/layout/dashboard_status_card.xml
Normal 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>
|
||||||
@@ -302,4 +302,8 @@
|
|||||||
<!-- Padding between the radio buttons/checkbox and text on the redaction interstitial -->
|
<!-- Padding between the radio buttons/checkbox and text on the redaction interstitial -->
|
||||||
<dimen name="redaction_padding_start">16dp</dimen>
|
<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>
|
</resources>
|
||||||
|
|||||||
@@ -7376,4 +7376,13 @@
|
|||||||
<!-- Title of developer options to set the smallest width of the screen [CHAR LIMIT=60]-->
|
<!-- Title of developer options to set the smallest width of the screen [CHAR LIMIT=60]-->
|
||||||
<string name="developer_smallest_width">Smallest width</string>
|
<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>
|
</resources>
|
||||||
|
|||||||
@@ -392,4 +392,8 @@
|
|||||||
<item name="android:textAppearance">@android:style/TextAppearance.Material.Subhead</item>
|
<item name="android:textAppearance">@android:style/TextAppearance.Material.Subhead</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="TextAppearance.StatusTileTitle" parent="TextAppearance.TileTitle">
|
||||||
|
<item name="android:textAllCaps">true</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
package com.android.settings.dashboard;
|
package com.android.settings.dashboard;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.support.annotation.LayoutRes;
|
||||||
import android.support.v7.widget.GridLayoutManager;
|
import android.support.v7.widget.GridLayoutManager;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@@ -28,6 +30,7 @@ import android.widget.TextView;
|
|||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.dashboard.conditional.Condition;
|
import com.android.settings.dashboard.conditional.Condition;
|
||||||
import com.android.settings.dashboard.conditional.ConditionAdapterUtils;
|
import com.android.settings.dashboard.conditional.ConditionAdapterUtils;
|
||||||
|
import com.android.settings.dashboard.status.StatusCategory;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -42,10 +45,14 @@ public final class DashboardStatusAdapter
|
|||||||
public static final int GRID_COLUMN_COUNT = 2;
|
public static final int GRID_COLUMN_COUNT = 2;
|
||||||
|
|
||||||
// Namespaces
|
// 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
|
// 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_CONDITION = R.layout.condition_card;
|
||||||
|
private static final int TYPE_STATUS = R.layout.dashboard_status_card;
|
||||||
|
|
||||||
// Multi namespace support.
|
// Multi namespace support.
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
@@ -56,13 +63,16 @@ public final class DashboardStatusAdapter
|
|||||||
|
|
||||||
// Layout control
|
// Layout control
|
||||||
private final SpanSizeLookup mSpanSizeLookup;
|
private final SpanSizeLookup mSpanSizeLookup;
|
||||||
|
private final ItemDecoration mItemDecoration;
|
||||||
|
|
||||||
private List<Condition> mConditions;
|
private List<Condition> mConditions;
|
||||||
private Condition mExpandedCondition = null;
|
private Condition mExpandedCondition = null;
|
||||||
|
private List<StatusCategory> mStatus;
|
||||||
|
|
||||||
public DashboardStatusAdapter(Context context) {
|
public DashboardStatusAdapter(Context context) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mSpanSizeLookup = new SpanSizeLookup();
|
mSpanSizeLookup = new SpanSizeLookup();
|
||||||
|
mItemDecoration = new ItemDecoration(context);
|
||||||
setHasStableIds(true);
|
setHasStableIds(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,6 +80,7 @@ public final class DashboardStatusAdapter
|
|||||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
return new ViewHolder(
|
return new ViewHolder(
|
||||||
LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false));
|
LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -84,6 +95,11 @@ public final class DashboardStatusAdapter
|
|||||||
onExpandClick(v);
|
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;
|
return mSpanSizeLookup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ItemDecoration getItemDecoration() {
|
||||||
|
return mItemDecoration;
|
||||||
|
}
|
||||||
|
|
||||||
public void setConditions(List<Condition> conditions) {
|
public void setConditions(List<Condition> conditions) {
|
||||||
mConditions = conditions;
|
mConditions = conditions;
|
||||||
recountItems();
|
recountItems();
|
||||||
@@ -130,7 +150,7 @@ public final class DashboardStatusAdapter
|
|||||||
return null;
|
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) {
|
if (add) {
|
||||||
mItems.add(object);
|
mItems.add(object);
|
||||||
mTypes.add(type);
|
mTypes.add(type);
|
||||||
@@ -153,9 +173,16 @@ public final class DashboardStatusAdapter
|
|||||||
|
|
||||||
private void recountItems() {
|
private void recountItems() {
|
||||||
reset();
|
reset();
|
||||||
|
countItem(null, TYPE_SPACER, true /* add */, NS_SPACER);
|
||||||
|
boolean hasCondition = false;
|
||||||
for (int i = 0; mConditions != null && i < mConditions.size(); i++) {
|
for (int i = 0; mConditions != null && i < mConditions.size(); i++) {
|
||||||
boolean shouldShow = mConditions.get(i).shouldShow();
|
boolean shouldShow = mConditions.get(i).shouldShow();
|
||||||
countItem(mConditions.get(i), TYPE_CONDITION, shouldShow, NS_CONDITION);
|
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();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
@@ -169,12 +196,16 @@ public final class DashboardStatusAdapter
|
|||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link GridLayoutManager.SpanSizeLookup} that assigns column span for different item types.
|
||||||
|
*/
|
||||||
private final class SpanSizeLookup extends GridLayoutManager.SpanSizeLookup {
|
private final class SpanSizeLookup extends GridLayoutManager.SpanSizeLookup {
|
||||||
@Override
|
@Override
|
||||||
public int getSpanSize(int position) {
|
public int getSpanSize(int position) {
|
||||||
final int viewType = getItemViewType(position);
|
final int viewType = getItemViewType(position);
|
||||||
switch (viewType) {
|
switch (viewType) {
|
||||||
case TYPE_CONDITION:
|
case TYPE_CONDITION:
|
||||||
|
case TYPE_SPACER:
|
||||||
return 2;
|
return 2;
|
||||||
default:
|
default:
|
||||||
return 1;
|
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 static class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
public final ImageView icon;
|
|
||||||
public final TextView title;
|
public final TextView title;
|
||||||
|
public final ImageView icon;
|
||||||
public final TextView summary;
|
public final TextView summary;
|
||||||
|
public final ImageView icon2;
|
||||||
|
public final TextView summary2;
|
||||||
|
|
||||||
public ViewHolder(View itemView) {
|
public ViewHolder(View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
icon = (ImageView) itemView.findViewById(android.R.id.icon);
|
|
||||||
title = (TextView) itemView.findViewById(android.R.id.title);
|
title = (TextView) itemView.findViewById(android.R.id.title);
|
||||||
|
icon = (ImageView) itemView.findViewById(android.R.id.icon);
|
||||||
summary = (TextView) itemView.findViewById(android.R.id.summary);
|
summary = (TextView) itemView.findViewById(android.R.id.summary);
|
||||||
|
icon2 = (ImageView) itemView.findViewById(android.R.id.icon2);
|
||||||
|
summary2 = (TextView) itemView.findViewById(android.R.id.text2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,6 +71,7 @@ public final class DashboardStatusFragment extends InstrumentedFragment
|
|||||||
mRecyclerView.setHasFixedSize(true);
|
mRecyclerView.setHasFixedSize(true);
|
||||||
mRecyclerView.setListener(this);
|
mRecyclerView.setListener(this);
|
||||||
mRecyclerView.setAdapter(mAdapter);
|
mRecyclerView.setAdapter(mAdapter);
|
||||||
|
mRecyclerView.addItemDecoration(mAdapter.getItemDecoration());
|
||||||
ConditionAdapterUtils.addDismiss(mRecyclerView);
|
ConditionAdapterUtils.addDismiss(mRecyclerView);
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user