Loading res/layout/search_result_people_item.xml 0 → 100644 +62 −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.SearchResultPeopleView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:gravity="center_vertical" android:layout_height="wrap_content" android:padding="8dp" android:orientation="horizontal"> <View android:id="@+id/icon" android:layout_marginRight="8dp" android:layout_width="@dimen/default_icon_bitmap_size" android:layout_height="@dimen/default_icon_bitmap_size" /> <TextView android:layout_width="0dp" android:textColor="?android:attr/textColorPrimary" android:id="@+id/title" android:layout_height="wrap_content" android:layout_weight="1" /> <ImageButton android:id="@+id/provider_0" android:scaleType="fitCenter" android:adjustViewBounds="true" android:layout_margin="5dp" android:background="?android:attr/selectableItemBackground" android:layout_width="@dimen/default_icon_bitmap_size" android:layout_height="@dimen/default_icon_bitmap_size" /> <ImageButton android:id="@+id/provider_1" android:layout_margin="5dp" android:scaleType="fitCenter" android:adjustViewBounds="true" android:background="?android:attr/selectableItemBackground" android:layout_width="@dimen/default_icon_bitmap_size" android:layout_height="@dimen/default_icon_bitmap_size" /> <ImageButton android:id="@+id/provider_2" android:layout_margin="5dp" android:scaleType="fitCenter" android:adjustViewBounds="true" android:background="?android:attr/selectableItemBackground" android:layout_width="@dimen/default_icon_bitmap_size" android:layout_height="@dimen/default_icon_bitmap_size" /> </com.android.launcher3.views.SearchResultPeopleView> No newline at end of file src/com/android/launcher3/allapps/AllAppsGridAdapter.java +7 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,8 @@ public class AllAppsGridAdapter extends public static final int VIEW_TYPE_SEARCH_SHORTCUT = 1 << 10; public static final int VIEW_TYPE_SEARCH_PEOPLE = 1 << 11; // 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 @@ -182,6 +184,7 @@ public class AllAppsGridAdapter extends || viewType == VIEW_TYPE_SEARCH_ROW_WITH_BUTTON || viewType == VIEW_TYPE_SEARCH_SLICE || viewType == VIEW_TYPE_SEARCH_ROW || viewType == VIEW_TYPE_SEARCH_PEOPLE || viewType == VIEW_TYPE_SEARCH_SHORTCUT; } } Loading Loading @@ -432,6 +435,9 @@ public class AllAppsGridAdapter extends case VIEW_TYPE_SEARCH_SHORTCUT: return new ViewHolder(mLayoutInflater.inflate( R.layout.search_result_shortcut, parent, false)); case VIEW_TYPE_SEARCH_PEOPLE: return new ViewHolder(mLayoutInflater.inflate( R.layout.search_result_people_item, parent, false)); default: throw new RuntimeException("Unexpected view type"); } Loading Loading @@ -475,6 +481,7 @@ public class AllAppsGridAdapter extends case VIEW_TYPE_SEARCH_HERO_APP: case VIEW_TYPE_SEARCH_ROW: case VIEW_TYPE_SEARCH_SHORTCUT: case VIEW_TYPE_SEARCH_PEOPLE: PayloadResultHandler payloadResultView = (PayloadResultHandler) holder.itemView; payloadResultView.applyAdapterInfo( (AdapterItemWithPayload) mApps.getAdapterItems().get(position)); Loading src/com/android/launcher3/views/SearchResultPeopleView.java 0 → 100644 +156 −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 static android.content.Intent.URI_ALLOW_UNSAFE; import static android.content.Intent.URI_ANDROID_APP_SCHEME; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.util.AttributeSet; import android.view.View; import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.Nullable; import androidx.core.graphics.drawable.RoundedBitmapDrawable; import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.allapps.AllAppsGridAdapter; import com.android.launcher3.allapps.search.AllAppsSearchBarController; import com.android.launcher3.util.Themes; import java.net.URISyntaxException; import java.util.ArrayList; /** * A view representing a single people search result in all apps */ public class SearchResultPeopleView extends LinearLayout implements AllAppsSearchBarController.PayloadResultHandler<Bundle> { private final int mIconSize; private final int mButtonSize; private final PackageManager mPackageManager; View mIconView; TextView mTitleView; ImageButton[] mProviderButtons = new ImageButton[3]; public SearchResultPeopleView(Context context) { this(context, null, 0); } public SearchResultPeopleView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public SearchResultPeopleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); DeviceProfile deviceProfile = Launcher.getLauncher(getContext()).getDeviceProfile(); mPackageManager = getContext().getPackageManager(); mIconSize = deviceProfile.iconSizePx; mButtonSize = (int) (deviceProfile.iconSizePx / 1.5f); } @Override protected void onFinishInflate() { super.onFinishInflate(); mIconView = findViewById(R.id.icon); mIconView.getLayoutParams().height = mIconSize; mIconView.getLayoutParams().width = mIconSize; mTitleView = findViewById(R.id.title); mProviderButtons[0] = findViewById(R.id.provider_0); mProviderButtons[1] = findViewById(R.id.provider_1); mProviderButtons[2] = findViewById(R.id.provider_2); for (ImageButton button : mProviderButtons) { button.getLayoutParams().width = mButtonSize; button.getLayoutParams().height = mButtonSize; } setOnClickListener(v -> handleSelection()); } @Override public void applyAdapterInfo( AllAppsGridAdapter.AdapterItemWithPayload<Bundle> adapterItemWithPayload) { Launcher launcher = Launcher.getLauncher(getContext()); Bundle payload = adapterItemWithPayload.getPayload(); mTitleView.setText(payload.getString("title")); mContactUri = payload.getParcelable("contact_uri"); Bitmap icon = payload.getParcelable("icon"); if (icon != null) { RoundedBitmapDrawable d = RoundedBitmapDrawableFactory.create(getResources(), icon); float radius = Themes.getDialogCornerRadius(getContext()); d.setCornerRadius(radius); d.setBounds(0, 0, mIconSize, mIconSize); BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), Bitmap.createScaledBitmap(icon, mIconSize, mIconSize, false)); mIconView.setBackground(d); } ArrayList<Bundle> providers = payload.getParcelableArrayList("providers"); for (int i = 0; i < mProviderButtons.length; i++) { ImageButton button = mProviderButtons[i]; if (providers != null && i < providers.size()) { try { Bundle provider = providers.get(i); Intent intent = Intent.parseUri(provider.getString("intent_uri_str"), URI_ANDROID_APP_SCHEME | URI_ALLOW_UNSAFE); String pkg = provider.getString("package_name"); button.setOnClickListener(b -> launcher.startActivitySafely(b, intent, null)); UI_HELPER_EXECUTOR.post(() -> { try { ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo( pkg, 0); Drawable appIcon = applicationInfo.loadIcon(mPackageManager); button.setImageDrawable(appIcon); } catch (PackageManager.NameNotFoundException ignored) { } }); } catch (URISyntaxException ex) { button.setVisibility(GONE); } } else { button.setVisibility(GONE); } } adapterItemWithPayload.setSelectionHandler(this::handleSelection); } Uri mContactUri; private void handleSelection() { if (mContactUri != null) { Launcher launcher = Launcher.getLauncher(getContext()); launcher.startActivitySafely(this, new Intent(Intent.ACTION_VIEW, mContactUri).setFlags( Intent.FLAG_ACTIVITY_NEW_TASK), null); } } } Loading
res/layout/search_result_people_item.xml 0 → 100644 +62 −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.SearchResultPeopleView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:gravity="center_vertical" android:layout_height="wrap_content" android:padding="8dp" android:orientation="horizontal"> <View android:id="@+id/icon" android:layout_marginRight="8dp" android:layout_width="@dimen/default_icon_bitmap_size" android:layout_height="@dimen/default_icon_bitmap_size" /> <TextView android:layout_width="0dp" android:textColor="?android:attr/textColorPrimary" android:id="@+id/title" android:layout_height="wrap_content" android:layout_weight="1" /> <ImageButton android:id="@+id/provider_0" android:scaleType="fitCenter" android:adjustViewBounds="true" android:layout_margin="5dp" android:background="?android:attr/selectableItemBackground" android:layout_width="@dimen/default_icon_bitmap_size" android:layout_height="@dimen/default_icon_bitmap_size" /> <ImageButton android:id="@+id/provider_1" android:layout_margin="5dp" android:scaleType="fitCenter" android:adjustViewBounds="true" android:background="?android:attr/selectableItemBackground" android:layout_width="@dimen/default_icon_bitmap_size" android:layout_height="@dimen/default_icon_bitmap_size" /> <ImageButton android:id="@+id/provider_2" android:layout_margin="5dp" android:scaleType="fitCenter" android:adjustViewBounds="true" android:background="?android:attr/selectableItemBackground" android:layout_width="@dimen/default_icon_bitmap_size" android:layout_height="@dimen/default_icon_bitmap_size" /> </com.android.launcher3.views.SearchResultPeopleView> No newline at end of file
src/com/android/launcher3/allapps/AllAppsGridAdapter.java +7 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,8 @@ public class AllAppsGridAdapter extends public static final int VIEW_TYPE_SEARCH_SHORTCUT = 1 << 10; public static final int VIEW_TYPE_SEARCH_PEOPLE = 1 << 11; // 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 @@ -182,6 +184,7 @@ public class AllAppsGridAdapter extends || viewType == VIEW_TYPE_SEARCH_ROW_WITH_BUTTON || viewType == VIEW_TYPE_SEARCH_SLICE || viewType == VIEW_TYPE_SEARCH_ROW || viewType == VIEW_TYPE_SEARCH_PEOPLE || viewType == VIEW_TYPE_SEARCH_SHORTCUT; } } Loading Loading @@ -432,6 +435,9 @@ public class AllAppsGridAdapter extends case VIEW_TYPE_SEARCH_SHORTCUT: return new ViewHolder(mLayoutInflater.inflate( R.layout.search_result_shortcut, parent, false)); case VIEW_TYPE_SEARCH_PEOPLE: return new ViewHolder(mLayoutInflater.inflate( R.layout.search_result_people_item, parent, false)); default: throw new RuntimeException("Unexpected view type"); } Loading Loading @@ -475,6 +481,7 @@ public class AllAppsGridAdapter extends case VIEW_TYPE_SEARCH_HERO_APP: case VIEW_TYPE_SEARCH_ROW: case VIEW_TYPE_SEARCH_SHORTCUT: case VIEW_TYPE_SEARCH_PEOPLE: PayloadResultHandler payloadResultView = (PayloadResultHandler) holder.itemView; payloadResultView.applyAdapterInfo( (AdapterItemWithPayload) mApps.getAdapterItems().get(position)); Loading
src/com/android/launcher3/views/SearchResultPeopleView.java 0 → 100644 +156 −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 static android.content.Intent.URI_ALLOW_UNSAFE; import static android.content.Intent.URI_ANDROID_APP_SCHEME; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.util.AttributeSet; import android.view.View; import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.Nullable; import androidx.core.graphics.drawable.RoundedBitmapDrawable; import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.allapps.AllAppsGridAdapter; import com.android.launcher3.allapps.search.AllAppsSearchBarController; import com.android.launcher3.util.Themes; import java.net.URISyntaxException; import java.util.ArrayList; /** * A view representing a single people search result in all apps */ public class SearchResultPeopleView extends LinearLayout implements AllAppsSearchBarController.PayloadResultHandler<Bundle> { private final int mIconSize; private final int mButtonSize; private final PackageManager mPackageManager; View mIconView; TextView mTitleView; ImageButton[] mProviderButtons = new ImageButton[3]; public SearchResultPeopleView(Context context) { this(context, null, 0); } public SearchResultPeopleView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public SearchResultPeopleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); DeviceProfile deviceProfile = Launcher.getLauncher(getContext()).getDeviceProfile(); mPackageManager = getContext().getPackageManager(); mIconSize = deviceProfile.iconSizePx; mButtonSize = (int) (deviceProfile.iconSizePx / 1.5f); } @Override protected void onFinishInflate() { super.onFinishInflate(); mIconView = findViewById(R.id.icon); mIconView.getLayoutParams().height = mIconSize; mIconView.getLayoutParams().width = mIconSize; mTitleView = findViewById(R.id.title); mProviderButtons[0] = findViewById(R.id.provider_0); mProviderButtons[1] = findViewById(R.id.provider_1); mProviderButtons[2] = findViewById(R.id.provider_2); for (ImageButton button : mProviderButtons) { button.getLayoutParams().width = mButtonSize; button.getLayoutParams().height = mButtonSize; } setOnClickListener(v -> handleSelection()); } @Override public void applyAdapterInfo( AllAppsGridAdapter.AdapterItemWithPayload<Bundle> adapterItemWithPayload) { Launcher launcher = Launcher.getLauncher(getContext()); Bundle payload = adapterItemWithPayload.getPayload(); mTitleView.setText(payload.getString("title")); mContactUri = payload.getParcelable("contact_uri"); Bitmap icon = payload.getParcelable("icon"); if (icon != null) { RoundedBitmapDrawable d = RoundedBitmapDrawableFactory.create(getResources(), icon); float radius = Themes.getDialogCornerRadius(getContext()); d.setCornerRadius(radius); d.setBounds(0, 0, mIconSize, mIconSize); BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), Bitmap.createScaledBitmap(icon, mIconSize, mIconSize, false)); mIconView.setBackground(d); } ArrayList<Bundle> providers = payload.getParcelableArrayList("providers"); for (int i = 0; i < mProviderButtons.length; i++) { ImageButton button = mProviderButtons[i]; if (providers != null && i < providers.size()) { try { Bundle provider = providers.get(i); Intent intent = Intent.parseUri(provider.getString("intent_uri_str"), URI_ANDROID_APP_SCHEME | URI_ALLOW_UNSAFE); String pkg = provider.getString("package_name"); button.setOnClickListener(b -> launcher.startActivitySafely(b, intent, null)); UI_HELPER_EXECUTOR.post(() -> { try { ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo( pkg, 0); Drawable appIcon = applicationInfo.loadIcon(mPackageManager); button.setImageDrawable(appIcon); } catch (PackageManager.NameNotFoundException ignored) { } }); } catch (URISyntaxException ex) { button.setVisibility(GONE); } } else { button.setVisibility(GONE); } } adapterItemWithPayload.setSelectionHandler(this::handleSelection); } Uri mContactUri; private void handleSelection() { if (mContactUri != null) { Launcher launcher = Launcher.getLauncher(getContext()); launcher.startActivitySafely(this, new Intent(Intent.ACTION_VIEW, mContactUri).setFlags( Intent.FLAG_ACTIVITY_NEW_TASK), null); } } }