Почему LayoutInflater игнорирует указанные мной параметры макета layout_width и layout_height? - PullRequest
162 голосов
/ 17 февраля 2011

У меня были серьезные проблемы с тем, чтобы LayoutInflater работал должным образом, как и другие люди: Как использовать layoutinflator для добавления видов во время выполнения? .

Почему LayoutInflater игнорируетпараметры макета я уже уточнил?Например, почему значения layout_width и layout_height из моих ресурсов XML не соблюдаются?

Ответы [ 3 ]

366 голосов
/ 17 февраля 2011

Я исследовал эту проблему, обращаясь к документам LayoutInflater и настраивая небольшой демонстрационный проект.В следующих руководствах показано, как динамически заполнить макет с помощью LayoutInflater.

. Прежде чем начать, посмотрим, как выглядят параметры LayoutInflater.inflate():

  • resource : Идентификатор загружаемого ресурса макета XML (например, R.layout.main_page)
  • root : Необязательный вид, который будет родительским для сгенерированной иерархии (если attachToRoot равно true)или просто объект, который предоставляет набор LayoutParams значений для корня возвращаемой иерархии (если attachToRoot равно false.)
  • attachToRoot :завышенная иерархия должна быть привязана к корневому параметру?Если false, root используется только для создания правильного подкласса LayoutParams для корневого представления в XML.

  • Возвращает : корневое представление завышенногоиерархия.Если был указан root и attachToRoot равно true, это root;в противном случае это корень завышенного XML-файла.

Теперь для примера макета и кода.

Основной макет (main.xml):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</LinearLayout>

В этот контейнер добавлен отдельныйTextView, видимый как маленький красный квадрат, если параметры макета успешно применяются из XML (red.xml):

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="25dp"
    android:layout_height="25dp"
    android:background="#ff0000"
    android:text="red" />

Теперь LayoutInflater используется с несколькими вариантами параметров вызова

public class InflaterTest extends Activity {

    private View view;

    @Override
    public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);

      setContentView(R.layout.main);
      ViewGroup parent = (ViewGroup) findViewById(R.id.container);

      // result: layout_height=wrap_content layout_width=match_parent
      view = LayoutInflater.from(this).inflate(R.layout.red, null);
      parent.addView(view);

      // result: layout_height=100 layout_width=100
      view = LayoutInflater.from(this).inflate(R.layout.red, null);
      parent.addView(view, 100, 100);

      // result: layout_height=25dp layout_width=25dp
      // view=textView due to attachRoot=false
      view = LayoutInflater.from(this).inflate(R.layout.red, parent, false);
      parent.addView(view);

      // result: layout_height=25dp layout_width=25dp 
      // parent.addView not necessary as this is already done by attachRoot=true
      // view=root due to parent supplied as hierarchy root and attachRoot=true
      view = LayoutInflater.from(this).inflate(R.layout.red, parent, true);
    }
}

Фактические результаты изменений параметров задокументированы в коде.

СИНХРОНИЗАЦИЯ: Вызов LayoutInflater без указания корня приводит к раздутому вызову, игнорирующему параметры макета из XML.Вызов inflate с root не равен null и attachRoot=true загружает параметры макета, но возвращает корневой объект снова, что предотвращает дальнейшие изменения макета загруженного объекта (если вы не можете найти его с помощью findViewById()).Таким образом, соглашение о вызовах, которое вы, скорее всего, хотели бы использовать, таково:

loadedView = LayoutInflater.from(context)
                .inflate(R.layout.layout_to_load, parent, false);

Для решения проблем с макетом настоятельно рекомендуется Инспектор макетов .

4 голосов
/ 19 февраля 2016

andig правильно, что общая причина игнорирования LayoutInflater ваших layout_params будет в том, что не указан корень.Многие люди думают, что вы можете передать null для root.Это приемлемо для нескольких сценариев, таких как диалог, когда у вас нет доступа к root во время создания.Однако следует соблюдать хорошее правило: если у вас есть root, передайте его LayoutInflater.

Я написал подробное сообщение в блоге об этом, которое вы можете проверить здесь:

https://www.bignerdranch.com/blog/understanding-androids-layoutinflater-inflate/

0 голосов
/ 08 ноября 2018

хочу добавить к основному ответу выше
Я пытался следовать этому, но мой recyclerView начал растягивать каждый элемент на экран
Мне пришлось добавить следующую строку после надувания для достижения цели

itemLayoutView.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT));

Я уже добавил эти параметры в xml, но они не работали корректно
и с этой строкой все ок

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