Android TextView имеет высоту и ширину 0

#android

#Android

Вопрос:

У меня есть небольшой проект, в котором я хочу несколько раз повторно использовать определенный компонент пользовательского интерфейса, поэтому я создал виджет, расширив ViewGroup. В этой ViewGroup я раздул представление, которое содержало TextView внутри LinearLayout, и добавил это раздутое представление в ViewGroup через addView.

Внешний LinearLayout отлично расширяется, но внутренний TextView имеет getHeight () = 0 и getWith () = 0, когда я просматриваю его через средство просмотра иерархии. Странно то, что layout_height и layout_width — это значения, которые я дал им в моем xml.

У меня здесь нет кода, но он выглядел примерно так:

xml:

 <LinearLayout  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent">  

    <TextView  
        android:text="random text.."  
        android:layout_with="200px"  
        android:layout_height="50px" />  
</LinearLayout>  
  

Java:

 class MyWidget extends ViewGroup {
...

//In constructor  
myView = View.inflate(context, R.layout.xml, null);  
addView(myView);  

//In layout  
myView.layout(l, t, r, b);  
  

Я попытался присвоить моему текстовому представлению значения fill_parent для размера, но это не помогло.

Комментарии:

1. вы пробовали в Hierarchy Viewer принудительно запрашивать макет? если из-за этого отображается textview, то вы, вероятно, столкнулись с ошибкой фреймворка (которая должна быть решена в API> 8 AFAIK).

2. Нет, я не знал, что смогу это сделать. Попробую, когда вернусь позже. Однако я несколько раз пробовал forceLayout () из моего виджета, и это не помогло.

3. Возможно, вам следует создать LinearLayout. LayoutParams (int width, int height) и установить его в свой TextView?

4. Я думаю, вам нужно вызвать measure (…, …)

5. В TextView layout_width отсутствует d . Это, вероятно, не поможет.

Ответ №1:

Помните: getHeight() и getWidth() возвращайте 0 , если компоненты еще не отрисованы.


Чтобы найти ширину и высоту элемента View перед его отрисовкой:

  1. Первый вызов measure

     view.measure(MeasureSpec.UNSPECIFIED,MeasureSpec.UNSPECIFIED)
      
  2. Теперь вы можете получить ширину, используя getMeasuredWidth и высоту, используя getMeasuredHeight

     int width = view.getMeasuredWidth();
    int height = view.getMeasuredHeight();
      

Я опубликовал здесь еще несколько идей: как получить ширину / высоту представления

Комментарии:

1. вы это сделали. предоставлен ответ в одну строку на самый распространенный вопрос во всем # Android

2. Боже, я никогда не видел этого ни в одном ответе по этому вопросу.

Ответ №2:

1) Вот несколько ссылок для использования Hierarchy Viewer на вашем телефоне разработчика.

http://developer.android.com/guide/developing/debugging/debugging-ui.html

и класс, который вам понадобится:

http://github.com/romainguy/ViewServer

2) Вы также можете повторно использовать макет как компонент с тегом include:

 <include android:id="@ id/your_id" layout="@layout/layout_name" />
  

Ответ №3:

Итак, я назначил награду за это, и вот что я нашел.

Раздувание с помощью null ссылки — плохая идея (TM). По сути, это представление не получит необходимых параметров макета, в которых оно нуждается (его родительский элемент устанавливает целую кучу из них, с задействованием целой кучи магии / логики). Таким образом, раздувание в null означает отсутствие родителей и унаследованных параметров макета. Можно вручную установить ряд этих параметров, но из-за задействованной магии это может не решить вашу проблему.

«Решения», которые я придумал, предполагают; использование include (когда вы знаете, сколько вам нужно) и перенос их в код или раздувание до родительского элемента (когда вам нужно по-настоящему динамичное, N вещей). И, конечно, у XML, который вы раздуваете, будут конфликты идентификаторов, поэтому я делаю это, беря последний дочерний элемент (например, getChildAt(getChildCount() -1) ) того, что я ищу, и т.д.

Ответ №4:

Вы пробовали выдавать себя за root:

 View.inflate(context, R.layout.xml, this); 
  

Поскольку вы будете родительским для этого представления, которое соответствует спецификации javadoc.

Комментарии:

1. Обязательно удалите addView(view) строку, иначе вы получите исключение во время выполнения при попытке назначить представление другому родительскому элементу.