From 606f39289d7dd406fde50b812f00a5da6ecabf15 Mon Sep 17 00:00:00 2001 From: xxxifan <445947962@qq.com> Date: Fri, 8 Nov 2019 09:13:35 +0800 Subject: [PATCH 1/5] don't append collapse symbol when collapse span is null --- .../src/main/java/com/lsjwzh/widget/text/ReadMoreTextView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/ReadMoreTextView.java b/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/ReadMoreTextView.java index ec41919..d5c4a3f 100644 --- a/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/ReadMoreTextView.java +++ b/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/ReadMoreTextView.java @@ -117,8 +117,8 @@ protected void onDraw(Canvas canvas) { protected StaticLayout makeLayout(CharSequence text, int maxWidth, boolean exactly) { mWithEllipsisLayout = super.makeLayout(text, maxWidth, exactly); SpannableStringBuilder textWithExtraEnd = new SpannableStringBuilder(text); - textWithExtraEnd.append(COLLAPSE_NORMAL); if (mCollapseSpan != null) { + textWithExtraEnd.append(COLLAPSE_NORMAL); textWithExtraEnd.setSpan(mCollapseSpan, textWithExtraEnd.length() - 1, textWithExtraEnd.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE); } From 3374204050476295087f0b03add8d01f84cc0475 Mon Sep 17 00:00:00 2001 From: xxxifan <445947962@qq.com> Date: Thu, 5 Dec 2019 11:33:15 +0800 Subject: [PATCH 2/5] [project needs] remove multiple line breaker --- .../java/com/lsjwzh/widget/text/FastTextView.java | 7 +------ .../com/lsjwzh/widget/text/ReadMoreTextView.java | 13 ++++++++++++- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/FastTextView.java b/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/FastTextView.java index af30f78..46a62da 100644 --- a/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/FastTextView.java +++ b/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/FastTextView.java @@ -26,6 +26,7 @@ import android.util.TypedValue; import android.view.Gravity; import android.view.MotionEvent; +import android.view.ViewTreeObserver; /** * Simple and Fast TextView. @@ -132,7 +133,6 @@ public boolean onTouchEvent(MotionEvent event) { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - long start = System.currentTimeMillis(); int width = MeasureSpec.getSize(widthMeasureSpec); boolean exactly = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY; if (!exactly) { @@ -164,11 +164,6 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { } else { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } - - long end = System.currentTimeMillis(); - if (BuildConfig.DEBUG) { - Log.d(TAG, "onMeasure cost:" + (end - start)); - } } protected boolean shouldResetStaticLayout(int width, CharSequence text, Layout layout) { diff --git a/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/ReadMoreTextView.java b/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/ReadMoreTextView.java index d5c4a3f..5bedf40 100644 --- a/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/ReadMoreTextView.java +++ b/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/ReadMoreTextView.java @@ -115,7 +115,18 @@ protected void onDraw(Canvas canvas) { @NonNull @Override protected StaticLayout makeLayout(CharSequence text, int maxWidth, boolean exactly) { - mWithEllipsisLayout = super.makeLayout(text, maxWidth, exactly); + if (mAttrsHelper.mMaxLines < Integer.MAX_VALUE) { + String[] strs = text.toString().split("\n"); + StringBuilder builder = new StringBuilder(); + for (String str : strs) { + if (str.isEmpty()) continue; + builder.append(str); + builder.append("\n"); + } + mWithEllipsisLayout = super.makeLayout(builder.toString(), maxWidth, exactly); + } else { + mWithEllipsisLayout = super.makeLayout(text, maxWidth, exactly); + } SpannableStringBuilder textWithExtraEnd = new SpannableStringBuilder(text); if (mCollapseSpan != null) { textWithExtraEnd.append(COLLAPSE_NORMAL); From fb274d5acb23bb360638da04e1b7a020e348f03f Mon Sep 17 00:00:00 2001 From: xxxifan <445947962@qq.com> Date: Tue, 17 Dec 2019 10:00:01 +0800 Subject: [PATCH 3/5] add compressText --- .../java/com/lsjwzh/widget/text/ReadMoreTextView.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/ReadMoreTextView.java b/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/ReadMoreTextView.java index 5bedf40..27ffc5c 100644 --- a/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/ReadMoreTextView.java +++ b/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/ReadMoreTextView.java @@ -27,6 +27,7 @@ public class ReadMoreTextView extends FastTextView { protected StaticLayout mAllTextLayout; protected StaticLayout mWithEllipsisLayout; protected ReplacementSpan mCollapseSpan = new EllipsisSpan(COLLAPSE_NORMAL); + protected boolean mCompressText; public ReadMoreTextView(Context context) { this(context, null); @@ -115,7 +116,7 @@ protected void onDraw(Canvas canvas) { @NonNull @Override protected StaticLayout makeLayout(CharSequence text, int maxWidth, boolean exactly) { - if (mAttrsHelper.mMaxLines < Integer.MAX_VALUE) { + if (mCompressText) { String[] strs = text.toString().split("\n"); StringBuilder builder = new StringBuilder(); for (String str : strs) { @@ -123,6 +124,7 @@ protected StaticLayout makeLayout(CharSequence text, int maxWidth, boolean exact builder.append(str); builder.append("\n"); } + builder.append("\n"); // extra line to fix ellipse symbol display mWithEllipsisLayout = super.makeLayout(builder.toString(), maxWidth, exactly); } else { mWithEllipsisLayout = super.makeLayout(text, maxWidth, exactly); @@ -199,6 +201,10 @@ public boolean isShowAll() { return mIsShowAll; } + public void compressText(boolean enable) { + mCompressText = enable; + } + public static class EllipsisSpan extends ReplacementSpan implements ClickableSpanUtil.Clickable { String mText; From 79233f72b0fd3aa1f217f3f6ce6da4f43527f70f Mon Sep 17 00:00:00 2001 From: xxxifan <445947962@qq.com> Date: Mon, 23 Dec 2019 11:03:41 +0800 Subject: [PATCH 4/5] add extra line when real count more than 2 --- .../main/java/com/lsjwzh/widget/text/ReadMoreTextView.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/ReadMoreTextView.java b/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/ReadMoreTextView.java index 27ffc5c..8333ae7 100644 --- a/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/ReadMoreTextView.java +++ b/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/ReadMoreTextView.java @@ -119,12 +119,16 @@ protected StaticLayout makeLayout(CharSequence text, int maxWidth, boolean exact if (mCompressText) { String[] strs = text.toString().split("\n"); StringBuilder builder = new StringBuilder(); + int realCount = 0; for (String str : strs) { + realCount++; if (str.isEmpty()) continue; builder.append(str); builder.append("\n"); } - builder.append("\n"); // extra line to fix ellipse symbol display + if (realCount > 2) { + builder.append("\n"); // extra line to fix ellipse symbol display + } mWithEllipsisLayout = super.makeLayout(builder.toString(), maxWidth, exactly); } else { mWithEllipsisLayout = super.makeLayout(text, maxWidth, exactly); From e49bc16aa66f67f1b5486070a2084f28632e8cd0 Mon Sep 17 00:00:00 2001 From: xxxifan <445947962@qq.com> Date: Fri, 27 Dec 2019 10:16:18 +0800 Subject: [PATCH 5/5] [project needs] add support for links --- .../com/lsjwzh/widget/text/FastTextView.java | 49 +++++++++++++++++-- .../lsjwzh/widget/text/ReadMoreTextView.java | 28 +++-------- 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/FastTextView.java b/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/FastTextView.java index 46a62da..878f18e 100644 --- a/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/FastTextView.java +++ b/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/FastTextView.java @@ -4,6 +4,7 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.Paint; import android.os.Build; import android.support.annotation.NonNull; @@ -14,6 +15,7 @@ import android.text.LayoutUtils; import android.text.Spannable; import android.text.SpannableString; +import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.StaticLayout; import android.text.StaticLayoutBuilderCompat; @@ -21,12 +23,13 @@ import android.text.TextPaint; import android.text.TextUtils; import android.text.style.ReplacementSpan; +import android.text.util.Linkify; import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; import android.view.Gravity; import android.view.MotionEvent; -import android.view.ViewTreeObserver; +import java.util.regex.Pattern; /** * Simple and Fast TextView. @@ -40,6 +43,9 @@ public class FastTextView extends FastTextLayoutView { private boolean mEnableLayoutCache = false; // experiment private EllipsisSpannedContainer mEllipsisSpanned; private int mCurTextColor; + protected boolean mCompressText; + protected int mLinkifyMask; + private int mLinkColor = Color.parseColor("#109DD0"); public FastTextView(Context context) { this(context, null); @@ -306,7 +312,7 @@ public void setMaxLines(int maxLines) { * TypedValue} for the possible dimension units. * * @param textSize The desired size in the given units. - * @param unit The desired dimension unit. + * @param unit The desired dimension unit. */ public void setTextSize(float textSize, int unit) { float rawTextSize = TypedValue.applyDimension( @@ -344,8 +350,42 @@ public void setCustomEllipsisSpan(ReplacementSpan customEllipsisSpan) { mCustomEllipsisSpan = customEllipsisSpan; } + public void compressText(boolean enable) { + mCompressText = enable; + } + + public void addLinks(int mask) { + mLinkifyMask = mask; + mTextPaint.linkColor = mLinkColor; + } + @NonNull protected StaticLayout makeLayout(CharSequence text, int maxWidth, boolean exactly) { + if (mCompressText) { + SpannableStringBuilder ssb = new SpannableStringBuilder(); + String[] patterns = Pattern.compile("\n").split(text); + int patternSize = patterns.length; + int realCount = 0; + for (int i = 0; i < patternSize; i++) { + realCount++; + if (patterns[i].isEmpty()) continue; + ssb.append(patterns[i]); + if (i < patternSize - 1) { + ssb.append("\n"); + } + } + if (realCount >= mAttrsHelper.mMaxLines) { + ssb.append("\n").append("\n"); // extra line to fix ellipse symbol display + } + text = ssb; + } else { + text = new SpannableString(text); // also make text into SpannableString. + } + + if (mLinkifyMask > 0) { + Linkify.addLinks((Spannable) text, mLinkifyMask); + } + TextUtils.TruncateAt truncateAt = getTruncateAt(); int layoutTargetWidth = maxWidth; int contentWidth = maxWidth; @@ -356,7 +396,6 @@ protected StaticLayout makeLayout(CharSequence text, int maxWidth, boolean exact layoutTargetWidth = maxWidth > 0 ? Math.min(maxWidth, contentWidth) : contentWidth; } - StaticLayoutBuilderCompat layoutBuilder = createStaticLayoutBuilder(text, 0, text .length(), mTextPaint, layoutTargetWidth); layoutBuilder.setLineSpacing(mAttrsHelper.mSpacingAdd, mAttrsHelper.mSpacingMultiplier) @@ -401,8 +440,8 @@ protected StaticLayout makeLayout(CharSequence text, int maxWidth, boolean exact } protected StaticLayoutBuilderCompat createStaticLayoutBuilder(CharSequence source, - int start, int end, - TextPaint paint, int width) { + int start, int end, + TextPaint paint, int width) { return StaticLayoutBuilderCompat.obtain(source, start, end, paint, width); } diff --git a/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/ReadMoreTextView.java b/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/ReadMoreTextView.java index 8333ae7..9f2b6c8 100644 --- a/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/ReadMoreTextView.java +++ b/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/ReadMoreTextView.java @@ -8,6 +8,7 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.RequiresApi; +import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.StaticLayout; @@ -15,6 +16,7 @@ import android.text.TextPaint; import android.text.TextUtils; import android.text.style.ReplacementSpan; +import android.text.util.Linkify; import android.util.AttributeSet; import android.util.Log; import android.view.View; @@ -27,7 +29,6 @@ public class ReadMoreTextView extends FastTextView { protected StaticLayout mAllTextLayout; protected StaticLayout mWithEllipsisLayout; protected ReplacementSpan mCollapseSpan = new EllipsisSpan(COLLAPSE_NORMAL); - protected boolean mCompressText; public ReadMoreTextView(Context context) { this(context, null); @@ -116,24 +117,11 @@ protected void onDraw(Canvas canvas) { @NonNull @Override protected StaticLayout makeLayout(CharSequence text, int maxWidth, boolean exactly) { - if (mCompressText) { - String[] strs = text.toString().split("\n"); - StringBuilder builder = new StringBuilder(); - int realCount = 0; - for (String str : strs) { - realCount++; - if (str.isEmpty()) continue; - builder.append(str); - builder.append("\n"); - } - if (realCount > 2) { - builder.append("\n"); // extra line to fix ellipse symbol display - } - mWithEllipsisLayout = super.makeLayout(builder.toString(), maxWidth, exactly); - } else { - mWithEllipsisLayout = super.makeLayout(text, maxWidth, exactly); - } + mWithEllipsisLayout = super.makeLayout(text, maxWidth, exactly); SpannableStringBuilder textWithExtraEnd = new SpannableStringBuilder(text); + if (mLinkifyMask > 0) { + Linkify.addLinks(textWithExtraEnd, mLinkifyMask); + } if (mCollapseSpan != null) { textWithExtraEnd.append(COLLAPSE_NORMAL); textWithExtraEnd.setSpan(mCollapseSpan, textWithExtraEnd.length() - 1, @@ -205,10 +193,6 @@ public boolean isShowAll() { return mIsShowAll; } - public void compressText(boolean enable) { - mCompressText = enable; - } - public static class EllipsisSpan extends ReplacementSpan implements ClickableSpanUtil.Clickable { String mText;