From 2078d3125fd81b3ffe5a797a420bdd9ce3735bc8 Mon Sep 17 00:00:00 2001 From: Matt Casey Date: Fri, 20 May 2022 18:38:16 +0000 Subject: [PATCH] Minimize distance between text and pin in direct share row When the TextView takes up multiple lines, the layout acts as if the full width is used, thus pushing the pin all the way to the left. This change measures the text itself and computes an ideal width for the TextView based upon the line measurements. Test: Visual inspection: pin several targets: single line, first line longer, second line longer, etc. Observe spacing. Bug: 232445263 Change-Id: Id7601c58aae1e28c66c5311ba66b288443d73272 --- .../internal/app/ChooserListAdapter.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/core/java/com/android/internal/app/ChooserListAdapter.java b/core/java/com/android/internal/app/ChooserListAdapter.java index aab1bc3aab5ae..1ec5325623ec1 100644 --- a/core/java/com/android/internal/app/ChooserListAdapter.java +++ b/core/java/com/android/internal/app/ChooserListAdapter.java @@ -36,9 +36,11 @@ import android.os.UserHandle; import android.os.UserManager; import android.provider.DeviceConfig; import android.service.chooser.ChooserTarget; +import android.text.Layout; import android.util.Log; import android.view.View; import android.view.ViewGroup; +import android.widget.TextView; import com.android.internal.R; import com.android.internal.app.ResolverActivity.ResolvedComponentInfo; @@ -102,6 +104,37 @@ public class ChooserListAdapter extends ResolverListAdapter { private AppPredictor mAppPredictor; private AppPredictor.Callback mAppPredictorCallback; + // For pinned direct share labels, if the text spans multiple lines, the TextView will consume + // the full width, even if the characters actually take up less than that. Measure the actual + // line widths and constrain the View's width based upon that so that the pin doesn't end up + // very far from the text. + private final View.OnLayoutChangeListener mPinTextSpacingListener = + new View.OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, + int oldLeft, int oldTop, int oldRight, int oldBottom) { + TextView textView = (TextView) v; + Layout layout = textView.getLayout(); + if (layout != null) { + int textWidth = 0; + for (int line = 0; line < layout.getLineCount(); line++) { + textWidth = Math.max((int) Math.ceil(layout.getLineMax(line)), + textWidth); + } + int desiredWidth = textWidth + textView.getPaddingLeft() + + textView.getPaddingRight(); + if (textView.getWidth() > desiredWidth) { + ViewGroup.LayoutParams params = textView.getLayoutParams(); + params.width = desiredWidth; + textView.setLayoutParams(params); + // Need to wait until layout pass is over before requesting layout. + textView.post(() -> textView.requestLayout()); + } + textView.removeOnLayoutChangeListener(this); + } + } + }; + public ChooserListAdapter(Context context, List payloadIntents, Intent[] initialIntents, List rList, boolean filterLastUsed, ResolverListController resolverListController, @@ -225,6 +258,7 @@ public class ChooserListAdapter extends ResolverListAdapter { @Override protected void onBindView(View view, TargetInfo info, int position) { final ViewHolder holder = (ViewHolder) view.getTag(); + if (info == null) { holder.icon.setImageDrawable( mContext.getDrawable(R.drawable.resolver_icon_placeholder)); @@ -274,6 +308,9 @@ public class ChooserListAdapter extends ResolverListAdapter { holder.itemView.setBackground(holder.defaultItemViewBackground); } + // Always remove the spacing listener, attach as needed to direct share targets below. + holder.text.removeOnLayoutChangeListener(mPinTextSpacingListener); + if (info instanceof MultiDisplayResolveInfo) { // If the target is grouped show an indicator Drawable bkg = mContext.getDrawable(R.drawable.chooser_group_background); @@ -286,6 +323,7 @@ public class ChooserListAdapter extends ResolverListAdapter { Drawable bkg = mContext.getDrawable(R.drawable.chooser_pinned_background); holder.text.setPaddingRelative(bkg.getIntrinsicWidth() /* start */, 0, 0, 0); holder.text.setBackground(bkg); + holder.text.addOnLayoutChangeListener(mPinTextSpacingListener); } else { holder.text.setBackground(null); holder.text.setPaddingRelative(0, 0, 0, 0);