Setup SearchResultIcon for single cell results
SearchResultIcon will be able to render apps, shortcuts and remote actions. It can also handle its own focused state drawing. Screenshot: https://screenshot.googleplex.com/C3KgjJtLQTBPgaf Bug: 170752716 Test: Manual Change-Id: I460a9c128ea3f5814784e342c5d5fa5b7e310882
This commit is contained in:
parent
d5bbe6809d
commit
314761a808
|
@ -30,6 +30,7 @@
|
|||
with some minor changed based on the derivative app.
|
||||
-->
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.CALL_PHONE" />
|
||||
<uses-permission android:name="android.permission.SET_WALLPAPER" />
|
||||
<uses-permission android:name="android.permission.SET_WALLPAPER_HINTS" />
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2015 The Android Open Source Project
|
||||
<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2015 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.
|
||||
|
@ -13,16 +12,10 @@
|
|||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<com.android.launcher3.BubbleTextView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.android.launcher3.BubbleTextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:launcher="http://schemas.android.com/apk/res-auto"
|
||||
style="@style/BaseIcon"
|
||||
style="@style/BaseIcon.AllApps"
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:stateListAnimator="@animator/all_apps_fastscroll_icon_anim"
|
||||
launcher:iconDisplay="all_apps"
|
||||
launcher:centerVertically="true"
|
||||
android:paddingLeft="@dimen/dynamic_grid_cell_padding_x"
|
||||
android:paddingRight="@dimen/dynamic_grid_cell_padding_x" />
|
||||
launcher:centerVertically="true" />
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2008 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.
|
||||
-->
|
||||
|
||||
<com.android.launcher3.views.SearchResultIcon xmlns:launcher="http://schemas.android.com/apk/res-auto"
|
||||
style="@style/BaseIcon.AllApps"
|
||||
launcher:iconDisplay="all_apps"
|
||||
launcher:centerVertically="true" />
|
||||
|
|
@ -223,6 +223,16 @@
|
|||
<item name="android:lines">1</item>
|
||||
</style>
|
||||
|
||||
<!-- Base theme for AllApps BubbleTextViews -->
|
||||
<style name="BaseIcon.AllApps" parent="BaseIcon">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:stateListAnimator">@animator/all_apps_fastscroll_icon_anim</item>
|
||||
<item name="android:paddingLeft">@dimen/dynamic_grid_cell_padding_x</item>
|
||||
<item name="android:paddingRight">@dimen/dynamic_grid_cell_padding_x</item>
|
||||
</style>
|
||||
|
||||
|
||||
<!-- Icon displayed on the workspace -->
|
||||
<style name="BaseIcon.Workspace" >
|
||||
<item name="android:shadowRadius">2.0</item>
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package com.android.launcher3;
|
||||
|
||||
import static com.android.launcher3.FastBitmapDrawable.newIcon;
|
||||
import static com.android.launcher3.graphics.IconShape.getShape;
|
||||
import static com.android.launcher3.graphics.PreloadIconDrawable.newPendingIcon;
|
||||
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
|
||||
|
||||
|
@ -27,15 +28,18 @@ import android.animation.ValueAnimator;
|
|||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.BlurMaskFilter;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.PorterDuff.Mode;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Process;
|
||||
import android.text.TextUtils.TruncateAt;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Property;
|
||||
|
@ -50,6 +54,8 @@ import androidx.core.graphics.ColorUtils;
|
|||
|
||||
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;
|
||||
import com.android.launcher3.folder.FolderIcon;
|
||||
|
@ -60,6 +66,7 @@ import com.android.launcher3.graphics.PreloadIconDrawable;
|
|||
import com.android.launcher3.icons.DotRenderer;
|
||||
import com.android.launcher3.icons.IconCache.IconLoadRequest;
|
||||
import com.android.launcher3.icons.IconCache.ItemInfoUpdateReceiver;
|
||||
import com.android.launcher3.icons.LauncherIcons;
|
||||
import com.android.launcher3.model.data.AppInfo;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.model.data.ItemInfoWithIcon;
|
||||
|
@ -79,7 +86,7 @@ import java.text.NumberFormat;
|
|||
* too aggressive.
|
||||
*/
|
||||
public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, OnResumeCallback,
|
||||
IconLabelDotView, DraggableView, Reorderable {
|
||||
IconLabelDotView, DraggableView, Reorderable, AllAppsSectionDecorator.SelfDecoratingView {
|
||||
|
||||
private static final int DISPLAY_WORKSPACE = 0;
|
||||
private static final int DISPLAY_ALL_APPS = 1;
|
||||
|
@ -87,6 +94,8 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
|
|||
private static final int DISPLAY_HERO_APP = 5;
|
||||
|
||||
private static final int[] STATE_PRESSED = new int[]{android.R.attr.state_pressed};
|
||||
private static final float HIGHLIGHT_SCALE = 1.16f;
|
||||
|
||||
|
||||
private final PointF mTranslationForReorderBounce = new PointF(0, 0);
|
||||
private final PointF mTranslationForReorderPreview = new PointF(0, 0);
|
||||
|
@ -95,6 +104,11 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
|
|||
|
||||
private float mScaleForReorderBounce = 1f;
|
||||
|
||||
protected final Paint mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private final Path mHighlightPath = new Path();
|
||||
protected int mHighlightColor = Color.TRANSPARENT;
|
||||
private final BlurMaskFilter mHighlightShadowFilter;
|
||||
|
||||
private static final Property<BubbleTextView, Float> DOT_SCALE_PROPERTY
|
||||
= new Property<BubbleTextView, Float>(Float.TYPE, "dotScale") {
|
||||
@Override
|
||||
|
@ -208,6 +222,11 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
|
|||
setEllipsize(TruncateAt.END);
|
||||
setAccessibilityDelegate(mActivity.getAccessibilityDelegate());
|
||||
setTextAlpha(1f);
|
||||
|
||||
int shadowSize = context.getResources().getDimensionPixelSize(
|
||||
R.dimen.blur_size_click_shadow);
|
||||
mHighlightShadowFilter = new BlurMaskFilter(shadowSize, BlurMaskFilter.Blur.INNER);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -421,8 +440,38 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
|
|||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && mHighlightColor != Color.TRANSPARENT) {
|
||||
int count = canvas.save();
|
||||
drawFocusHighlight(canvas);
|
||||
canvas.restoreToCount(count);
|
||||
}
|
||||
super.onDraw(canvas);
|
||||
drawDotIfNecessary(canvas);
|
||||
}
|
||||
|
||||
protected void drawFocusHighlight(Canvas canvas) {
|
||||
boolean isBadged = getTag() instanceof ItemInfo && !Process.myUserHandle().equals(
|
||||
((ItemInfo) getTag()).user);
|
||||
float insetScale = (HIGHLIGHT_SCALE - 1) / 2;
|
||||
canvas.translate(-getIconSize() * insetScale, -insetScale * getIconSize());
|
||||
float outlineSize = getIconSize() * HIGHLIGHT_SCALE;
|
||||
mHighlightPath.reset();
|
||||
mHighlightPaint.reset();
|
||||
getIconBounds(mDotParams.iconBounds);
|
||||
getShape().addToPath(mHighlightPath, mDotParams.iconBounds.left, mDotParams.iconBounds.top,
|
||||
outlineSize / 2);
|
||||
if (isBadged) {
|
||||
float borderSize = outlineSize - getIconSize();
|
||||
float badgeSize = LauncherIcons.getBadgeSizeForIconSize(getIconSize()) + borderSize;
|
||||
float badgeInset = outlineSize - badgeSize;
|
||||
getShape().addToPath(mHighlightPath, mDotParams.iconBounds.left + badgeInset,
|
||||
mDotParams.iconBounds.top + badgeInset, badgeSize / 2);
|
||||
}
|
||||
mHighlightPaint.setMaskFilter(mHighlightShadowFilter);
|
||||
mHighlightPaint.setColor(mDotParams.color);
|
||||
canvas.drawPath(mHighlightPath, mHighlightPaint);
|
||||
mHighlightPaint.setMaskFilter(null);
|
||||
mHighlightPaint.setColor(mHighlightColor);
|
||||
canvas.drawPath(mHighlightPath, mHighlightPaint);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -787,10 +836,11 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
|
|||
|
||||
@Override
|
||||
public SafeCloseable prepareDrawDragView() {
|
||||
int highlightColor = mHighlightColor;
|
||||
mHighlightColor = Color.TRANSPARENT;
|
||||
resetIconScale();
|
||||
setForceHideDot(true);
|
||||
return () -> {
|
||||
};
|
||||
return () -> mHighlightColor = highlightColor;
|
||||
}
|
||||
|
||||
private void resetIconScale() {
|
||||
|
@ -827,4 +877,17 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
|
|||
});
|
||||
iconUpdateAnimation.start();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void decorate(int color) {
|
||||
mHighlightColor = color;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDecoration() {
|
||||
mHighlightColor = Color.TRANSPARENT;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,15 +43,12 @@ import com.android.launcher3.BaseDraggingActivity;
|
|||
import com.android.launcher3.BubbleTextView;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.allapps.search.AllAppsSearchBarController.SearchTargetHandler;
|
||||
import com.android.launcher3.allapps.search.SearchEventTracker;
|
||||
import com.android.launcher3.allapps.search.SearchSectionInfo;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.model.data.AppInfo;
|
||||
import com.android.launcher3.util.PackageManagerHelper;
|
||||
import com.android.launcher3.views.HeroSearchResultView;
|
||||
import com.android.launcher3.views.SearchSliceWrapper;
|
||||
import com.android.systemui.plugins.shared.SearchTarget;
|
||||
import com.android.systemui.plugins.shared.SearchTargetEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -94,9 +91,11 @@ public class AllAppsGridAdapter extends
|
|||
|
||||
public static final int VIEW_TYPE_SEARCH_SUGGEST = 1 << 13;
|
||||
|
||||
public static final int VIEW_TYPE_SEARCH_ICON = 1 << 14;
|
||||
|
||||
// Common view type masks
|
||||
public static final int VIEW_TYPE_MASK_DIVIDER = VIEW_TYPE_ALL_APPS_DIVIDER;
|
||||
public static final int VIEW_TYPE_MASK_ICON = VIEW_TYPE_ICON;
|
||||
public static final int VIEW_TYPE_MASK_ICON = VIEW_TYPE_ICON | VIEW_TYPE_SEARCH_ICON;
|
||||
|
||||
/**
|
||||
* ViewHolder for each icon.
|
||||
|
@ -186,6 +185,7 @@ public class AllAppsGridAdapter extends
|
|||
|| viewType == VIEW_TYPE_SEARCH_PEOPLE
|
||||
|| viewType == VIEW_TYPE_SEARCH_THUMBNAIL
|
||||
|| viewType == VIEW_TYPE_SEARCH_ICON_ROW
|
||||
|| viewType == VIEW_TYPE_SEARCH_ICON
|
||||
|| viewType == VIEW_TYPE_SEARCH_SUGGEST;
|
||||
}
|
||||
}
|
||||
|
@ -399,11 +399,8 @@ public class AllAppsGridAdapter extends
|
|||
R.layout.all_apps_icon, parent, false);
|
||||
icon.setLongPressTimeoutFactor(1f);
|
||||
icon.setOnFocusChangeListener(mIconFocusListener);
|
||||
if (!FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
|
||||
icon.setOnClickListener(mOnIconClickListener);
|
||||
icon.setOnLongClickListener(mOnIconLongClickListener);
|
||||
}
|
||||
|
||||
icon.setOnClickListener(mOnIconClickListener);
|
||||
icon.setOnLongClickListener(mOnIconLongClickListener);
|
||||
// Ensure the all apps icon height matches the workspace icons in portrait mode.
|
||||
icon.getLayoutParams().height = mLauncher.getDeviceProfile().allAppsCellHeightPx;
|
||||
return new ViewHolder(icon);
|
||||
|
@ -419,6 +416,9 @@ public class AllAppsGridAdapter extends
|
|||
case VIEW_TYPE_ALL_APPS_DIVIDER:
|
||||
return new ViewHolder(mLayoutInflater.inflate(
|
||||
R.layout.all_apps_divider, parent, false));
|
||||
case VIEW_TYPE_SEARCH_ICON:
|
||||
return new ViewHolder(mLayoutInflater.inflate(
|
||||
R.layout.search_result_icon, parent, false));
|
||||
case VIEW_TYPE_SEARCH_CORPUS_TITLE:
|
||||
return new ViewHolder(
|
||||
mLayoutInflater.inflate(R.layout.search_section_title, parent, false));
|
||||
|
@ -453,6 +453,10 @@ 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);
|
||||
|
@ -460,43 +464,6 @@ public class AllAppsGridAdapter extends
|
|||
BubbleTextView icon = (BubbleTextView) holder.itemView;
|
||||
icon.reset();
|
||||
icon.applyFromApplicationInfo(info);
|
||||
if (!FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
|
||||
break;
|
||||
}
|
||||
//TODO: replace with custom TopHitBubbleTextView with support for both shortcut
|
||||
// and apps
|
||||
if (adapterItem instanceof SearchAdapterItem) {
|
||||
SearchAdapterItem item = (SearchAdapterItem) adapterItem;
|
||||
SearchTargetHandler searchTargetHandler = new SearchTargetHandler() {
|
||||
@Override
|
||||
public void applySearchTarget(SearchTarget searchTarget) {
|
||||
// Does nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSelection(int type) {
|
||||
SearchTargetEvent e = new SearchTargetEvent(SearchTarget.ItemType.APP,
|
||||
type, item.position, item.getSearchSessionId());
|
||||
e.bundle = HeroSearchResultView.getAppBundle(info);
|
||||
SearchEventTracker.INSTANCE.get(mLauncher).notifySearchTargetEvent(e);
|
||||
}
|
||||
};
|
||||
SearchEventTracker.INSTANCE.get(mLauncher).registerWeakHandler(
|
||||
((SearchAdapterItem) adapterItem).getSearchTarget(),
|
||||
searchTargetHandler);
|
||||
|
||||
icon.setOnClickListener(view -> {
|
||||
searchTargetHandler.handleSelection(SearchTargetEvent.SELECT);
|
||||
mOnIconClickListener.onClick(view);
|
||||
});
|
||||
icon.setOnLongClickListener(view -> {
|
||||
searchTargetHandler.handleSelection(SearchTargetEvent.LONG_PRESS);
|
||||
return mOnIconLongClickListener.onLongClick(view);
|
||||
});
|
||||
} else {
|
||||
icon.setOnClickListener(mOnIconClickListener);
|
||||
icon.setOnLongClickListener(mOnIconLongClickListener);
|
||||
}
|
||||
break;
|
||||
case VIEW_TYPE_EMPTY_SEARCH:
|
||||
TextView emptyViewText = (TextView) holder.itemView;
|
||||
|
@ -525,6 +492,7 @@ public class AllAppsGridAdapter extends
|
|||
case VIEW_TYPE_SEARCH_ROW_WITH_BUTTON:
|
||||
case VIEW_TYPE_SEARCH_HERO_APP:
|
||||
case VIEW_TYPE_SEARCH_ROW:
|
||||
case VIEW_TYPE_SEARCH_ICON:
|
||||
case VIEW_TYPE_SEARCH_ICON_ROW:
|
||||
case VIEW_TYPE_SEARCH_PEOPLE:
|
||||
case VIEW_TYPE_SEARCH_THUMBNAIL:
|
||||
|
@ -544,11 +512,10 @@ public class AllAppsGridAdapter extends
|
|||
public void onViewRecycled(@NonNull ViewHolder holder) {
|
||||
super.onViewRecycled(holder);
|
||||
if (!FeatureFlags.ENABLE_DEVICE_SEARCH.get()) return;
|
||||
if (holder.itemView instanceof BubbleTextView) {
|
||||
BubbleTextView icon = (BubbleTextView) holder.itemView;
|
||||
icon.setOnClickListener(null);
|
||||
icon.setOnLongClickListener(null);
|
||||
} else if (holder.itemView instanceof SliceView) {
|
||||
if (holder.itemView instanceof AllAppsSectionDecorator.SelfDecoratingView) {
|
||||
((AllAppsSectionDecorator.SelfDecoratingView) holder.itemView).removeDecoration();
|
||||
}
|
||||
if (holder.itemView instanceof SliceView) {
|
||||
SliceView sliceView = (SliceView) holder.itemView;
|
||||
if (sliceView.getTag() instanceof SearchSliceWrapper) {
|
||||
((SearchSliceWrapper) sliceView.getTag()).destroy();
|
||||
|
|
|
@ -54,6 +54,9 @@ public class AllAppsSectionDecorator extends RecyclerView.ItemDecoration {
|
|||
int i = 0;
|
||||
while (i < itemCount) {
|
||||
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) {
|
||||
|
@ -93,7 +96,7 @@ public class AllAppsSectionDecorator extends RecyclerView.ItemDecoration {
|
|||
int index = mAppsView.getApps().getFocusedChildIndex();
|
||||
AppsGridLayoutManager layoutManager = (AppsGridLayoutManager)
|
||||
mAppsView.getActiveRecyclerView().getLayoutManager();
|
||||
if (layoutManager.findFirstVisibleItemPosition() == index
|
||||
if (layoutManager.findFirstVisibleItemPosition() <= index
|
||||
&& index < parent.getChildCount()) {
|
||||
decorationHandler.onFocusDraw(c, parent.getChildAt(index));
|
||||
}
|
||||
|
@ -156,6 +159,10 @@ 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);
|
||||
|
@ -169,4 +176,18 @@ public class AllAppsSectionDecorator extends RecyclerView.ItemDecoration {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ package com.android.launcher3.allapps;
|
|||
import static com.android.launcher3.model.data.AppInfo.COMPONENT_KEY_COMPARATOR;
|
||||
import static com.android.launcher3.model.data.AppInfo.EMPTY_ARRAY;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.os.UserHandle;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
|
@ -27,6 +29,7 @@ import com.android.launcher3.model.data.ItemInfo;
|
|||
import com.android.launcher3.model.data.PromiseAppInfo;
|
||||
import com.android.launcher3.util.ComponentKey;
|
||||
import com.android.launcher3.util.PackageUserKey;
|
||||
import com.android.systemui.plugins.shared.SearchTarget;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -86,6 +89,19 @@ public class AllAppsStore {
|
|||
return index < 0 ? null : mApps[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets AppInfo from {@link SearchTarget}
|
||||
* TODO: SearchTarget should have userHandle and ComponentKey members
|
||||
*/
|
||||
public AppInfo getAppFromSearchTarget(SearchTarget searchTarget) {
|
||||
ComponentName cn = searchTarget.bundle.getParcelable("component_name");
|
||||
UserHandle userHandle = searchTarget.bundle.getParcelable("user_handle");
|
||||
if (cn == null) {
|
||||
throw new IllegalStateException("Component name is required for AppInfo");
|
||||
}
|
||||
return getApp(new ComponentKey(cn, userHandle));
|
||||
}
|
||||
|
||||
public void enableDeferUpdates(int flag) {
|
||||
mDeferUpdatesFlags |= flag;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package com.android.launcher3.allapps.search;
|
||||
|
||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
@ -61,7 +63,7 @@ public class SearchEventTracker {
|
|||
*/
|
||||
public void notifySearchTargetEvent(SearchTargetEvent searchTargetEvent) {
|
||||
if (mPlugin != null) {
|
||||
mPlugin.notifySearchTargetEvent(searchTargetEvent);
|
||||
UI_HELPER_EXECUTOR.post(() -> mPlugin.notifySearchTargetEvent(searchTargetEvent));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,13 +19,11 @@ import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_ALL_APP
|
|||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.graphics.Point;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Pair;
|
||||
import android.view.View;
|
||||
|
@ -51,7 +49,6 @@ import com.android.launcher3.model.data.ItemInfoWithIcon;
|
|||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
|
||||
import com.android.launcher3.touch.ItemLongClickListener;
|
||||
import com.android.launcher3.util.ComponentKey;
|
||||
import com.android.systemui.plugins.shared.SearchTarget;
|
||||
import com.android.systemui.plugins.shared.SearchTargetEvent;
|
||||
|
||||
|
@ -122,7 +119,8 @@ public class HeroSearchResultView extends LinearLayout implements DragSource, Se
|
|||
|
||||
@Override
|
||||
public void applySearchTarget(SearchTarget searchTarget) {
|
||||
AppInfo appInfo = getAppInfo(searchTarget.bundle);
|
||||
AllAppsStore apps = Launcher.getLauncher(getContext()).getAppsView().getAppsStore();
|
||||
AppInfo appInfo = apps.getAppFromSearchTarget(searchTarget);
|
||||
// TODO: replace this with searchTarget.shortcuts
|
||||
ArrayList<ShortcutInfo> infos = searchTarget.bundle.getParcelableArrayList(
|
||||
SHORTCUTS_KEY);
|
||||
|
@ -156,13 +154,6 @@ public class HeroSearchResultView extends LinearLayout implements DragSource, Se
|
|||
SearchEventTracker.INSTANCE.get(getContext()).registerWeakHandler(searchTarget, this);
|
||||
}
|
||||
|
||||
private AppInfo getAppInfo(Bundle bundle) {
|
||||
AllAppsStore apps = Launcher.getLauncher(getContext()).getAppsView().getAppsStore();
|
||||
ComponentName cn = bundle.getParcelable("component_name");
|
||||
UserHandle userHandle = bundle.getParcelable("user_handle");
|
||||
return (cn != null) ? apps.getApp(new ComponentKey(cn, userHandle)) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getTargetInfo() {
|
||||
return mTargetInfo;
|
||||
|
|
|
@ -42,7 +42,7 @@ import com.android.launcher3.util.Themes;
|
|||
*/
|
||||
public class ScrimView<T extends Launcher> extends View implements Insettable, OnChangeListener {
|
||||
|
||||
private static final float SCRIM_ALPHA = .8f;
|
||||
private static final float SCRIM_ALPHA = .75f;
|
||||
protected final T mLauncher;
|
||||
private final WallpaperColorInfo mWallpaperColorInfo;
|
||||
protected final int mEndScrim;
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (C) 2020 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.launcher3.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.launcher3.BubbleTextView;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.allapps.AllAppsStore;
|
||||
import com.android.launcher3.allapps.search.AllAppsSearchBarController;
|
||||
import com.android.launcher3.allapps.search.SearchEventTracker;
|
||||
import com.android.launcher3.model.data.AppInfo;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.touch.ItemLongClickListener;
|
||||
import com.android.systemui.plugins.shared.SearchTarget;
|
||||
import com.android.systemui.plugins.shared.SearchTargetEvent;
|
||||
|
||||
/**
|
||||
* A {@link BubbleTextView} representing a single cell result in AllApps
|
||||
*/
|
||||
public class SearchResultIcon extends BubbleTextView implements
|
||||
AllAppsSearchBarController.SearchTargetHandler, View.OnClickListener,
|
||||
View.OnLongClickListener {
|
||||
private final Object[] mTargetInfo = createTargetInfo();
|
||||
private final Launcher mLauncher;
|
||||
|
||||
private SearchTarget mSearchTarget;
|
||||
|
||||
public SearchResultIcon(Context context) {
|
||||
this(context, null, 0);
|
||||
}
|
||||
|
||||
public SearchResultIcon(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public SearchResultIcon(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
mLauncher = Launcher.getLauncher(getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
setLongPressTimeoutFactor(1f);
|
||||
setOnFocusChangeListener(mLauncher.getFocusHandler());
|
||||
setOnClickListener(this);
|
||||
setOnLongClickListener(this);
|
||||
getLayoutParams().height = mLauncher.getDeviceProfile().allAppsCellHeightPx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applySearchTarget(SearchTarget searchTarget) {
|
||||
mSearchTarget = searchTarget;
|
||||
AllAppsStore appsStore = mLauncher.getAppsView().getAppsStore();
|
||||
if (searchTarget.type == SearchTarget.ItemType.APP) {
|
||||
AppInfo appInfo = appsStore.getAppFromSearchTarget(searchTarget);
|
||||
applyFromApplicationInfo(appInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getTargetInfo() {
|
||||
return mTargetInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSelection(int eventType) {
|
||||
SearchTargetEvent event = getSearchTargetEvent(mSearchTarget.type,
|
||||
eventType);
|
||||
if (mSearchTarget.type.equals(SearchTarget.ItemType.APP)) {
|
||||
event.bundle = HeroSearchResultView.getAppBundle((ItemInfo) getTag());
|
||||
}
|
||||
SearchEventTracker.INSTANCE.get(mLauncher).notifySearchTargetEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
handleSelection(SearchTargetEvent.SELECT);
|
||||
mLauncher.getItemOnClickListener().onClick(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View view) {
|
||||
handleSelection(SearchTargetEvent.LONG_PRESS);
|
||||
return ItemLongClickListener.INSTANCE_ALL_APPS.onLongClick(view);
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@ import android.app.RemoteAction;
|
|||
import android.content.Context;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
@ -44,6 +45,7 @@ import com.android.launcher3.model.data.ItemInfoWithIcon;
|
|||
import com.android.launcher3.model.data.RemoteActionItemInfo;
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
import com.android.launcher3.touch.ItemClickHandler;
|
||||
import com.android.launcher3.util.Themes;
|
||||
import com.android.systemui.plugins.shared.SearchTarget;
|
||||
import com.android.systemui.plugins.shared.SearchTarget.ItemType;
|
||||
import com.android.systemui.plugins.shared.SearchTargetEvent;
|
||||
|
@ -97,6 +99,14 @@ public class SearchResultIconRow extends DoubleShadowBubbleTextView implements
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawFocusHighlight(Canvas canvas) {
|
||||
mHighlightPaint.setColor(mHighlightColor);
|
||||
float r = Themes.getDialogCornerRadius(getContext());
|
||||
canvas.drawRoundRect(0, 0, getWidth(), getHeight(), r, r, mHighlightPaint);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void applySearchTarget(SearchTarget searchTarget) {
|
||||
if (searchTarget.mRemoteAction != null) {
|
||||
|
|
Loading…
Reference in New Issue