diff --git a/src/org/thoughtcrime/securesms/components/emoji/EmojiTextView.java b/src/org/thoughtcrime/securesms/components/emoji/EmojiTextView.java index 47cebbdfd9..36e001405b 100644 --- a/src/org/thoughtcrime/securesms/components/emoji/EmojiTextView.java +++ b/src/org/thoughtcrime/securesms/components/emoji/EmojiTextView.java @@ -1,15 +1,20 @@ package org.thoughtcrime.securesms.components.emoji; import android.content.Context; +import android.graphics.Paint.FontMetricsInt; import android.graphics.drawable.Drawable; import android.support.annotation.NonNull; import android.support.v7.widget.AppCompatTextView; -import android.text.InputFilter; +import android.text.TextUtils; +import android.text.TextUtils.TruncateAt; import android.util.AttributeSet; import org.thoughtcrime.securesms.components.emoji.EmojiProvider.EmojiDrawable; +import org.thoughtcrime.securesms.util.ViewUtil; public class EmojiTextView extends AppCompatTextView { + private CharSequence source; + private boolean needsEllipsizing; public EmojiTextView(Context context) { this(context, null); @@ -21,11 +26,42 @@ public class EmojiTextView extends AppCompatTextView { public EmojiTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - setFilters(new InputFilter[]{ new EmojiFilter(this) }); + } + + @Override public void setText(CharSequence text, BufferType type) { + source = EmojiProvider.getInstance(getContext()).emojify(text, this); + setTextEllipsized(source); + } + + public void setTextEllipsized(final CharSequence source) { + super.setText(needsEllipsizing ? ViewUtil.ellipsize(source, this) : source, BufferType.SPANNABLE); } @Override public void invalidateDrawable(@NonNull Drawable drawable) { if (drawable instanceof EmojiDrawable) invalidate(); else super.invalidateDrawable(drawable); } + + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + final int size = MeasureSpec.getSize(widthMeasureSpec); + final int mode = MeasureSpec.getMode(widthMeasureSpec); + if (getEllipsize() == TruncateAt.END && + !TextUtils.isEmpty(source) && + (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) && + getPaint().breakText(source, 0, source.length()-1, true, size, null) != source.length()) + { + needsEllipsizing = true; + FontMetricsInt font = getPaint().getFontMetricsInt(); + super.onMeasure(MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(Math.abs(font.top - font.bottom), MeasureSpec.EXACTLY)); + } else { + needsEllipsizing = false; + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + } + + @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + if (changed) setTextEllipsized(source); + super.onLayout(changed, left, top, right, bottom); + } } diff --git a/src/org/thoughtcrime/securesms/util/ViewUtil.java b/src/org/thoughtcrime/securesms/util/ViewUtil.java index 1d801c82cb..4a88dfdb23 100644 --- a/src/org/thoughtcrime/securesms/util/ViewUtil.java +++ b/src/org/thoughtcrime/securesms/util/ViewUtil.java @@ -18,8 +18,13 @@ package org.thoughtcrime.securesms.util; import android.graphics.drawable.Drawable; import android.support.annotation.DrawableRes; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.text.TextUtils; +import android.text.TextUtils.TruncateAt; import android.view.View; import android.view.ViewGroup; +import android.widget.TextView; public class ViewUtil { public static void setBackgroundSavingPadding(View v, Drawable drawable) { @@ -45,4 +50,15 @@ public class ViewUtil { if (childIndex > -1) parent.removeView(toRemove); parent.addView(toAdd, childIndex > -1 ? childIndex : defaultIndex); } + + public static CharSequence ellipsize(@Nullable CharSequence text, @NonNull TextView view) { + if (TextUtils.isEmpty(text) || view.getWidth() == 0 || view.getEllipsize() != TruncateAt.END) { + return text; + } else { + return TextUtils.ellipsize(text, + view.getPaint(), + view.getWidth() - view.getPaddingRight() - view.getPaddingLeft(), + TruncateAt.END); + } + } }