Refactor slice renderer to handle different card width
- Refactor SliceContextualCardRenderer to support for displaying slice in half/full width card. - Add two helper classes to separately deal with different card width. Only the skeleton of the half card helper is put in this CL, the implementation hasn't been filled in yet. Will implement the detail in next CL. Bug: 119655434 Test: visual, robotests Change-Id: Iacdc90c23bf41cfa7ccae3c0c70a3b663e89307d
This commit is contained in:
@@ -26,7 +26,6 @@ import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ViewFlipper;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.lifecycle.LifecycleObserver;
|
||||
@@ -35,40 +34,40 @@ import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.OnLifecycleEvent;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.SliceItem;
|
||||
import androidx.slice.widget.EventInfo;
|
||||
import androidx.slice.widget.SliceLiveData;
|
||||
import androidx.slice.widget.SliceView;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.homepage.contextualcards.CardContentProvider;
|
||||
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||
import com.android.settings.homepage.contextualcards.ContextualCardFeatureProvider;
|
||||
import com.android.settings.homepage.contextualcards.ContextualCardRenderer;
|
||||
import com.android.settings.homepage.contextualcards.ControllerRendererPool;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Card renderer for {@link ContextualCard} built as slices.
|
||||
* Card renderer for {@link ContextualCard} built as slice full card or slice half card.
|
||||
*/
|
||||
public class SliceContextualCardRenderer implements ContextualCardRenderer,
|
||||
SliceView.OnSliceActionListener, LifecycleObserver {
|
||||
public static final int VIEW_TYPE = R.layout.homepage_slice_tile;
|
||||
public class SliceContextualCardRenderer implements ContextualCardRenderer, LifecycleObserver {
|
||||
public static final int VIEW_TYPE_FULL_WIDTH = R.layout.homepage_slice_tile;
|
||||
public static final int VIEW_TYPE_HALF_WIDTH = R.layout.homepage_slice_half_tile;
|
||||
|
||||
private static final String TAG = "SliceCardRenderer";
|
||||
|
||||
@VisibleForTesting
|
||||
final Map<Uri, LiveData<Slice>> mSliceLiveDataMap;
|
||||
@VisibleForTesting
|
||||
final Set<SliceViewHolder> mFlippedCardSet;
|
||||
final Set<RecyclerView.ViewHolder> mFlippedCardSet;
|
||||
|
||||
private final Context mContext;
|
||||
private final LifecycleOwner mLifecycleOwner;
|
||||
private final ControllerRendererPool mControllerRendererPool;
|
||||
private final Set<ContextualCard> mCardSet;
|
||||
private final SliceFullCardRendererHelper mFullCardHelper;
|
||||
private final SliceHalfCardRendererHelper mHalfCardHelper;
|
||||
|
||||
//TODO(b/121303357): Remove isHalfWidth field from SliceContextualCardRenderer class.
|
||||
private boolean mIsHalfWidth;
|
||||
|
||||
public SliceContextualCardRenderer(Context context, LifecycleOwner lifecycleOwner,
|
||||
ControllerRendererPool controllerRendererPool) {
|
||||
@@ -79,21 +78,26 @@ public class SliceContextualCardRenderer implements ContextualCardRenderer,
|
||||
mCardSet = new ArraySet<>();
|
||||
mFlippedCardSet = new ArraySet<>();
|
||||
mLifecycleOwner.getLifecycle().addObserver(this);
|
||||
mFullCardHelper = new SliceFullCardRendererHelper(context);
|
||||
mHalfCardHelper = new SliceHalfCardRendererHelper(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewType(boolean isHalfWidth) {
|
||||
return VIEW_TYPE;
|
||||
mIsHalfWidth = isHalfWidth;
|
||||
return isHalfWidth? VIEW_TYPE_HALF_WIDTH : VIEW_TYPE_FULL_WIDTH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecyclerView.ViewHolder createViewHolder(View view) {
|
||||
return new SliceViewHolder(view);
|
||||
if (mIsHalfWidth) {
|
||||
return mHalfCardHelper.createViewHolder(view);
|
||||
}
|
||||
return mFullCardHelper.createViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(RecyclerView.ViewHolder holder, ContextualCard card) {
|
||||
final SliceViewHolder cardHolder = (SliceViewHolder) holder;
|
||||
final Uri uri = card.getSliceUri();
|
||||
//TODO(b/120629936): Take this out once blank card issue is fixed.
|
||||
Log.d(TAG, "bindView - uri = " + uri);
|
||||
@@ -103,10 +107,6 @@ public class SliceContextualCardRenderer implements ContextualCardRenderer,
|
||||
return;
|
||||
}
|
||||
|
||||
cardHolder.sliceView.setScrollable(false);
|
||||
cardHolder.sliceView.setTag(uri);
|
||||
//TODO(b/114009676): We will soon have a field to decide what slice mode we should set.
|
||||
cardHolder.sliceView.setMode(SliceView.MODE_LARGE);
|
||||
LiveData<Slice> sliceLiveData = mSliceLiveDataMap.get(uri);
|
||||
|
||||
if (sliceLiveData == null) {
|
||||
@@ -125,82 +125,58 @@ public class SliceContextualCardRenderer implements ContextualCardRenderer,
|
||||
//TODO(b/120629936): Take this out once blank card issue is fixed.
|
||||
Log.d(TAG, "Slice callback - uri = " + slice.getUri());
|
||||
}
|
||||
cardHolder.sliceView.setSlice(slice);
|
||||
if (holder.getItemViewType() == VIEW_TYPE_HALF_WIDTH) {
|
||||
mHalfCardHelper.bindView(holder, card, slice);
|
||||
} else {
|
||||
mFullCardHelper.bindView(holder, card, slice, mCardSet);
|
||||
}
|
||||
});
|
||||
|
||||
// Set this listener so we can log the interaction users make on the slice
|
||||
cardHolder.sliceView.setOnSliceActionListener(this);
|
||||
|
||||
// Customize slice view for Settings
|
||||
cardHolder.sliceView.showTitleItems(true);
|
||||
if (card.isLargeCard()) {
|
||||
cardHolder.sliceView.showHeaderDivider(true);
|
||||
cardHolder.sliceView.showActionDividers(true);
|
||||
if (holder.getItemViewType() == VIEW_TYPE_HALF_WIDTH) {
|
||||
initDismissalActions(holder, card, R.id.content);
|
||||
} else {
|
||||
initDismissalActions(holder, card, R.id.slice_view);
|
||||
}
|
||||
|
||||
initDismissalActions(cardHolder, card);
|
||||
}
|
||||
|
||||
private void initDismissalActions(SliceViewHolder cardHolder, ContextualCard card) {
|
||||
cardHolder.sliceView.setOnLongClickListener(v -> {
|
||||
cardHolder.viewFlipper.showNext();
|
||||
mFlippedCardSet.add(cardHolder);
|
||||
private void initDismissalActions(RecyclerView.ViewHolder holder, ContextualCard card,
|
||||
int initialViewId) {
|
||||
// initialView is the first view in the ViewFlipper.
|
||||
final View initialView = holder.itemView.findViewById(initialViewId);
|
||||
initialView.setOnLongClickListener(v -> {
|
||||
flipCardToDismissalView(holder);
|
||||
mFlippedCardSet.add(holder);
|
||||
return true;
|
||||
});
|
||||
|
||||
final Button btnKeep = cardHolder.itemView.findViewById(R.id.keep);
|
||||
final Button btnKeep = holder.itemView.findViewById(R.id.keep);
|
||||
btnKeep.setOnClickListener(v -> {
|
||||
cardHolder.resetCard();
|
||||
mFlippedCardSet.remove(cardHolder);
|
||||
mFlippedCardSet.remove(holder);
|
||||
resetCardView(holder);
|
||||
});
|
||||
|
||||
final Button btnRemove = cardHolder.itemView.findViewById(R.id.remove);
|
||||
final Button btnRemove = holder.itemView.findViewById(R.id.remove);
|
||||
btnRemove.setOnClickListener(v -> {
|
||||
mControllerRendererPool.getController(mContext, card.getCardType()).onDismissed(card);
|
||||
cardHolder.resetCard();
|
||||
mFlippedCardSet.remove(cardHolder);
|
||||
mFlippedCardSet.remove(holder);
|
||||
resetCardView(holder);
|
||||
mSliceLiveDataMap.get(card.getSliceUri()).removeObservers(mLifecycleOwner);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSliceAction(@NonNull EventInfo eventInfo, @NonNull SliceItem sliceItem) {
|
||||
//TODO(b/79698338): Log user interaction
|
||||
|
||||
// sliceItem.getSlice().getUri() is like
|
||||
// content://android.settings.slices/action/wifi/_gen/0/_gen/0
|
||||
// contextualCard.getSliceUri() is prefix of sliceItem.getSlice().getUri()
|
||||
for (ContextualCard card : mCardSet) {
|
||||
if (sliceItem.getSlice().getUri().toString().startsWith(
|
||||
card.getSliceUri().toString())) {
|
||||
ContextualCardFeatureProvider contexualCardFeatureProvider =
|
||||
FeatureFactory.getFactory(mContext)
|
||||
.getContextualCardFeatureProvider(mContext);
|
||||
contexualCardFeatureProvider.logContextualCardClick(card,
|
||||
eventInfo.rowIndex, eventInfo.actionType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
|
||||
public void onStop() {
|
||||
mFlippedCardSet.stream().forEach(holder -> holder.resetCard());
|
||||
mFlippedCardSet.stream().forEach(holder -> resetCardView(holder));
|
||||
mFlippedCardSet.clear();
|
||||
}
|
||||
|
||||
public static class SliceViewHolder extends RecyclerView.ViewHolder {
|
||||
public final SliceView sliceView;
|
||||
public final ViewFlipper viewFlipper;
|
||||
private void resetCardView(RecyclerView.ViewHolder holder) {
|
||||
final ViewFlipper viewFlipper = holder.itemView.findViewById(R.id.view_flipper);
|
||||
viewFlipper.setDisplayedChild(0 /* whichChild */);
|
||||
}
|
||||
|
||||
public SliceViewHolder(View view) {
|
||||
super(view);
|
||||
sliceView = view.findViewById(R.id.slice_view);
|
||||
viewFlipper = view.findViewById(R.id.view_flipper);
|
||||
}
|
||||
|
||||
public void resetCard() {
|
||||
viewFlipper.setDisplayedChild(0);
|
||||
}
|
||||
private void flipCardToDismissalView(RecyclerView.ViewHolder holder) {
|
||||
final ViewFlipper viewFlipper = holder.itemView.findViewById(R.id.view_flipper);
|
||||
viewFlipper.showNext();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user