Loading core/java/com/android/internal/app/ChooserTargetActionsDialogFragment.java +77 −35 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import static java.util.stream.Collectors.toList; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AlertDialog.Builder; import android.app.Dialog; import android.app.DialogFragment; import android.content.ComponentName; Loading @@ -34,21 +33,25 @@ import android.content.DialogInterface; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.UserHandle; import android.util.Pair; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; import com.android.internal.R; import com.android.internal.app.chooser.DisplayResolveInfo; import com.android.internal.widget.RecyclerView; import java.util.ArrayList; import java.util.List; import java.util.Optional; /** * Shows a dialog with actions to take on a chooser target. Loading @@ -68,47 +71,86 @@ public class ChooserTargetActionsDialogFragment extends DialogFragment mTargetInfos = targets; } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { /** * Recreate the layout from scratch to match new Sharesheet redlines */ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { // Make the background transparent to show dialog rounding Optional.of(getDialog()).map(Dialog::getWindow) .ifPresent(window -> { window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); }); // Fetch UI details from target info List<Pair<CharSequence, Drawable>> items = mTargetInfos.stream().map(dri -> { return new Pair<>(getItemLabel(dri), getItemIcon(dri)); List<Pair<Drawable, CharSequence>> items = mTargetInfos.stream().map(dri -> { return new Pair<>(getItemIcon(dri), getItemLabel(dri)); }).collect(toList()); View v = inflater.inflate(R.layout.chooser_dialog, container, false); TextView title = v.findViewById(R.id.title); ImageView icon = v.findViewById(R.id.icon); RecyclerView rv = v.findViewById(R.id.listContainer); final ResolveInfoPresentationGetter pg = getProvidingAppPresentationGetter(); return new Builder(getContext()) .setTitle(pg.getLabel()) .setIcon(pg.getIcon(mUserHandle)) .setCancelable(true) .setAdapter(getAdapterForContent(items), this) .create(); } protected ArrayAdapter<Pair<CharSequence, Drawable>> getAdapterForContent( List<Pair<CharSequence, Drawable>> items) { return new ArrayAdapter<Pair<CharSequence, Drawable>>(getContext(), R.layout.chooser_dialog_item, R.id.text, items) { title.setText(pg.getLabel()); icon.setImageDrawable(pg.getIcon(mUserHandle)); rv.setAdapter(new VHAdapter(items)); return v; } class VHAdapter extends RecyclerView.Adapter<VH> { List<Pair<Drawable, CharSequence>> mItems; VHAdapter(List<Pair<Drawable, CharSequence>> items) { mItems = items; } @NonNull @Override public View getView(int position, View convertView, ViewGroup parent) { View v = super.getView(position, convertView, parent); // super recycles views TextView label = v.findViewById(R.id.text); ImageView icon = v.findViewById(R.id.icon); public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { return new VH(LayoutInflater.from(parent.getContext()).inflate( R.layout.chooser_dialog_item, parent, false)); } @Override public void onBindViewHolder(@NonNull VH holder, int position) { holder.bind(mItems.get(position), position); } @Override public int getItemCount() { return mItems.size(); } } Pair<CharSequence, Drawable> pair = getItem(position); label.setText(pair.first); class VH extends RecyclerView.ViewHolder { TextView mLabel; ImageView mIcon; // Hide icon view if one isn't available if (pair.second == null) { icon.setVisibility(View.GONE); VH(@NonNull View itemView) { super(itemView); mLabel = itemView.findViewById(R.id.text); mIcon = itemView.findViewById(R.id.icon); } public void bind(Pair<Drawable, CharSequence> item, int position) { mLabel.setText(item.second); if (item.first == null) { mIcon.setVisibility(View.GONE); } else { icon.setImageDrawable(pair.second); icon.setVisibility(View.VISIBLE); mIcon.setVisibility(View.VISIBLE); mIcon.setImageDrawable(item.first); } return v; itemView.setOnClickListener(v -> onClick(getDialog(), position)); } }; } @Override Loading core/res/res/drawable/chooser_dialog_background.xml 0 → 100644 +21 −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. --> <shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android"> <corners android:radius="?attr/dialogCornerRadius" /> <solid android:color="?attr/colorBackgroundFloating" /> </shape> No newline at end of file core/res/res/layout/chooser_dialog.xml 0 → 100644 +60 −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. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:background="@drawable/chooser_dialog_background" android:orientation="vertical" android:paddingBottom="8dp" android:paddingTop="8dp" android:layout_width="240dp" android:layout_height="wrap_content"> <LinearLayout android:gravity="start|center_vertical" android:paddingStart="16dp" android:paddingEnd="16dp" android:minHeight="56dp" android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/icon" android:layout_marginEnd="16dp" android:layout_width="24dp" android:layout_height="24dp"/> <TextView android:id="@+id/title" android:textSize="16sp" android:textColor="?android:attr/textColorPrimary" android:textAppearance="@android:style/TextAppearance.DeviceDefault.WindowTitle" android:text="App name" android:lines="1" android:ellipsize="end" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> <com.android.internal.widget.RecyclerView xmlns:app="http://schemas.android.com/apk/res-auto" app:layoutManager="com.android.internal.widget.LinearLayoutManager" android:id="@+id/listContainer" android:overScrollMode="never" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout> No newline at end of file core/res/res/layout/chooser_dialog_item.xml +15 −14 Original line number Diff line number Diff line Loading @@ -16,27 +16,28 @@ --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:background="?android:attr/selectableItemBackground" android:clickable="true" android:paddingStart="16dp" android:paddingEnd="16dp" android:orientation="horizontal" android:gravity="start|center_vertical" android:paddingStart="?attr/dialogPreferredPadding" android:paddingEnd="?attr/dialogPreferredPadding" android:minHeight="48dp" android:minHeight="56dp" android:layout_width="match_parent" android:layout_height="match_parent"> android:layout_height="wrap_content"> <!-- Icon and text aligns with aligns with alert_dialog_title_material --> <ImageView android:id="@+id/icon" android:tint="?android:attr/textColorAlertDialogListItem" android:padding="4dp" android:layout_marginEnd="8dp" android:layout_width="32dp" android:layout_height="32dp"/> android:alpha="0.54" android:tint="?android:attr/textColorPrimary" android:layout_marginEnd="16dp" android:layout_width="24dp" android:layout_height="24dp"/> <!-- Using text style from select_dialog_item_material --> <TextView android:id="@+id/text" android:textAppearance="?android:attr/textAppearanceListItemSmall" android:textColor="?android:attr/textColorAlertDialogListItem" android:lines="1" android:textAppearance="?android:attr/textAppearanceSmall" android:textColor="?android:attr/textColorPrimary" android:textSize="16sp" android:maxLines="2" android:ellipsize="end" android:layout_width="wrap_content" android:layout_height="wrap_content"/> Loading core/res/res/values/symbols.xml +2 −0 Original line number Diff line number Diff line Loading @@ -3838,7 +3838,9 @@ <java-symbol type="string" name="config_factoryResetPackage" /> <java-symbol type="array" name="config_highRefreshRateBlacklist" /> <java-symbol type="layout" name="chooser_dialog" /> <java-symbol type="layout" name="chooser_dialog_item" /> <java-symbol type="drawable" name="chooser_dialog_background" /> <java-symbol type="id" name="chooser_copy_button" /> <java-symbol type="layout" name="chooser_action_button" /> <java-symbol type="dimen" name="chooser_action_button_icon_size" /> Loading Loading
core/java/com/android/internal/app/ChooserTargetActionsDialogFragment.java +77 −35 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import static java.util.stream.Collectors.toList; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AlertDialog.Builder; import android.app.Dialog; import android.app.DialogFragment; import android.content.ComponentName; Loading @@ -34,21 +33,25 @@ import android.content.DialogInterface; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.UserHandle; import android.util.Pair; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; import com.android.internal.R; import com.android.internal.app.chooser.DisplayResolveInfo; import com.android.internal.widget.RecyclerView; import java.util.ArrayList; import java.util.List; import java.util.Optional; /** * Shows a dialog with actions to take on a chooser target. Loading @@ -68,47 +71,86 @@ public class ChooserTargetActionsDialogFragment extends DialogFragment mTargetInfos = targets; } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { /** * Recreate the layout from scratch to match new Sharesheet redlines */ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { // Make the background transparent to show dialog rounding Optional.of(getDialog()).map(Dialog::getWindow) .ifPresent(window -> { window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); }); // Fetch UI details from target info List<Pair<CharSequence, Drawable>> items = mTargetInfos.stream().map(dri -> { return new Pair<>(getItemLabel(dri), getItemIcon(dri)); List<Pair<Drawable, CharSequence>> items = mTargetInfos.stream().map(dri -> { return new Pair<>(getItemIcon(dri), getItemLabel(dri)); }).collect(toList()); View v = inflater.inflate(R.layout.chooser_dialog, container, false); TextView title = v.findViewById(R.id.title); ImageView icon = v.findViewById(R.id.icon); RecyclerView rv = v.findViewById(R.id.listContainer); final ResolveInfoPresentationGetter pg = getProvidingAppPresentationGetter(); return new Builder(getContext()) .setTitle(pg.getLabel()) .setIcon(pg.getIcon(mUserHandle)) .setCancelable(true) .setAdapter(getAdapterForContent(items), this) .create(); } protected ArrayAdapter<Pair<CharSequence, Drawable>> getAdapterForContent( List<Pair<CharSequence, Drawable>> items) { return new ArrayAdapter<Pair<CharSequence, Drawable>>(getContext(), R.layout.chooser_dialog_item, R.id.text, items) { title.setText(pg.getLabel()); icon.setImageDrawable(pg.getIcon(mUserHandle)); rv.setAdapter(new VHAdapter(items)); return v; } class VHAdapter extends RecyclerView.Adapter<VH> { List<Pair<Drawable, CharSequence>> mItems; VHAdapter(List<Pair<Drawable, CharSequence>> items) { mItems = items; } @NonNull @Override public View getView(int position, View convertView, ViewGroup parent) { View v = super.getView(position, convertView, parent); // super recycles views TextView label = v.findViewById(R.id.text); ImageView icon = v.findViewById(R.id.icon); public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { return new VH(LayoutInflater.from(parent.getContext()).inflate( R.layout.chooser_dialog_item, parent, false)); } @Override public void onBindViewHolder(@NonNull VH holder, int position) { holder.bind(mItems.get(position), position); } @Override public int getItemCount() { return mItems.size(); } } Pair<CharSequence, Drawable> pair = getItem(position); label.setText(pair.first); class VH extends RecyclerView.ViewHolder { TextView mLabel; ImageView mIcon; // Hide icon view if one isn't available if (pair.second == null) { icon.setVisibility(View.GONE); VH(@NonNull View itemView) { super(itemView); mLabel = itemView.findViewById(R.id.text); mIcon = itemView.findViewById(R.id.icon); } public void bind(Pair<Drawable, CharSequence> item, int position) { mLabel.setText(item.second); if (item.first == null) { mIcon.setVisibility(View.GONE); } else { icon.setImageDrawable(pair.second); icon.setVisibility(View.VISIBLE); mIcon.setVisibility(View.VISIBLE); mIcon.setImageDrawable(item.first); } return v; itemView.setOnClickListener(v -> onClick(getDialog(), position)); } }; } @Override Loading
core/res/res/drawable/chooser_dialog_background.xml 0 → 100644 +21 −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. --> <shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android"> <corners android:radius="?attr/dialogCornerRadius" /> <solid android:color="?attr/colorBackgroundFloating" /> </shape> No newline at end of file
core/res/res/layout/chooser_dialog.xml 0 → 100644 +60 −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. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:background="@drawable/chooser_dialog_background" android:orientation="vertical" android:paddingBottom="8dp" android:paddingTop="8dp" android:layout_width="240dp" android:layout_height="wrap_content"> <LinearLayout android:gravity="start|center_vertical" android:paddingStart="16dp" android:paddingEnd="16dp" android:minHeight="56dp" android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/icon" android:layout_marginEnd="16dp" android:layout_width="24dp" android:layout_height="24dp"/> <TextView android:id="@+id/title" android:textSize="16sp" android:textColor="?android:attr/textColorPrimary" android:textAppearance="@android:style/TextAppearance.DeviceDefault.WindowTitle" android:text="App name" android:lines="1" android:ellipsize="end" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> <com.android.internal.widget.RecyclerView xmlns:app="http://schemas.android.com/apk/res-auto" app:layoutManager="com.android.internal.widget.LinearLayoutManager" android:id="@+id/listContainer" android:overScrollMode="never" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout> No newline at end of file
core/res/res/layout/chooser_dialog_item.xml +15 −14 Original line number Diff line number Diff line Loading @@ -16,27 +16,28 @@ --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:background="?android:attr/selectableItemBackground" android:clickable="true" android:paddingStart="16dp" android:paddingEnd="16dp" android:orientation="horizontal" android:gravity="start|center_vertical" android:paddingStart="?attr/dialogPreferredPadding" android:paddingEnd="?attr/dialogPreferredPadding" android:minHeight="48dp" android:minHeight="56dp" android:layout_width="match_parent" android:layout_height="match_parent"> android:layout_height="wrap_content"> <!-- Icon and text aligns with aligns with alert_dialog_title_material --> <ImageView android:id="@+id/icon" android:tint="?android:attr/textColorAlertDialogListItem" android:padding="4dp" android:layout_marginEnd="8dp" android:layout_width="32dp" android:layout_height="32dp"/> android:alpha="0.54" android:tint="?android:attr/textColorPrimary" android:layout_marginEnd="16dp" android:layout_width="24dp" android:layout_height="24dp"/> <!-- Using text style from select_dialog_item_material --> <TextView android:id="@+id/text" android:textAppearance="?android:attr/textAppearanceListItemSmall" android:textColor="?android:attr/textColorAlertDialogListItem" android:lines="1" android:textAppearance="?android:attr/textAppearanceSmall" android:textColor="?android:attr/textColorPrimary" android:textSize="16sp" android:maxLines="2" android:ellipsize="end" android:layout_width="wrap_content" android:layout_height="wrap_content"/> Loading
core/res/res/values/symbols.xml +2 −0 Original line number Diff line number Diff line Loading @@ -3838,7 +3838,9 @@ <java-symbol type="string" name="config_factoryResetPackage" /> <java-symbol type="array" name="config_highRefreshRateBlacklist" /> <java-symbol type="layout" name="chooser_dialog" /> <java-symbol type="layout" name="chooser_dialog_item" /> <java-symbol type="drawable" name="chooser_dialog_background" /> <java-symbol type="id" name="chooser_copy_button" /> <java-symbol type="layout" name="chooser_action_button" /> <java-symbol type="dimen" name="chooser_action_button_icon_size" /> Loading