Loading res/layout/search_result_thumbnail.xml 0 → 100644 +19 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- 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. --> <com.android.launcher3.views.ThumbnailSearchResultView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="125dp" android:layout_height="125dp"/> No newline at end of file src/com/android/launcher3/allapps/AllAppsGridAdapter.java +17 −5 Original line number Diff line number Diff line Loading @@ -96,6 +96,8 @@ public class AllAppsGridAdapter extends public static final int VIEW_TYPE_SEARCH_PEOPLE = 1 << 11; public static final int VIEW_TYPE_SEARCH_THUMBNAIL = 1 << 12; // 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; Loading Loading @@ -186,6 +188,7 @@ public class AllAppsGridAdapter extends || viewType == VIEW_TYPE_SEARCH_SLICE || viewType == VIEW_TYPE_SEARCH_ROW || viewType == VIEW_TYPE_SEARCH_PEOPLE || viewType == VIEW_TYPE_SEARCH_THUMBNAIL || viewType == VIEW_TYPE_SEARCH_SHORTCUT; } } Loading Loading @@ -307,15 +310,21 @@ public class AllAppsGridAdapter extends @Override public int getSpanSize(int position) { if (isIconViewType(mApps.getAdapterItems().get(position).viewType)) { return 1; int viewType = mApps.getAdapterItems().get(position).viewType; if (isIconViewType(viewType)) { return 1 * SPAN_MULTIPLIER; } else if (viewType == VIEW_TYPE_SEARCH_THUMBNAIL) { return mAppsPerRow; } else { // Section breaks span the full width return mAppsPerRow; return mAppsPerRow * SPAN_MULTIPLIER; } } } // multiplier to support adapter item column count that is not mAppsPerRow. private static final int SPAN_MULTIPLIER = 3; private final BaseDraggingActivity mLauncher; private final LayoutInflater mLayoutInflater; private final AlphabeticalAppsList mApps; Loading Loading @@ -352,7 +361,7 @@ public class AllAppsGridAdapter extends public void setAppsPerRow(int appsPerRow) { mAppsPerRow = appsPerRow; mGridLayoutMgr.setSpanCount(mAppsPerRow); mGridLayoutMgr.setSpanCount(mAppsPerRow * SPAN_MULTIPLIER); } /** Loading Loading @@ -444,6 +453,9 @@ public class AllAppsGridAdapter extends case VIEW_TYPE_SEARCH_PEOPLE: return new ViewHolder(mLayoutInflater.inflate( R.layout.search_result_people_item, parent, false)); case VIEW_TYPE_SEARCH_THUMBNAIL: return new ViewHolder(mLayoutInflater.inflate( R.layout.search_result_thumbnail, parent, false)); default: throw new RuntimeException("Unexpected view type"); } Loading Loading @@ -525,6 +537,7 @@ public class AllAppsGridAdapter extends case VIEW_TYPE_SEARCH_ROW: case VIEW_TYPE_SEARCH_SHORTCUT: case VIEW_TYPE_SEARCH_PEOPLE: case VIEW_TYPE_SEARCH_THUMBNAIL: PayloadResultHandler payloadResultView = (PayloadResultHandler) holder.itemView; payloadResultView.applyAdapterInfo( (AdapterItemWithPayload) mApps.getAdapterItems().get(position)); Loading Loading @@ -553,7 +566,6 @@ public class AllAppsGridAdapter extends } } @Override public boolean onFailedToRecycleView(ViewHolder holder) { // Always recycle and we will reset the view when it is bound Loading src/com/android/launcher3/views/ThumbnailSearchResultView.java 0 → 100644 +81 −0 Original line number Diff line number Diff line /* * 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.content.Intent; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; import android.util.AttributeSet; import androidx.core.graphics.drawable.RoundedBitmapDrawable; import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; import com.android.launcher3.Launcher; import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItemWithPayload; import com.android.launcher3.allapps.search.AllAppsSearchBarController; import com.android.launcher3.util.Themes; import com.android.systemui.plugins.AllAppsSearchPlugin; import com.android.systemui.plugins.shared.SearchTarget; import com.android.systemui.plugins.shared.SearchTargetEvent; /** * A view representing a high confidence app search result that includes shortcuts */ public class ThumbnailSearchResultView extends androidx.appcompat.widget.AppCompatImageView implements AllAppsSearchBarController.PayloadResultHandler<Bundle> { Intent mIntent; AllAppsSearchPlugin mPlugin; public ThumbnailSearchResultView(Context context) { super(context); } public ThumbnailSearchResultView(Context context, AttributeSet attrs) { super(context, attrs); } public ThumbnailSearchResultView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } private void handleSelection(int eventType) { Launcher launcher = Launcher.getLauncher(getContext()); launcher.startActivitySafely(this, mIntent, null); SearchTargetEvent event = new SearchTargetEvent( SearchTarget.ItemType.SCREENSHOT, eventType); if (mPlugin != null) { mPlugin.notifySearchTargetEvent(event); } } @Override public void applyAdapterInfo(AdapterItemWithPayload<Bundle> adapterItem) { RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(null, (Bitmap) adapterItem.getPayload().getParcelable("bitmap")); drawable.setCornerRadius(Themes.getDialogCornerRadius(getContext())); setImageDrawable(drawable); mIntent = new Intent(Intent.ACTION_VIEW) .setData(Uri.parse(adapterItem.getPayload().getString("uri"))) .setType("image/*") .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mPlugin = adapterItem.getPlugin(); adapterItem.setSelectionHandler(this::handleSelection); } } src_plugins/com/android/systemui/plugins/shared/SearchTarget.java +43 −2 Original line number Diff line number Diff line Loading @@ -26,14 +26,52 @@ import java.util.List; public class SearchTarget implements Comparable<SearchTarget> { public enum ViewType { /** * Consists of N number of icons. (N: launcher column count) */ TOP_HIT(0), /** * Consists of 1 icon and two subsidiary icons. */ HERO(1), /** * Main/sub/breadcrumb texts are rendered. */ DETAIL(2), /** * Consists of an icon, three detail strings. */ ROW(3), /** * Consists of an icon, three detail strings and a button. */ ROW_WITH_BUTTON(4), /** * Consists of a single slice view */ SLICE(5), /** * Similar to hero section. */ SHORTCUT(6), PEOPLE(7); /** * Person icon and handling app icons are rendered. */ PEOPLE(7), /** * N number of 1x1 ratio thumbnail is rendered. * (current N = 3) */ THUMBNAIL(8); private final int mId; ViewType(int id) { Loading @@ -52,9 +90,12 @@ public class SearchTarget implements Comparable<SearchTarget> { APP(3, "", ViewType.TOP_HIT), APP_HERO(4, "", ViewType.HERO), SHORTCUT(5, "Shortcuts", ViewType.SHORTCUT), PEOPLE(6, "People", ViewType.PEOPLE); PEOPLE(6, "People", ViewType.PEOPLE), SCREENSHOT(7, "Screenshots", ViewType.THUMBNAIL); private final int mId; /** Used to render section title. */ private final String mTitle; private final ViewType mViewType; Loading Loading
res/layout/search_result_thumbnail.xml 0 → 100644 +19 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- 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. --> <com.android.launcher3.views.ThumbnailSearchResultView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="125dp" android:layout_height="125dp"/> No newline at end of file
src/com/android/launcher3/allapps/AllAppsGridAdapter.java +17 −5 Original line number Diff line number Diff line Loading @@ -96,6 +96,8 @@ public class AllAppsGridAdapter extends public static final int VIEW_TYPE_SEARCH_PEOPLE = 1 << 11; public static final int VIEW_TYPE_SEARCH_THUMBNAIL = 1 << 12; // 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; Loading Loading @@ -186,6 +188,7 @@ public class AllAppsGridAdapter extends || viewType == VIEW_TYPE_SEARCH_SLICE || viewType == VIEW_TYPE_SEARCH_ROW || viewType == VIEW_TYPE_SEARCH_PEOPLE || viewType == VIEW_TYPE_SEARCH_THUMBNAIL || viewType == VIEW_TYPE_SEARCH_SHORTCUT; } } Loading Loading @@ -307,15 +310,21 @@ public class AllAppsGridAdapter extends @Override public int getSpanSize(int position) { if (isIconViewType(mApps.getAdapterItems().get(position).viewType)) { return 1; int viewType = mApps.getAdapterItems().get(position).viewType; if (isIconViewType(viewType)) { return 1 * SPAN_MULTIPLIER; } else if (viewType == VIEW_TYPE_SEARCH_THUMBNAIL) { return mAppsPerRow; } else { // Section breaks span the full width return mAppsPerRow; return mAppsPerRow * SPAN_MULTIPLIER; } } } // multiplier to support adapter item column count that is not mAppsPerRow. private static final int SPAN_MULTIPLIER = 3; private final BaseDraggingActivity mLauncher; private final LayoutInflater mLayoutInflater; private final AlphabeticalAppsList mApps; Loading Loading @@ -352,7 +361,7 @@ public class AllAppsGridAdapter extends public void setAppsPerRow(int appsPerRow) { mAppsPerRow = appsPerRow; mGridLayoutMgr.setSpanCount(mAppsPerRow); mGridLayoutMgr.setSpanCount(mAppsPerRow * SPAN_MULTIPLIER); } /** Loading Loading @@ -444,6 +453,9 @@ public class AllAppsGridAdapter extends case VIEW_TYPE_SEARCH_PEOPLE: return new ViewHolder(mLayoutInflater.inflate( R.layout.search_result_people_item, parent, false)); case VIEW_TYPE_SEARCH_THUMBNAIL: return new ViewHolder(mLayoutInflater.inflate( R.layout.search_result_thumbnail, parent, false)); default: throw new RuntimeException("Unexpected view type"); } Loading Loading @@ -525,6 +537,7 @@ public class AllAppsGridAdapter extends case VIEW_TYPE_SEARCH_ROW: case VIEW_TYPE_SEARCH_SHORTCUT: case VIEW_TYPE_SEARCH_PEOPLE: case VIEW_TYPE_SEARCH_THUMBNAIL: PayloadResultHandler payloadResultView = (PayloadResultHandler) holder.itemView; payloadResultView.applyAdapterInfo( (AdapterItemWithPayload) mApps.getAdapterItems().get(position)); Loading Loading @@ -553,7 +566,6 @@ public class AllAppsGridAdapter extends } } @Override public boolean onFailedToRecycleView(ViewHolder holder) { // Always recycle and we will reset the view when it is bound Loading
src/com/android/launcher3/views/ThumbnailSearchResultView.java 0 → 100644 +81 −0 Original line number Diff line number Diff line /* * 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.content.Intent; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; import android.util.AttributeSet; import androidx.core.graphics.drawable.RoundedBitmapDrawable; import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; import com.android.launcher3.Launcher; import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItemWithPayload; import com.android.launcher3.allapps.search.AllAppsSearchBarController; import com.android.launcher3.util.Themes; import com.android.systemui.plugins.AllAppsSearchPlugin; import com.android.systemui.plugins.shared.SearchTarget; import com.android.systemui.plugins.shared.SearchTargetEvent; /** * A view representing a high confidence app search result that includes shortcuts */ public class ThumbnailSearchResultView extends androidx.appcompat.widget.AppCompatImageView implements AllAppsSearchBarController.PayloadResultHandler<Bundle> { Intent mIntent; AllAppsSearchPlugin mPlugin; public ThumbnailSearchResultView(Context context) { super(context); } public ThumbnailSearchResultView(Context context, AttributeSet attrs) { super(context, attrs); } public ThumbnailSearchResultView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } private void handleSelection(int eventType) { Launcher launcher = Launcher.getLauncher(getContext()); launcher.startActivitySafely(this, mIntent, null); SearchTargetEvent event = new SearchTargetEvent( SearchTarget.ItemType.SCREENSHOT, eventType); if (mPlugin != null) { mPlugin.notifySearchTargetEvent(event); } } @Override public void applyAdapterInfo(AdapterItemWithPayload<Bundle> adapterItem) { RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(null, (Bitmap) adapterItem.getPayload().getParcelable("bitmap")); drawable.setCornerRadius(Themes.getDialogCornerRadius(getContext())); setImageDrawable(drawable); mIntent = new Intent(Intent.ACTION_VIEW) .setData(Uri.parse(adapterItem.getPayload().getString("uri"))) .setType("image/*") .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mPlugin = adapterItem.getPlugin(); adapterItem.setSelectionHandler(this::handleSelection); } }
src_plugins/com/android/systemui/plugins/shared/SearchTarget.java +43 −2 Original line number Diff line number Diff line Loading @@ -26,14 +26,52 @@ import java.util.List; public class SearchTarget implements Comparable<SearchTarget> { public enum ViewType { /** * Consists of N number of icons. (N: launcher column count) */ TOP_HIT(0), /** * Consists of 1 icon and two subsidiary icons. */ HERO(1), /** * Main/sub/breadcrumb texts are rendered. */ DETAIL(2), /** * Consists of an icon, three detail strings. */ ROW(3), /** * Consists of an icon, three detail strings and a button. */ ROW_WITH_BUTTON(4), /** * Consists of a single slice view */ SLICE(5), /** * Similar to hero section. */ SHORTCUT(6), PEOPLE(7); /** * Person icon and handling app icons are rendered. */ PEOPLE(7), /** * N number of 1x1 ratio thumbnail is rendered. * (current N = 3) */ THUMBNAIL(8); private final int mId; ViewType(int id) { Loading @@ -52,9 +90,12 @@ public class SearchTarget implements Comparable<SearchTarget> { APP(3, "", ViewType.TOP_HIT), APP_HERO(4, "", ViewType.HERO), SHORTCUT(5, "Shortcuts", ViewType.SHORTCUT), PEOPLE(6, "People", ViewType.PEOPLE); PEOPLE(6, "People", ViewType.PEOPLE), SCREENSHOT(7, "Screenshots", ViewType.THUMBNAIL); private final int mId; /** Used to render section title. */ private final String mTitle; private final ViewType mViewType; Loading