为什么从onMeasure设置文本不会影响TextView?

时间:2011-08-04 11:37:54

标签: android user-interface android-layout textview

有一个TextView的特定大小,只要文字设置太长,我就想将它重新设置为某个预设值。

要完成此操作,我将覆盖onMeasure并致电setText。但是,这不会影响TextView内容。

我错过了什么?

编辑:如果您认为应该以完全不同的方式完成 - 请随时提出建议

7 个答案:

答案 0 :(得分:5)

onMeasure()通常在布局阶段调用。此外据我所知onMeasure()必须衡量你的观点。它接收2个值,这些值是视图父级的大小,可以是常量。

为什么不检查您正在设置的文本的长度?如果它太长,只需将其替换为默认文本?

答案 1 :(得分:0)

来自View文档页面。

  

测量视图及其内容以确定测量的宽度和   测量的高度。此方法由 measure(int,int)调用   并且应该被子类覆盖以提供准确和   有效测量其内容。

如果您希望textview的宽度或高度有限,请致电setMaxWidth() setMaxHeight() setMaxLines()或手动检查,并根据自定义方式进行更改

答案 2 :(得分:0)

onMeasure(int,int)

  1. 致电super(int,int)
  2. 使用getMeasuredWidth()getMeasuredHeight
  3. 类似的东西:

    void onMeasure(int a, int b){
        super(a,b);
        if(getMeasuredWidth()>bla)
            setText("default");
    }
    

答案 3 :(得分:0)

这是我在文本内容足够大以转到下一行时减少文本字体的方法。问题几乎是一样的,你的情况的唯一区别是你想用其他一些默认文本替换它。

ViewTreeObserver vto = ((TextView)findViewById(R.id.myTextView)).getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

            @Override
            public void onGlobalLayout() {

                if (null != ((TextView)findViewById(R.id.myTextView))) {
                    if (1 < ((TextView)findViewById(R.id.myTextView)).getLineCount()) {
                    ((TextView)findViewById(R.id.myTextView)).setTextSize(TypedValue.COMPLEX_UNIT_PX,
                              ((TextView)findViewById(R.id.myTextView)).getTextSize() - 2);
                    }
                }

           }
});

这会动态地处理你的长度。现在,文本大小或长度无法根据它将改变的不同形状因素来修复。例如,3.2英寸屏幕中的20个字符文本肯定会很大,但对于4.1英寸屏幕来说它太小了。因此,我建议您使用行计数作为参考,如果文本包装,那么您可以像我一样减少字体或用其他东西替换它。

答案 4 :(得分:0)

这是我的想法:

如果文本的长度大于所需的限制,则可以使用.length()轻松测量文本,而不是仅使用子字符串。但是,如果要显示整个文本,可以在onClickListener()上实现TextView,其中envoking将整个文本显示为Dialog或其他任何内容。

我认为另一种适合的方法是为不同的密度屏幕创建不同的布局,然后添加xml android:maxLines="your limit" android:textSize="some value"android:maxLength="@integer/mylimit"(不同密度的不同限制和大小) )。剩下的就是测量长度并仅显示子串(或默认文本)


类似的东西:

String myText = "bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla";
String clickForMore="...Click for more";
int limit =  myActivity.this.getResources().getInteger(R.integer.limit); //dont forget to declare it in your string.xml

想象一下,我们有3行文字,我们只允许2行(总长度值为int limit)。我们的文本片段适合TextView内部,但并未完全显示。我们需要告知用户还有更多要阅读...

    myTextView.setVisibility(View.INVISIBLE);// <--- takes the space in the container
    if(clickForMore.length() < myText.length() && myText.length() > limit)// <--- avoiding negative place and checking if the entire text is inside the box or there are characters leftover.
    {
    String temp = myText.substring(0, limit-clickForMore.length());// <-- we cutting space from currently displayed (not original string)  to append the `clickForMore` string information.
    myTextView.setText(temp+clickForMore);
     myTextView.setVisibility(View.VISIBLE);
     myTextView.setOnTouchListener(new OnTouchListener() {

        @Override
    public boolean onTouch(View v, MotionEvent event) {
    // display the dialog with full text....
    return false;
                }

}); //<--- instantiate the click listener 
    }
    else
    {
       //the text fits the box and no need to slice it, just display it straight forward
    }

myText.length() > limit - 测试字符串是否与限制重叠。 实施.addTextChangeListener()TextWatcher)并在afterTextChange()覆盖方法中实现我上面提到的所有这些。

然后为您创建对话框的onClickListener()创建TextView,然后按原样显示文字。


我希望你能找到这个想法,合理。如果你需要更多解释我的想法随时写我。

答案 5 :(得分:0)

您可以使用TextWatcher注册自定义addTextChangedListener (TextWatcher watcher)

TextWatcher内部,您将覆盖afterTextChanged(Editable s)函数,确定文本的长度,如果太长,则将其设置为默认文本。

编辑:我对此不太确定,但这就是为什么我认为你的onMeasure解决方案无法正常工作:在初始布局阶段调用onMeasure,或者需要调整UI的大小时,所以一旦你的UI设置,如果之后更改UI的文本,并且文本变得太长,这不会影响TextView的大小,并且不再调用onMeasure ...

AnyWay更好的是只关注文本更改,并在超出限制时执行您想要的操作,并让Android执行脏TextView测量工作

答案 6 :(得分:0)

您需要实施Textwatcher,并在onTextChanged(...)方法中调用TextView的{​​{3}}方法,该方法将设置TextView的宽度宽度为(n m ),其中n是setEms(...)的输入。

...
TextView tv = (TextView) findViewById(R.id.my_text_view);
tv.addTextChangedListener(this);
...
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    tv.setEms(count);
}