Support suggestion UI card with a button.
Bug: 65065268 Test: robotests Change-Id: I24c8947e9b23a80de38b8cbd57404736a5d1660a
This commit is contained in:
@@ -33,26 +33,27 @@
|
||||
android:layout_width="@dimen/dashboard_tile_image_size"
|
||||
android:layout_height="@dimen/dashboard_tile_image_size"
|
||||
android:layout_marginStart="14dp"
|
||||
android:layout_marginEnd="24dp"/>
|
||||
android:layout_marginEnd="24dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView android:id="@android:id/title"
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/TextAppearance.TileTitle"
|
||||
android:ellipsize="marquee"
|
||||
android:fadingEdge="horizontal"/>
|
||||
android:fadingEdge="horizontal" />
|
||||
|
||||
<TextView android:id="@android:id/summary"
|
||||
<TextView
|
||||
android:id="@android:id/summary"
|
||||
android:textAppearance="@style/TextAppearance.SuggestionSummary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/TextAppearance.Small"
|
||||
android:textColor="?android:attr/textColorSecondary"/>
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
72
res/layout/suggestion_tile_with_button.xml
Normal file
72
res/layout/suggestion_tile_with_button.xml
Normal file
@@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2017 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.
|
||||
-->
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/white"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:paddingBottom="20dp"
|
||||
android:paddingTop="16dp"
|
||||
android:orientation="horizontal"
|
||||
android:minHeight="@dimen/dashboard_tile_minimum_height">
|
||||
|
||||
<ImageView
|
||||
android:id="@android:id/icon"
|
||||
android:layout_width="@dimen/dashboard_tile_image_size"
|
||||
android:layout_height="@dimen/dashboard_tile_image_size"
|
||||
android:contentDescription="@null" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start"
|
||||
android:layout_marginStart="18dp"
|
||||
android:layout_marginTop="2dp"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
style="@style/TextAppearance.SuggestionTitle"
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_marginEnd="50dp"
|
||||
android:textAppearance="@style/TextAppearance.SuggestionSummary" />
|
||||
|
||||
<Button
|
||||
android:id="@android:id/primary"
|
||||
style="@style/SuwGlifButton.Primary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="@string/suggestion_button_text" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
@@ -7321,6 +7321,8 @@
|
||||
settings button -->
|
||||
<string name="notification_app_settings_button">Notification settings</string>
|
||||
|
||||
<!-- Generic label for suggestion card's ok button [CHAR LIMIT=20] -->
|
||||
<string name="suggestion_button_text">Ok</string>
|
||||
|
||||
<!-- [CHAR LIMIT=35] Feedback on the device -->
|
||||
<string name="device_feedback">Send feedback about this device</string>
|
||||
|
@@ -318,7 +318,10 @@
|
||||
<style name="TextAppearance.SuggestionTitle"
|
||||
parent="@android:style/TextAppearance.Material.Subhead">
|
||||
<item name="android:fontFamily">sans-serif-medium</item>
|
||||
<item name="android:textSize">14sp</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.SuggestionSummary" parent="TextAppearance.Small">
|
||||
<item name="android:textColor">?android:attr/textColorSecondary</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.FingerprintErrorText"
|
||||
|
@@ -44,7 +44,7 @@ public class SuggestionAdapter extends RecyclerView.Adapter<DashboardItemHolder>
|
||||
private final Context mContext;
|
||||
private final MetricsFeatureProvider mMetricsFeatureProvider;
|
||||
private final SuggestionFeatureProvider mSuggestionFeatureProvider;
|
||||
@Deprecated // in favor of mNewSuggestions
|
||||
@Deprecated // in favor of mSuggestionsV2
|
||||
private final List<Tile> mSuggestions;
|
||||
private final List<Suggestion> mSuggestionsV2;
|
||||
private final IconCache mCache;
|
||||
@@ -88,23 +88,15 @@ public class SuggestionAdapter extends RecyclerView.Adapter<DashboardItemHolder>
|
||||
mContext, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, id);
|
||||
mSuggestionsShownLogged.add(id);
|
||||
}
|
||||
// TODO: Add remote view field in Suggestion, and enable this.
|
||||
// if (suggestion.remoteViews != null) {
|
||||
// final ViewGroup itemView = (ViewGroup) holder.itemView;
|
||||
// itemView.removeAllViews();
|
||||
// itemView.addView(suggestion.remoteViews.apply(itemView.getContext(),
|
||||
// itemView));
|
||||
// } else
|
||||
{
|
||||
holder.icon.setImageDrawable(mCache.getIcon(suggestion.getIcon()));
|
||||
holder.title.setText(suggestion.getTitle());
|
||||
final CharSequence summary = suggestion.getSummary();
|
||||
if (!TextUtils.isEmpty(summary)) {
|
||||
holder.summary.setText(summary);
|
||||
holder.summary.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.summary.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
holder.icon.setImageDrawable(mCache.getIcon(suggestion.getIcon()));
|
||||
holder.title.setText(suggestion.getTitle());
|
||||
final CharSequence summary = suggestion.getSummary();
|
||||
if (!TextUtils.isEmpty(summary)) {
|
||||
holder.summary.setText(summary);
|
||||
holder.summary.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.summary.setVisibility(View.GONE);
|
||||
}
|
||||
final View divider = holder.itemView.findViewById(R.id.divider);
|
||||
if (divider != null) {
|
||||
@@ -116,8 +108,6 @@ public class SuggestionAdapter extends RecyclerView.Adapter<DashboardItemHolder>
|
||||
final View primaryAction = holder.itemView.findViewById(android.R.id.primary);
|
||||
if (primaryAction != null) {
|
||||
clickHandler = primaryAction;
|
||||
// set the item view to disabled to remove any touch effects
|
||||
holder.itemView.setEnabled(false);
|
||||
}
|
||||
clickHandler.setOnClickListener(v -> {
|
||||
mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_SETTINGS_SUGGESTION, id);
|
||||
@@ -198,13 +188,12 @@ public class SuggestionAdapter extends RecyclerView.Adapter<DashboardItemHolder>
|
||||
? R.layout.suggestion_tile_remote_container
|
||||
: R.layout.suggestion_tile;
|
||||
} else {
|
||||
|
||||
return R.layout.suggestion_tile;
|
||||
// TODO: Add remote view field in Suggestion, and enable this.
|
||||
// Suggestion suggestion = getSuggestionsV2(position);
|
||||
// return suggestion.remoteViews != null
|
||||
// ? R.layout.suggestion_tile_remote_container
|
||||
// : R.layout.suggestion_tile;
|
||||
final Suggestion suggestion = getSuggestionsV2(position);
|
||||
if ((suggestion.getFlags() & Suggestion.FLAG_HAS_BUTTON) != 0) {
|
||||
return R.layout.suggestion_tile_with_button;
|
||||
} else {
|
||||
return R.layout.suggestion_tile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -89,7 +89,7 @@ public class SuggestionDismissController extends ItemTouchHelper.SimpleCallback
|
||||
public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
|
||||
final int layoutId = viewHolder.getItemViewType();
|
||||
if (layoutId == R.layout.suggestion_tile
|
||||
|| layoutId == R.layout.suggestion_tile_remote_container) {
|
||||
|| layoutId == R.layout.suggestion_tile_with_button) {
|
||||
// Only return swipe direction for suggestion tiles. All other types are not swipeable.
|
||||
return super.getSwipeDirs(recyclerView, viewHolder);
|
||||
}
|
||||
|
@@ -18,15 +18,17 @@ package android.service.settings.suggestions;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.os.Parcel;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
public class Suggestion {
|
||||
|
||||
public static final int FLAG_HAS_BUTTON = 1 << 0;
|
||||
|
||||
private final String mId;
|
||||
private final CharSequence mTitle;
|
||||
private final CharSequence mSummary;
|
||||
private final Icon mIcon;
|
||||
private final int mFlags;
|
||||
private final PendingIntent mPendingIntent;
|
||||
|
||||
/**
|
||||
@@ -57,6 +59,10 @@ public class Suggestion {
|
||||
return mIcon;
|
||||
}
|
||||
|
||||
public int getFlags() {
|
||||
return mFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Intent to launch when the suggestion is activated.
|
||||
*/
|
||||
@@ -70,13 +76,16 @@ public class Suggestion {
|
||||
mIcon = builder.mIcon;
|
||||
mPendingIntent = builder.mPendingIntent;
|
||||
mId = builder.mId;
|
||||
mFlags = builder.mFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder class for {@link Suggestion}.
|
||||
*/
|
||||
public static class Builder {
|
||||
|
||||
private final String mId;
|
||||
private int mFlags;
|
||||
private CharSequence mTitle;
|
||||
private CharSequence mSummary;
|
||||
private Icon mIcon;
|
||||
@@ -114,6 +123,11 @@ public class Suggestion {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setFlags(int flags) {
|
||||
mFlags = flags;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets suggestion intent
|
||||
*/
|
||||
|
@@ -143,6 +143,21 @@ public class SuggestionAdapterTest {
|
||||
.isEqualTo(R.layout.suggestion_tile);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getItemType_hasButton_shouldReturnSuggestionWithButton() {
|
||||
final List<Suggestion> suggestions = new ArrayList<>();
|
||||
suggestions.add(new Suggestion.Builder("id")
|
||||
.setFlags(Suggestion.FLAG_HAS_BUTTON)
|
||||
.setTitle("123")
|
||||
.setSummary("456")
|
||||
.build());
|
||||
mSuggestionAdapter = new SuggestionAdapter(mContext, null /* suggestions */,
|
||||
suggestions, new ArrayList<>());
|
||||
|
||||
assertThat(mSuggestionAdapter.getItemViewType(0))
|
||||
.isEqualTo(R.layout.suggestion_tile_with_button);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_shouldSetListener() {
|
||||
final View view = spy(LayoutInflater.from(mContext).inflate(
|
||||
|
@@ -92,7 +92,7 @@ public class SuggestionDismissControllerTest {
|
||||
@Test
|
||||
public void getSwipeDirs_isSuggestionTileCard_shouldReturnDirection() {
|
||||
final RecyclerView.ViewHolder vh = mock(RecyclerView.ViewHolder.class);
|
||||
when(vh.getItemViewType()).thenReturn(R.layout.suggestion_tile_remote_container);
|
||||
when(vh.getItemViewType()).thenReturn(R.layout.suggestion_tile_with_button);
|
||||
|
||||
assertThat(mController.getSwipeDirs(mRecyclerView, vh))
|
||||
.isEqualTo(ItemTouchHelper.START | ItemTouchHelper.END);
|
||||
|
Reference in New Issue
Block a user