Почему настройка текста из onMeasure не влияет на TextView? - PullRequest
5 голосов
/ 04 августа 2011

Существует TextView определенного размера, и всякий раз, когда текст, для которого он установлен, слишком длинный, я бы хотел переустановить его на какое-то предустановленное значение.

Для этого я переопределяю onMeasure и звонит setText.Однако это не влияет на содержимое TextView.

Чего мне не хватает?

РЕДАКТИРОВАТЬ: , если вы считаете, что это должно быть сделано совершенно другим способом -пожалуйста, не стесняйтесь предложить

Ответы [ 7 ]

5 голосов
/ 04 августа 2011

onMeasure() обычно вызывается на этапе макета.Кроме того, насколько я знаю, onMeasure() - это то, где ВЫ должны измерить ваш взгляд.Он получает 2 значения размером родительского элемента вашего представления, которые могут быть постоянными.

Почему бы вам просто не проверить длину текста, который вы устанавливаете, и, если он слишком длинный, просто заменить его наваш по умолчанию?

0 голосов
/ 17 августа 2011

Вы захотите реализовать Textwatcher, и в методе onTextChanged(...) вызовите метод TextView '* setEms (...) , который установит ширину TextView вширина (n m s), где 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);
}
0 голосов
/ 17 августа 2011

Вы можете зарегистрировать пользовательский TextWatcher с помощью addTextChangedListener (TextWatcher watcher).

Внутри TextWatcher вы переопределяете функцию afterTextChanged(Editable s), измеряете длину текста и, если слишком долго, возвращаете текст по умолчанию.

РЕДАКТИРОВАТЬ: я не слишком уверен в этом, но именно поэтому я думаю, что ваше решение с onMeasure не работает: onMeasure вызывается на начальной стадии макета, или когда нужно изменить размер пользовательского интерфейса, поэтому, как только ваш пользовательский интерфейс устанавливается, если вы впоследствии измените текст пользовательского интерфейса, и текст станет слишком длинным, это не повлияет на размер TextView, и onMeasure больше не вызывается ...

В любом случае лучше просто следить за изменениями текста и делать то, что вы хотите, когда он превысит лимит, и позволить Android выполнять грязные измерения TextView

0 голосов
/ 15 августа 2011

Это моя идея:

Вы можете измерить текст тривиально с помощью .length(), если его длина больше, чем желаемый предел, чем вырезать, поместив только подстроку. Но если вы хотите отобразить весь текст, вы можете реализовать onClickListener() на этом TextView, который будет отображать весь текст как 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() override реализуйте все, что я упоминал выше.

Затем вы создаете onClickListener() для TextView, где вы делаете диалог, а затем показывает свой текст как есть.


Надеюсь, вы найдете эту идею разумной. Если вам нужно больше объяснений, что я имел в виду, напишите мне.

0 голосов
/ 13 августа 2011

Это то, что я делаю, чтобы уменьшить шрифт текста, если текстовое содержимое достаточно велико, чтобы перейти к следующей строке. Проблема почти такая же, единственное отличие в вашем случае в том, что вы хотите заменить его другим текстом по умолчанию.

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);
                    }
                }

           }
});

Это позаботится о вашей длине динамически. Теперь размер или длину текста нельзя зафиксировать, так как он зависит от различных форм-факторов. Например, 20-символьный текст на 3,2-дюймовом экране будет решительно большим, однако он будет слишком маленьким для 4,1-дюймового экрана. Поэтому я бы посоветовал вам использовать счетчик строк в качестве ссылки, и если текст переносится, то вы можете либо уменьшить шрифт, как я, либо заменить его чем-то другим.

0 голосов
/ 13 августа 2011

В вашем onMeasure(int,int)

  1. ЗВОНОК super(int,int)
  2. Используйте getMeasuredWidth() и getMeasuredHeight

как то так:

void onMeasure(int a, int b){
    super(a,b);
    if(getMeasuredWidth()>bla)
        setText("default");
}
0 голосов
/ 04 августа 2011

Со страницы документации View.

Измерьте вид и его содержимое, чтобы определить измеренную ширину и измеренная высота. Этот метод вызывается measure (int, int) и должны быть переопределены подклассами для обеспечения точного и эффективное измерение их содержания.

Если вы хотите, чтобы текстовое представление имело ограниченную ширину или высоту, вызовите setMaxWidth() setMaxHeight() setMaxLines() или отметьте его вручную и измените его так, как вам нравится из пользовательского метода

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...