Implement slice half card
To display slice in half width form needs to bind slice, extract the title and the icon from slice, and finally put the title and the icon into half card layout. Bug: 119655434 Test: visual, robotests Change-Id: Ib390f9a45f0ee609eb9e3499bff74136c7616ac3
This commit is contained in:
@@ -16,13 +16,24 @@
|
||||
|
||||
package com.android.settings.homepage.contextualcards.slices;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.SliceMetadata;
|
||||
import androidx.slice.core.SliceAction;
|
||||
import androidx.slice.widget.EventInfo;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||
import com.android.settings.homepage.contextualcards.ContextualCardFeatureProvider;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
|
||||
/**
|
||||
* Card renderer helper for {@link ContextualCard} built as slice half card.
|
||||
@@ -37,10 +48,38 @@ class SliceHalfCardRendererHelper {
|
||||
}
|
||||
|
||||
RecyclerView.ViewHolder createViewHolder(View view) {
|
||||
return null;
|
||||
return new HalfCardViewHolder(view);
|
||||
}
|
||||
|
||||
void bindView(RecyclerView.ViewHolder holder, ContextualCard card, Slice slice) {
|
||||
final HalfCardViewHolder view = (HalfCardViewHolder) holder;
|
||||
final SliceMetadata sliceMetadata = SliceMetadata.from(mContext, slice);
|
||||
final SliceAction primaryAction = sliceMetadata.getPrimaryAction();
|
||||
view.icon.setImageDrawable(primaryAction.getIcon().loadDrawable(mContext));
|
||||
view.title.setText(primaryAction.getTitle());
|
||||
view.content.setOnClickListener(v -> {
|
||||
try {
|
||||
primaryAction.getAction().send();
|
||||
} catch (PendingIntent.CanceledException e) {
|
||||
Log.w(TAG, "Failed to start intent " + primaryAction.getTitle());
|
||||
}
|
||||
final ContextualCardFeatureProvider contextualCardFeatureProvider =
|
||||
FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider(mContext);
|
||||
contextualCardFeatureProvider.logContextualCardClick(card, 0 /* row */,
|
||||
EventInfo.ACTION_TYPE_CONTENT);
|
||||
});
|
||||
}
|
||||
|
||||
static class HalfCardViewHolder extends RecyclerView.ViewHolder {
|
||||
public final LinearLayout content;
|
||||
public final ImageView icon;
|
||||
public final TextView title;
|
||||
|
||||
public HalfCardViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
content = itemView.findViewById(R.id.content);
|
||||
icon = itemView.findViewById(android.R.id.icon);
|
||||
title = itemView.findViewById(android.R.id.title);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.
|
||||
*/
|
||||
|
||||
package com.android.settings.homepage.contextualcards.slices;
|
||||
|
||||
import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.SliceProvider;
|
||||
import androidx.slice.builders.ListBuilder;
|
||||
import androidx.slice.builders.SliceAction;
|
||||
import androidx.slice.widget.SliceLiveData;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||
import com.android.settings.homepage.contextualcards.slices.SliceHalfCardRendererHelper.HalfCardViewHolder;
|
||||
import com.android.settings.intelligence.ContextualCardProto;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class SliceHalfCardRendererHelperTest {
|
||||
|
||||
private static final Uri TEST_SLICE_URI = Uri.parse("content://test/test");
|
||||
|
||||
private Activity mActivity;
|
||||
private SliceHalfCardRendererHelper mHelper;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
// Set-up specs for SliceMetadata.
|
||||
SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
|
||||
mActivity = Robolectric.buildActivity(Activity.class).create().get();
|
||||
mActivity.setTheme(R.style.Theme_Settings_Home);
|
||||
mHelper = new SliceHalfCardRendererHelper(mActivity);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createViewHolder_shouldAlwaysReturnCustomViewHolder() {
|
||||
final RecyclerView.ViewHolder viewHolder = getHalfCardViewHolder();
|
||||
|
||||
assertThat(viewHolder).isInstanceOf(HalfCardViewHolder.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindView_shouldSetTitle() {
|
||||
final RecyclerView.ViewHolder viewHolder = getHalfCardViewHolder();
|
||||
|
||||
mHelper.bindView(viewHolder, buildContextualCard(), buildSlice());
|
||||
|
||||
assertThat(((HalfCardViewHolder) viewHolder).title.getText()).isEqualTo("test_title");
|
||||
}
|
||||
|
||||
private RecyclerView.ViewHolder getHalfCardViewHolder() {
|
||||
final RecyclerView recyclerView = new RecyclerView(mActivity);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
|
||||
final View view = LayoutInflater.from(mActivity).inflate(VIEW_TYPE_HALF_WIDTH, recyclerView,
|
||||
false);
|
||||
|
||||
return mHelper.createViewHolder(view);
|
||||
}
|
||||
|
||||
private ContextualCard buildContextualCard() {
|
||||
return new ContextualCard.Builder()
|
||||
.setName("test_name")
|
||||
.setCategory(ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE)
|
||||
.setCardType(ContextualCard.CardType.SLICE)
|
||||
.setSliceUri(TEST_SLICE_URI)
|
||||
.setIsHalfWidth(false /* isHalfWidth */)
|
||||
.build();
|
||||
}
|
||||
|
||||
private Slice buildSlice() {
|
||||
final String title = "test_title";
|
||||
final IconCompat icon = IconCompat.createWithResource(mActivity, R.drawable.empty_icon);
|
||||
final PendingIntent pendingIntent = PendingIntent.getActivity(
|
||||
mActivity,
|
||||
title.hashCode() /* requestCode */,
|
||||
new Intent("test action"),
|
||||
0 /* flags */);
|
||||
final SliceAction action
|
||||
= SliceAction.createDeeplink(pendingIntent, icon, ListBuilder.SMALL_IMAGE, title);
|
||||
return new ListBuilder(mActivity, TEST_SLICE_URI, ListBuilder.INFINITY)
|
||||
.addRow(new ListBuilder.RowBuilder()
|
||||
.addEndItem(icon, ListBuilder.ICON_IMAGE)
|
||||
.setTitle(title)
|
||||
.setPrimaryAction(action))
|
||||
.build();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user