我想知道是否可以在TextView中仅缩写字符串的一部分.我想做的是这样的事情:
Element with short title (X) Element with a very lo...(X)
标题应该是椭圆化的,但X必须始终可见.在我的情况下,不可能使用多个TextView.你认为这有一个简单的方法吗?
谢谢!
解决方法
我真的需要一个干净的解决方案,所以在搜索周围并没有找到任何我觉得我喜欢的解决方案后,我花了一些时间来写这个.
这是一个带有增强省略号控件的TextView的实现.它的工作方式是使用Android的Spanned接口.它定义了一个枚举,您可以使用它来标记您希望在需要时进行椭圆化处理的特定文本部分.
限制:
>不支持MIDDLE的省略号.如果它真的需要(我没有),这应该很容易添加.
>此类将始终将文本呈现为一行,因为它只支持单行文本.如果需要,欢迎其他人扩展(但这是一个更难的问题).
以下是用法示例:
FooActivity.java
class FooActivity extends Activity { /** * You can do this however you'd like,this example uses this simple * helper function to create a text span tagged for ellipsizing */ CharSequence ellipsizeText(String text) { SpannableString s = new SpannableString(text); s.setSpan(TrimmedTextView.EllipsizeRange.ELLIPSIS_AT_END,s.length(),Spannable.SPAN_INCLUSIVE_EXCLUSIVE); return s; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.foo_layout); TextView textView = (TextView) findViewById(R.id.textView4); SpannableStringBuilder text = new SpannableStringBuilder(); text.append(ellipsizeText("This is a long string of text which has important information ")); text.append("AT THE END"); textView.setText(text); } }
RES /布局/ foo_layout.xml
<com.example.text.TrimmedTextView android:id="@+id/textView4" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge"/>
而已
这是结果的一个例子:
实施
package com.example.text; import android.content.Context; import android.text.Editable; import android.text.Layout; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.TextUtils; import android.text.TextUtils.TruncateAt; import android.text.TextWatcher; import android.util.AttributeSet; import android.util.Log; import android.widget.TextView; public class TrimmedTextView extends TextView { public static enum EllipsizeRange { ELLIPSIS_AT_START,ELLIPSIS_AT_END; } private CharSequence originalText; private SpannableStringBuilder builder = new SpannableStringBuilder(); /** * This allows the cached value of the original unmodified text to be * invalidated whenever set externally. */ private final TextWatcher textCacheInvalidator = new TextWatcher() { @Override public void onTextChanged(CharSequence s,int start,int before,int count) { originalText = null; } @Override public void beforeTextChanged(CharSequence s,int count,int after) { } @Override public void afterTextChanged(Editable s) { } }; public TrimmedTextView(Context context) { this(context,null,0); } public TrimmedTextView(Context context,AttributeSet attrs) { this(context,attrs,AttributeSet attrs,int defStyle) { super(context,defStyle); addTextChangedListener(textCacheInvalidator); Log.v("TEXT","Set!"); } /** * Make sure we return the original unmodified text value if it's been * custom-ellipsized by us. */ public CharSequence getText() { if (originalText == null) { return super.getText(); } return originalText; } @Override protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec) { super.onMeasure(widthMeasureSpec,heightMeasureSpec); Layout layout = getLayout(); CharSequence text = layout.getText(); if (text instanceof Spanned) { Spanned spanned = (Spanned) text; int ellipsisStart; int ellipsisEnd; TruncateAt where = null; ellipsisStart = spanned.getSpanStart(EllipsizeRange.ELLIPSIS_AT_START); if (ellipsisStart >= 0) { where = TruncateAt.START; ellipsisEnd = spanned.getSpanEnd(EllipsizeRange.ELLIPSIS_AT_START); } else { ellipsisStart = spanned.getSpanStart(EllipsizeRange.ELLIPSIS_AT_END); if (ellipsisStart >= 0) { where = TruncateAt.END; ellipsisEnd = spanned.getSpanEnd(EllipsizeRange.ELLIPSIS_AT_END); } else { // No EllipsisRange spans in this text return; } } Log.v("TEXT","ellipsisStart: " + ellipsisStart); Log.v("TEXT","ellipsisEnd: " + ellipsisEnd); Log.v("TEXT","where: " + where); builder.clear(); builder.append(text,ellipsisStart).append(text,ellipsisEnd,text.length()); float consumed = Layout.getDesiredWidth(builder,layout.getPaint()); CharSequence ellipsisText = text.subSequence(ellipsisStart,ellipsisEnd); CharSequence ellipsizedText = TextUtils.ellipsize(ellipsisText,layout.getPaint(),layout.getWidth() - consumed,where); if (ellipsizedText.length() < ellipsisText.length()) { builder.clear(); builder.append(text,ellipsisStart).append(ellipsizedText) .append(text,text.length()); setText(builder); originalText = text; requestLayout(); invalidate(); } } } }