Merge "Add group highlighting to AA+ result" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
dfdeddc66a
@@ -130,7 +130,7 @@ public class PredictionRowView extends LinearLayout implements
|
||||
|
||||
if (FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
|
||||
mDecorationHandler = new AllAppsSectionDecorator.SectionDecorationHandler(getContext(),
|
||||
false);
|
||||
false, 0, true, true);
|
||||
}
|
||||
|
||||
updateVisibility();
|
||||
@@ -164,7 +164,7 @@ public class PredictionRowView extends LinearLayout implements
|
||||
for (int i = 0; i < childrenCount; i++) {
|
||||
mDecorationHandler.extendBounds(getChildAt(i));
|
||||
}
|
||||
mDecorationHandler.onDraw(canvas);
|
||||
mDecorationHandler.onGroupDraw(canvas);
|
||||
mDecorationHandler.onFocusDraw(canvas, getFocusedChild());
|
||||
mLauncher.getAppsView().getActiveRecyclerView().invalidateItemDecorations();
|
||||
}
|
||||
|
||||
@@ -254,11 +254,13 @@
|
||||
|
||||
<!-- Search related -->
|
||||
<dimen name="search_hero_title_size">16sp</dimen>
|
||||
<dimen name="search_hero_subtitle_size">15sp</dimen>
|
||||
<dimen name="search_hero_subtitle_size">14sp</dimen>
|
||||
<dimen name="search_hero_inline_button_size">12sp</dimen>
|
||||
<dimen name="search_settings_icon_size">36dp</dimen>
|
||||
<dimen name="search_settings_icon_vertical_offset">16dp</dimen>
|
||||
<dimen name="search_line_spacing">4dp</dimen>
|
||||
<dimen name="search_decoration_corner_radius">28dp</dimen>
|
||||
<dimen name="search_decoration_padding">1dp</dimen>
|
||||
|
||||
<!-- Taskbar related (placeholders to compile in Launcher3 without Quickstep) -->
|
||||
<dimen name="taskbar_size">0dp</dimen>
|
||||
|
||||
@@ -53,7 +53,6 @@ import androidx.annotation.UiThread;
|
||||
|
||||
import com.android.launcher3.Launcher.OnResumeCallback;
|
||||
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
|
||||
import com.android.launcher3.allapps.AllAppsSectionDecorator;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.dot.DotInfo;
|
||||
import com.android.launcher3.dragndrop.DraggableView;
|
||||
@@ -84,7 +83,7 @@ import java.text.NumberFormat;
|
||||
* too aggressive.
|
||||
*/
|
||||
public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, OnResumeCallback,
|
||||
IconLabelDotView, DraggableView, Reorderable, AllAppsSectionDecorator.SelfDecoratingView {
|
||||
IconLabelDotView, DraggableView, Reorderable {
|
||||
|
||||
private static final int DISPLAY_WORKSPACE = 0;
|
||||
private static final int DISPLAY_ALL_APPS = 1;
|
||||
@@ -954,16 +953,4 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
|
||||
setCompoundDrawables(null, newIcon, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decorate(int color) {
|
||||
mHighlightColor = color;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDecoration() {
|
||||
mHighlightColor = Color.TRANSPARENT;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,8 +42,7 @@ import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.BubbleTextView;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.allapps.search.SearchAdapterProvider;
|
||||
import com.android.launcher3.allapps.search.SearchSectionInfo;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.allapps.search.SectionDecorationInfo;
|
||||
import com.android.launcher3.model.data.AppInfo;
|
||||
import com.android.launcher3.util.PackageManagerHelper;
|
||||
|
||||
@@ -109,7 +108,7 @@ public class AllAppsGridAdapter extends
|
||||
// The index of this app not including sections
|
||||
public int appIndex = -1;
|
||||
// Search section associated to result
|
||||
public SearchSectionInfo searchSectionInfo = null;
|
||||
public SectionDecorationInfo sectionDecorationInfo = null;
|
||||
|
||||
/**
|
||||
* Factory method for AppIcon AdapterItem
|
||||
@@ -372,10 +371,6 @@ public class AllAppsGridAdapter extends
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||
if (FeatureFlags.ENABLE_DEVICE_SEARCH.get()
|
||||
&& holder.itemView instanceof AllAppsSectionDecorator.SelfDecoratingView) {
|
||||
((AllAppsSectionDecorator.SelfDecoratingView) holder.itemView).removeDecoration();
|
||||
}
|
||||
switch (holder.getItemViewType()) {
|
||||
case VIEW_TYPE_ICON:
|
||||
AdapterItem adapterItem = mApps.getAdapterItems().get(position);
|
||||
@@ -409,10 +404,6 @@ public class AllAppsGridAdapter extends
|
||||
@Override
|
||||
public void onViewRecycled(@NonNull ViewHolder holder) {
|
||||
super.onViewRecycled(holder);
|
||||
if (!FeatureFlags.ENABLE_DEVICE_SEARCH.get()) return;
|
||||
if (holder.itemView instanceof AllAppsSectionDecorator.SelfDecoratingView) {
|
||||
((AllAppsSectionDecorator.SelfDecoratingView) holder.itemView).removeDecoration();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -18,16 +18,18 @@ package com.android.launcher3.allapps;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.RectF;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.allapps.AllAppsGridAdapter.AppsGridLayoutManager;
|
||||
import com.android.launcher3.allapps.search.SearchSectionInfo;
|
||||
import com.android.launcher3.allapps.search.SectionDecorationInfo;
|
||||
import com.android.launcher3.util.Themes;
|
||||
|
||||
import java.util.List;
|
||||
@@ -45,52 +47,51 @@ public class AllAppsSectionDecorator extends RecyclerView.ItemDecoration {
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
|
||||
// Iterate through views in recylerview and draw bounds around views in the same section.
|
||||
// Since views in the same section will follow each other, we can skip to a last view in
|
||||
// a section to get the bounds of the section without having to iterate on every item.
|
||||
int itemCount = parent.getChildCount();
|
||||
List<AllAppsGridAdapter.AdapterItem> adapterItems = mAppsView.getApps().getAdapterItems();
|
||||
SectionDecorationHandler lastDecorationHandler = null;
|
||||
int i = 0;
|
||||
while (i < itemCount) {
|
||||
boolean drawFallbackFocusedView = true;
|
||||
for (int i = 0; i < parent.getChildCount(); i++) {
|
||||
View view = parent.getChildAt(i);
|
||||
if (view instanceof SelfDecoratingView) {
|
||||
((SelfDecoratingView) view).removeDecoration();
|
||||
}
|
||||
int position = parent.getChildAdapterPosition(view);
|
||||
AllAppsGridAdapter.AdapterItem adapterItem = adapterItems.get(position);
|
||||
if (adapterItem.searchSectionInfo != null) {
|
||||
SearchSectionInfo sectionInfo = adapterItem.searchSectionInfo;
|
||||
int endIndex = Math.min(i + sectionInfo.getPosEnd() - position, itemCount - 1);
|
||||
if (adapterItem.sectionDecorationInfo != null) {
|
||||
SectionDecorationInfo sectionInfo = adapterItem.sectionDecorationInfo;
|
||||
SectionDecorationHandler decorationHandler = sectionInfo.getDecorationHandler();
|
||||
if (decorationHandler != lastDecorationHandler && lastDecorationHandler != null) {
|
||||
drawDecoration(c, lastDecorationHandler, parent);
|
||||
}
|
||||
lastDecorationHandler = decorationHandler;
|
||||
if (decorationHandler != null) {
|
||||
decorationHandler.extendBounds(view);
|
||||
}
|
||||
|
||||
if (endIndex > i) {
|
||||
i = endIndex;
|
||||
continue;
|
||||
if (sectionInfo.isFocusedView()) {
|
||||
decorationHandler.onFocusDraw(c, view);
|
||||
drawFallbackFocusedView = false;
|
||||
} else {
|
||||
decorationHandler.onGroupDraw(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (lastDecorationHandler != null) {
|
||||
drawDecoration(c, lastDecorationHandler, parent);
|
||||
// fallback logic in case none of the SearchTarget is labeled as focused item
|
||||
if (drawFallbackFocusedView) {
|
||||
for (int i = 0; i < parent.getChildCount(); i++) {
|
||||
View view = parent.getChildAt(i);
|
||||
int position = parent.getChildAdapterPosition(view);
|
||||
AllAppsGridAdapter.AdapterItem adapterItem = adapterItems.get(position);
|
||||
if (adapterItem.sectionDecorationInfo != null) {
|
||||
SectionDecorationInfo sectionInfo = adapterItem.sectionDecorationInfo;
|
||||
SectionDecorationHandler decorationHandler = sectionInfo.getDecorationHandler();
|
||||
if (decorationHandler != null) {
|
||||
drawDecoration(c, decorationHandler, parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void drawDecoration(Canvas c, SectionDecorationHandler decorationHandler,
|
||||
RecyclerView parent) {
|
||||
if (decorationHandler == null) return;
|
||||
// Fallback logic in case non of the SearchTarget is labeled as focused item.
|
||||
private void drawDecoration(@NonNull Canvas c,
|
||||
@NonNull SectionDecorationHandler decorationHandler,
|
||||
@NonNull RecyclerView parent) {
|
||||
if (decorationHandler.mIsFullWidth) {
|
||||
decorationHandler.mBounds.left = parent.getPaddingLeft();
|
||||
decorationHandler.mBounds.right = parent.getWidth() - parent.getPaddingRight();
|
||||
}
|
||||
decorationHandler.onDraw(c);
|
||||
if (mAppsView.getFloatingHeaderView().getFocusedChild() == null
|
||||
&& mAppsView.getApps().getFocusedChild() != null) {
|
||||
int index = mAppsView.getApps().getFocusedChildIndex();
|
||||
@@ -109,23 +110,41 @@ public class AllAppsSectionDecorator extends RecyclerView.ItemDecoration {
|
||||
* Handles grouping and drawing of items in the same all apps sections.
|
||||
*/
|
||||
public static class SectionDecorationHandler {
|
||||
private static final int FILL_ALPHA = 0;
|
||||
|
||||
protected RectF mBounds = new RectF();
|
||||
private final boolean mIsFullWidth;
|
||||
private final float mRadius;
|
||||
|
||||
protected int mFocusColor;
|
||||
protected int mFillcolor;
|
||||
protected final int mFocusColor; // main focused item color
|
||||
protected final int mFillcolor; // grouping color
|
||||
|
||||
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private final boolean mIsTopRound;
|
||||
private final boolean mIsBottomRound;
|
||||
private float [] mCorners;
|
||||
private float mFillSpacing;
|
||||
|
||||
public SectionDecorationHandler(Context context, boolean isFullWidth, int fillAlpha,
|
||||
boolean isTopRound, boolean isBottomRound) {
|
||||
|
||||
public SectionDecorationHandler(Context context, boolean isFullWidth) {
|
||||
mIsFullWidth = isFullWidth;
|
||||
int endScrim = Themes.getColorBackground(context);
|
||||
mFillcolor = ColorUtils.setAlphaComponent(endScrim, FILL_ALPHA);
|
||||
mFocusColor = endScrim;
|
||||
mRadius = Themes.getDialogCornerRadius(context);
|
||||
mFillcolor = ColorUtils.setAlphaComponent(endScrim, fillAlpha);
|
||||
mFocusColor = ColorUtils.setAlphaComponent(endScrim, fillAlpha);
|
||||
|
||||
mIsTopRound = isTopRound;
|
||||
mIsBottomRound = isBottomRound;
|
||||
|
||||
mRadius = context.getResources().getDimensionPixelSize(
|
||||
R.dimen.search_decoration_corner_radius);
|
||||
mFillSpacing = context.getResources().getDimensionPixelSize(
|
||||
R.dimen.search_decoration_padding);
|
||||
mCorners = new float[]{
|
||||
mIsTopRound ? mRadius : 0, mIsTopRound ? mRadius : 0, // Top left radius in px
|
||||
mIsTopRound ? mRadius : 0, mIsTopRound ? mRadius : 0, // Top right radius in px
|
||||
mIsBottomRound ? mRadius : 0, mIsBottomRound ? mRadius : 0, // Bottom right
|
||||
mIsBottomRound ? mRadius : 0, mIsBottomRound ? mRadius : 0 // Bottom left
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,9 +166,9 @@ public class AllAppsSectionDecorator extends RecyclerView.ItemDecoration {
|
||||
/**
|
||||
* Draw bounds onto canvas.
|
||||
*/
|
||||
public void onDraw(Canvas canvas) {
|
||||
public void onGroupDraw(Canvas canvas) {
|
||||
mPaint.setColor(mFillcolor);
|
||||
canvas.drawRoundRect(mBounds, mRadius, mRadius, mPaint);
|
||||
onDraw(canvas);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,13 +178,20 @@ public class AllAppsSectionDecorator extends RecyclerView.ItemDecoration {
|
||||
if (view == null) {
|
||||
return;
|
||||
}
|
||||
if (view instanceof SelfDecoratingView) {
|
||||
((SelfDecoratingView) view).decorate(mFocusColor);
|
||||
return;
|
||||
}
|
||||
mPaint.setColor(mFocusColor);
|
||||
canvas.drawRoundRect(view.getLeft(), view.getTop(),
|
||||
view.getRight(), view.getBottom(), mRadius, mRadius, mPaint);
|
||||
mBounds.set(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
|
||||
onDraw(canvas);
|
||||
}
|
||||
|
||||
|
||||
private void onDraw(Canvas canvas) {
|
||||
final Path path = new Path();
|
||||
RectF finalBounds = new RectF(mBounds.left + mFillSpacing,
|
||||
mBounds.top + mFillSpacing,
|
||||
mBounds.right - mFillSpacing,
|
||||
mBounds.bottom - mFillSpacing);
|
||||
path.addRoundRect(finalBounds, mCorners, Path.Direction.CW);
|
||||
canvas.drawPath(path, mPaint);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -175,19 +201,4 @@ public class AllAppsSectionDecorator extends RecyclerView.ItemDecoration {
|
||||
mBounds.setEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An interface for a view to draw highlight indicator
|
||||
*/
|
||||
public interface SelfDecoratingView {
|
||||
/**
|
||||
* Removes decorations drawing if focus is acquired by another view
|
||||
*/
|
||||
void removeDecoration();
|
||||
|
||||
/**
|
||||
* Draws highlight indicator on view.
|
||||
*/
|
||||
void decorate(int focusColor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import android.content.Context;
|
||||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItem;
|
||||
import com.android.launcher3.allapps.search.SearchSectionInfo;
|
||||
import com.android.launcher3.allapps.search.SectionDecorationInfo;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.model.data.AppInfo;
|
||||
import com.android.launcher3.util.ItemInfoMatcher;
|
||||
@@ -201,20 +201,11 @@ public class AlphabeticalAppsList implements AllAppsStore.OnUpdateListener {
|
||||
}
|
||||
|
||||
void updateSearchAdapterItems(ArrayList<AdapterItem> list, int offset) {
|
||||
SearchSectionInfo lastSection = null;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
AdapterItem adapterItem = list.get(i);
|
||||
adapterItem.position = offset + i;
|
||||
mAdapterItems.add(adapterItem);
|
||||
if (adapterItem.searchSectionInfo != lastSection) {
|
||||
if (adapterItem.searchSectionInfo != null) {
|
||||
adapterItem.searchSectionInfo.setPosStart(adapterItem.position);
|
||||
}
|
||||
if (lastSection != null) {
|
||||
lastSection.setPosEnd(adapterItem.position - 1);
|
||||
}
|
||||
lastSection = adapterItem.searchSectionInfo;
|
||||
}
|
||||
|
||||
if (adapterItem.isCountedForAccessibility()) {
|
||||
mAccessibilityResultsCount++;
|
||||
}
|
||||
@@ -295,16 +286,16 @@ public class AlphabeticalAppsList implements AllAppsStore.OnUpdateListener {
|
||||
mFastScrollerSections.clear();
|
||||
mAdapterItems.clear();
|
||||
|
||||
SearchSectionInfo appSection = new SearchSectionInfo();
|
||||
SectionDecorationInfo appSection = new SectionDecorationInfo();
|
||||
appSection.setDecorationHandler(
|
||||
new AllAppsSectionDecorator.SectionDecorationHandler(mLauncher, true));
|
||||
new AllAppsSectionDecorator.SectionDecorationHandler(mLauncher, true,
|
||||
0, false, false));
|
||||
|
||||
// Recreate the filtered and sectioned apps (for convenience for the grid layout) from the
|
||||
// ordered set of sections
|
||||
|
||||
if (!hasFilter()) {
|
||||
mAccessibilityResultsCount = mApps.size();
|
||||
appSection.setPosStart(position);
|
||||
for (AppInfo info : mApps) {
|
||||
String sectionName = info.sectionName;
|
||||
|
||||
@@ -321,11 +312,10 @@ public class AlphabeticalAppsList implements AllAppsStore.OnUpdateListener {
|
||||
lastFastScrollerSectionInfo.fastScrollToItem = appItem;
|
||||
}
|
||||
if (FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
|
||||
appItem.searchSectionInfo = appSection;
|
||||
appItem.sectionDecorationInfo = appSection;
|
||||
}
|
||||
mAdapterItems.add(appItem);
|
||||
}
|
||||
appSection.setPosEnd(mApps.isEmpty() ? appSection.getPosStart() : position - 1);
|
||||
} else {
|
||||
updateSearchAdapterItems(mSearchResults, 0);
|
||||
if (!FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
|
||||
|
||||
@@ -37,14 +37,14 @@ public class AppsSearchPipeline implements SearchPipeline {
|
||||
|
||||
private static final int MAX_RESULTS_COUNT = 5;
|
||||
|
||||
private final SearchSectionInfo mSearchSectionInfo;
|
||||
private final SectionDecorationInfo mSearchSectionInfo;
|
||||
private final LauncherAppState mLauncherAppState;
|
||||
|
||||
public AppsSearchPipeline(Context context, LauncherAppState launcherAppState) {
|
||||
mLauncherAppState = launcherAppState;
|
||||
mSearchSectionInfo = new SearchSectionInfo();
|
||||
mSearchSectionInfo = new SectionDecorationInfo();
|
||||
mSearchSectionInfo.setDecorationHandler(
|
||||
new SectionDecorationHandler(context, true));
|
||||
new SectionDecorationHandler(context, true, 0, true, true));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,7 +81,7 @@ public class AppsSearchPipeline implements SearchPipeline {
|
||||
ArrayList<AdapterItem> items = new ArrayList<>();
|
||||
for (int i = 0; i < matchingApps.size() && i < MAX_RESULTS_COUNT; i++) {
|
||||
AdapterItem appItem = AdapterItem.asApp(i, "", matchingApps.get(i), i);
|
||||
appItem.searchSectionInfo = mSearchSectionInfo;
|
||||
appItem.sectionDecorationInfo = mSearchSectionInfo;
|
||||
items.add(appItem);
|
||||
}
|
||||
|
||||
|
||||
+12
-20
@@ -18,37 +18,30 @@ package com.android.launcher3.allapps.search;
|
||||
import com.android.launcher3.allapps.AllAppsSectionDecorator.SectionDecorationHandler;
|
||||
|
||||
/**
|
||||
* Info class for a search section
|
||||
* Info class for a search section that is primarily used for decoration.
|
||||
*/
|
||||
public class SearchSectionInfo {
|
||||
public class SectionDecorationInfo {
|
||||
|
||||
public static final int QUICK_LAUNCH = 1 << 0;
|
||||
public static final int GROUPING = 1 << 1;
|
||||
|
||||
private String mSectionId;
|
||||
private boolean mFocused;
|
||||
private SectionDecorationHandler mDecorationHandler;
|
||||
|
||||
public int getPosStart() {
|
||||
return mPosStart;
|
||||
public boolean isFocusedView() {
|
||||
return mFocused;
|
||||
}
|
||||
|
||||
public void setPosStart(int posStart) {
|
||||
mPosStart = posStart;
|
||||
public void setFocusedView(boolean focused) {
|
||||
mFocused = focused;
|
||||
}
|
||||
|
||||
public int getPosEnd() {
|
||||
return mPosEnd;
|
||||
}
|
||||
|
||||
public void setPosEnd(int posEnd) {
|
||||
mPosEnd = posEnd;
|
||||
}
|
||||
|
||||
private int mPosStart;
|
||||
private int mPosEnd;
|
||||
|
||||
public SearchSectionInfo() {
|
||||
public SectionDecorationInfo() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public SearchSectionInfo(String sectionId) {
|
||||
public SectionDecorationInfo(String sectionId) {
|
||||
mSectionId = sectionId;
|
||||
}
|
||||
|
||||
@@ -56,7 +49,6 @@ public class SearchSectionInfo {
|
||||
mDecorationHandler = sectionDecorationHandler;
|
||||
}
|
||||
|
||||
|
||||
public SectionDecorationHandler getDecorationHandler() {
|
||||
return mDecorationHandler;
|
||||
}
|
||||
Reference in New Issue
Block a user