Ellipsize只在一个TextView节 [英] Ellipsize only a section in a TextView

查看:379
本文介绍了Ellipsize只在一个TextView节的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否有可能在一个TextView缩写字符串只有一部分。我想这样做是这样的:

I was wondering if it is possible to abbreviate only a portion of a string in a TextView. What I would like to do is something like this:

Element with short title (X)
Element with a very lo...(X)

标题应ellipsized,但X必须是始终可见。在我的情况下,是不可能使用一个以上的TextView。你认为有这样做的一个简单的方法?

The title should be ellipsized, but the X must be always visible. In my case, is not possible to use more than one TextView. Do you think there is a simple way of doing this?

谢谢!

推荐答案

我真的需要一个项目一个干净的解决方案,以便在搜索四周,没有找到,我觉得我喜欢的任何解决方案后,我花了一些时间来写这个了。

I really needed a clean solution for a project so after searching around and not finding any solutions I felt I liked, I took some time to write this up.

下面是具有增强省略号控制一个TextView的实现。它的工作方式是使用Android的跨区接口。它定义了一个枚举,你可以用它来标记,如果需要进行ellipsized文本的特定部分你想。

Here is an implementation of a TextView with enhanced ellipsis control. The way it works is by using Android's Spanned interface. It defines an enum you can use to tag the specific section of text you'd like to be ellipsized if needed.

限制:

  • 在不支持省略号在中部。这应该是很容易添加,如果它真的需要(我没有)。
  • 此类总是呈现文本到一条线,因为它仅支持单个文本行。其他人则欢迎来扩展它,如果这是需要的(但它是一个更难的问题)。

下面是使用的例子:

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, 0, 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"/>

就是这样

下面是结果的一个例子:

Here's an example of the result:

的实施

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 start, 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, 0);
  }

  public TrimmedTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, 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, 0, 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, 0, ellipsisStart).append(ellipsizedText)
            .append(text, ellipsisEnd, text.length());
        setText(builder);
        originalText = text;
        requestLayout();
        invalidate();
      }
    }
  }
}

这篇关于Ellipsize只在一个TextView节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆