diff options
| author | DennySPB <dennyspb@gmail.com> | 2018-03-22 16:51:38 +0300 |
|---|---|---|
| committer | Semavi Ulusoy <doc.divxm@gmail.com> | 2022-09-13 01:01:38 +0300 |
| commit | 5e143d89d7f34ffb882de2bef80420d2a72abef3 (patch) | |
| tree | bb3a87e127dddea12c88d9dd9498a845b4544305 | |
| parent | 3109f352d200feab7a3951fae22c819199c8f9ed (diff) | |
Improve contatcts layout
added custom TextAutoResizer
Change-Id: I257c7db64972e5a502f6e2eacd01ebebb7e106a6
Signed-off-by: DennySPB <dennyspb@gmail.com>
Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>
5 files changed, 318 insertions, 13 deletions
diff --git a/java/com/android/incallui/answer/impl/res/layout/fragment_incoming_call.xml b/java/com/android/incallui/answer/impl/res/layout/fragment_incoming_call.xml index d6966ec57..b49e41408 100644 --- a/java/com/android/incallui/answer/impl/res/layout/fragment_incoming_call.xml +++ b/java/com/android/incallui/answer/impl/res/layout/fragment_incoming_call.xml @@ -96,19 +96,21 @@ <!-- We have to keep deprecated singleLine to allow long text being truncated with ellipses. a bug --> - <com.android.incallui.autoresizetext.AutoResizeTextView + + <com.android.incallui.autoresizetext.CustomAutoResizeTextView android:id="@id/contactgrid_contact_name" android:layout_width="match_parent" android:layout_height="72dp" android:layout_marginBottom="8dp" android:layout_marginStart="24dp" android:layout_marginEnd="24dp" - android:singleLine="true" + android:gravity="center" + android:ellipsize="end" + android:maxLines="2" + android:singleLine="false" android:textAppearance="@style/Dialer.Incall.TextAppearance.Large" android:textSize="@dimen/answer_contact_name_text_size" - app:autoResizeText_minTextSize="@dimen/answer_contact_name_min_size" - tools:ignore="Deprecated" - tools:text="Jake Peralta"/> + app:resizing_text_min_size="@dimen/answer_contact_name_min_size"/> <include android:id="@id/contactgrid_bottom_row" diff --git a/java/com/android/incallui/autoresizetext/CustomAutoResizeTextView.java b/java/com/android/incallui/autoresizetext/CustomAutoResizeTextView.java new file mode 100644 index 000000000..3ce872d16 --- /dev/null +++ b/java/com/android/incallui/autoresizetext/CustomAutoResizeTextView.java @@ -0,0 +1,297 @@ +package com.android.incallui.autoresizetext; + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.res.Resources; +import android.graphics.RectF; +import android.os.Build; +import android.text.Layout.Alignment; +import android.text.StaticLayout; +import android.text.TextPaint; +import android.util.AttributeSet; +import android.util.SparseIntArray; +import android.util.TypedValue; +import android.widget.TextView; + +public class CustomAutoResizeTextView extends TextView { +private interface SizeTester { + /** + * + * @param suggestedSize + * Size of text to be tested + * @param availableSpace + * available space in which text must fit + * @return an integer < 0 if after applying {@code suggestedSize} to + * text, it takes less space than {@code availableSpace}, > 0 + * otherwise + */ + public int onTestSize(int suggestedSize, RectF availableSpace); +} + +private RectF mTextRect = new RectF(); + +private RectF mAvailableSpaceRect; + +private SparseIntArray mTextCachedSizes; + +private TextPaint mPaint; + +private float mMaxTextSize; + +private float mSpacingMult = 1.0f; + +private float mSpacingAdd = 0.0f; + +private float mMinTextSize = 20; + +private int mWidthLimit; + +private static final int NO_LINE_LIMIT = -1; +private int mMaxLines; + +private boolean mEnableSizeCache = true; +private boolean mInitiallized; + +public CustomAutoResizeTextView(Context context) { + super(context); + initialize(); +} + +public CustomAutoResizeTextView(Context context, AttributeSet attrs) { + super(context, attrs); + initialize(); +} + +public CustomAutoResizeTextView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + initialize(); +} + +private void initialize() { + mPaint = new TextPaint(getPaint()); + mMaxTextSize = getTextSize(); + mAvailableSpaceRect = new RectF(); + mTextCachedSizes = new SparseIntArray(); + if (mMaxLines == 0) { + // no value was assigned during construction + mMaxLines = NO_LINE_LIMIT; + } + mInitiallized = true; +} + +@Override +public void setText(final CharSequence text, BufferType type) { + super.setText(text, type); + if (text == null) return; + adjustTextSize(text.toString()); +} + +@Override +public void setTextSize(float size) { + mMaxTextSize = size; + mTextCachedSizes.clear(); + adjustTextSize(getText().toString()); +} + +@Override +public void setMaxLines(int maxlines) { + super.setMaxLines(maxlines); + mMaxLines = maxlines; + reAdjust(); +} + +public int getMaxLines() { + return mMaxLines; +} + +@Override +public void setSingleLine() { + super.setSingleLine(); + mMaxLines = 1; + reAdjust(); +} + +@Override +public void setSingleLine(boolean singleLine) { + super.setSingleLine(singleLine); + if (singleLine) { + mMaxLines = 1; + } else { + mMaxLines = NO_LINE_LIMIT; + } + reAdjust(); +} + +@Override +public void setLines(int lines) { + super.setLines(lines); + mMaxLines = lines; + reAdjust(); +} + +@Override +public void setTextSize(int unit, float size) { + Context c = getContext(); + Resources r; + + if (c == null) + r = Resources.getSystem(); + else + r = c.getResources(); + mMaxTextSize = TypedValue.applyDimension(unit, size, + r.getDisplayMetrics()); + mTextCachedSizes.clear(); + adjustTextSize(getText().toString()); +} + +@Override +public void setLineSpacing(float add, float mult) { + super.setLineSpacing(add, mult); + mSpacingMult = mult; + mSpacingAdd = add; +} + +/** + * Set the lower text size limit and invalidate the view + * + * @param minTextSize + */ +public void setMinTextSize(float minTextSize) { + mMinTextSize = minTextSize; + reAdjust(); +} + +private void reAdjust() { + adjustTextSize(getText().toString()); +} + +private void adjustTextSize(String string) { + if (!mInitiallized) { + return; + } + int startSize = (int) mMinTextSize; + int heightLimit = getMeasuredHeight() - getCompoundPaddingBottom() + - getCompoundPaddingTop(); + mWidthLimit = getMeasuredWidth() - getCompoundPaddingLeft() + - getCompoundPaddingRight(); + mAvailableSpaceRect.right = mWidthLimit; + mAvailableSpaceRect.bottom = heightLimit; + super.setTextSize( + TypedValue.COMPLEX_UNIT_PX, + efficientTextSizeSearch(startSize, (int) mMaxTextSize, + mSizeTester, mAvailableSpaceRect)); +} + +private final SizeTester mSizeTester = new SizeTester() { + @TargetApi(Build.VERSION_CODES.JELLY_BEAN) + @Override + public int onTestSize(int suggestedSize, RectF availableSPace) { + mPaint.setTextSize(suggestedSize); + String text = getText().toString(); + boolean singleline = getMaxLines() == 1; + if (singleline) { + mTextRect.bottom = mPaint.getFontSpacing(); + mTextRect.right = mPaint.measureText(text); + } else { + StaticLayout layout = new StaticLayout(text, mPaint, + mWidthLimit, Alignment.ALIGN_NORMAL, mSpacingMult, + mSpacingAdd, true); + // return early if we have more lines + if (getMaxLines() != NO_LINE_LIMIT + && layout.getLineCount() > getMaxLines()) { + return 1; + } + mTextRect.bottom = layout.getHeight(); + int maxWidth = -1; + for (int i = 0; i < layout.getLineCount(); i++) { + if (maxWidth < layout.getLineWidth(i)) { + maxWidth = (int) layout.getLineWidth(i); + } + } + mTextRect.right = maxWidth; + } + + mTextRect.offsetTo(0, 0); + if (availableSPace.contains(mTextRect)) { + // may be too small, don't worry we will find the best match + return -1; + } else { + // too big + return 1; + } + } +}; + +/** + * Enables or disables size caching, enabling it will improve performance + * where you are animating a value inside TextView. This stores the font + * size against getText().length() Be careful though while enabling it as 0 + * takes more space than 1 on some fonts and so on. + * + * @param enable + * enable font size caching + */ +public void enableSizeCache(boolean enable) { + mEnableSizeCache = enable; + mTextCachedSizes.clear(); + adjustTextSize(getText().toString()); +} + +private int efficientTextSizeSearch(int start, int end, + SizeTester sizeTester, RectF availableSpace) { + if (!mEnableSizeCache) { + return binarySearch(start, end, sizeTester, availableSpace); + } + String text = getText().toString(); + int key = text == null ? 0 : text.length(); + int size = mTextCachedSizes.get(key); + if (size != 0) { + return size; + } + size = binarySearch(start, end, sizeTester, availableSpace); + mTextCachedSizes.put(key, size); + return size; +} + +private static int binarySearch(int start, int end, SizeTester sizeTester, + RectF availableSpace) { + int lastBest = start; + int lo = start; + int hi = end - 1; + int mid = 0; + while (lo <= hi) { + mid = (lo + hi) >>> 1; + int midValCmp = sizeTester.onTestSize(mid, availableSpace); + if (midValCmp < 0) { + lastBest = lo; + lo = mid + 1; + } else if (midValCmp > 0) { + hi = mid - 1; + lastBest = hi; + } else { + return mid; + } + } + // make sure to return last best + // this is what should always be returned + return lastBest; + +} + +@Override +protected void onTextChanged(final CharSequence text, final int start, + final int before, final int after) { + super.onTextChanged(text, start, before, after); + reAdjust(); +} + +@Override +protected void onSizeChanged(int width, int height, int oldwidth, + int oldheight) { + mTextCachedSizes.clear(); + super.onSizeChanged(width, height, oldwidth, oldheight); + if (width != oldwidth || height != oldheight) { + reAdjust(); + } +} +}
\ No newline at end of file diff --git a/java/com/android/incallui/contactgrid/ContactGridManager.java b/java/com/android/incallui/contactgrid/ContactGridManager.java index f39e9ef24..894262f00 100644 --- a/java/com/android/incallui/contactgrid/ContactGridManager.java +++ b/java/com/android/incallui/contactgrid/ContactGridManager.java @@ -300,10 +300,10 @@ public class ContactGridManager { // Set direction of the name field int nameDirection = View.TEXT_DIRECTION_INHERIT; - boolean singleLine = true; + boolean singleLine = false; if (primaryInfo.nameIsNumber()) { nameDirection = View.TEXT_DIRECTION_LTR; - singleLine = false; + singleLine = true; } contactNameTextView.setTextDirection(nameDirection); contactNameTextView.setSingleLine(singleLine); diff --git a/java/com/android/incallui/incall/impl/CheckableLabeledButton.java b/java/com/android/incallui/incall/impl/CheckableLabeledButton.java index 616e9924b..89b892ea9 100644 --- a/java/com/android/incallui/incall/impl/CheckableLabeledButton.java +++ b/java/com/android/incallui/incall/impl/CheckableLabeledButton.java @@ -126,7 +126,8 @@ public class CheckableLabeledButton extends LinearLayout implements Checkable { labelView.setLayoutParams(labelParams); labelView.setTextAppearance(R.style.Dialer_Incall_TextAppearance_Label); labelView.setText(labelText); - labelView.setSingleLine(); + labelView.setSingleLine(false); + labelView.setMaxLines(2); labelView.setMaxEms(9); labelView.setEllipsize(TruncateAt.END); labelView.setGravity(Gravity.CENTER); diff --git a/java/com/android/incallui/video/impl/res/layout/video_contact_grid.xml b/java/com/android/incallui/video/impl/res/layout/video_contact_grid.xml index 56797d92e..f97523fda 100644 --- a/java/com/android/incallui/video/impl/res/layout/video_contact_grid.xml +++ b/java/com/android/incallui/video/impl/res/layout/video_contact_grid.xml @@ -30,13 +30,18 @@ <!-- We have to keep deprecated singleLine to allow long text being truncated with ellipses. a bug --> - <com.android.incallui.autoresizetext.AutoResizeTextView + <com.android.incallui.autoresizetext.CustomAutoResizeTextView android:id="@id/contactgrid_contact_name" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:singleLine="true" + android:layout_width="match_parent" + android:layout_height="72dp" + android:layout_marginStart="24dp" + android:layout_marginEnd="24dp" + android:gravity="center" + android:ellipsize="end" + android:maxLines="2" + android:singleLine="false" android:textAppearance="@style/Dialer.Incall.TextAppearance.Large" - app:autoResizeText_minTextSize="28sp" + app:resizing_text_min_size="28sp" tools:text="Jake Peralta" tools:ignore="Deprecated"/> |
