Как надуть один вид с макетом


221

У меня есть макет, определенный в XML. Он также содержит:

<RelativeLayout
    android:id="@+id/item"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
/>

Я хотел бы надуть этот RelativeView с другим файлом макета XML. Я могу использовать разные макеты в зависимости от ситуации. как мне это сделать? Я пробовал разные варианты

RelativeLayout item = (RelativeLayout) findViewById(R.id.item);
item.inflate(...)

Но ни один из них не работал нормально.

Ответы:


390

Я не уверен, что следил за вашим вопросом. Вы пытаетесь прикрепить дочернее представление к RelativeLayout? Если это так, вы хотите сделать что-то вроде:

RelativeLayout item = (RelativeLayout)findViewById(R.id.item);
View child = getLayoutInflater().inflate(R.layout.child, null);
item.addView(child);

3
Я получаю сообщение об ошибке: 02-25 22: 21: 19.324: ОШИБКА / AndroidRuntime (865): вызвано: java.lang.IllegalStateException: указанный дочерний элемент уже имеет родителя. Сначала вы должны вызвать removeView () у родителя ребенка.
Михал Димел

27
Только что попробовал это сейчас, мне нужно: View child = getLayoutInflater (). Inflate (R.layout.child, null);
Джеймс

3
Проблема не в коде. Это довольно легко следовать коду. Где вы делаете XML-файл. это тип ресурса стиля темы? проблема, я думаю, что люди, которых я включил, - то, где мы
помещаем

15
Это не идеально. Следует использовать версию с тремя параметрами инфлятора - вот почему: doubleencore.com/2013/05/layout-inflation-as-intended
Ник Кардосо,

3
Ответ неверный, даже если он работает. Пожалуйста, ознакомьтесь с этим сообщением возможныхmobile.com
2013/

107

Вы раздуваете ресурс XML. Смотрите документ LayoutInflater .

Если ваш макет находится в mylayout.xml , вы должны сделать что-то вроде:

View view; 
LayoutInflater inflater = (LayoutInflater)   getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
view = inflater.inflate(R.layout.mylayout, null);

RelativeLayout item = (RelativeLayout) view.findViewById(R.id.item);

4
У меня раздут основной взгляд. Проблема в том, что я хочу накачать часть этого из другого XML-файла. Этот элемент RelativeLayout является частью большего макета, и я хочу заполнить его макетом из другого файла XML.
Михал Димел

гм, извините, тогда я понятия не имею :(. Вы используете что-то вроде <include> в своем главном
окне

Нет, это простая раскладка. Я думаю, что я просто добавлю свои элементы программно - без XML. Спасибо за помощь!
Михал Димел

27

Хоть и поздний ответ, но хотелось бы добавить, что один из способов получить это

LayoutInflater layoutInflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = layoutInflater.inflate(R.layout.mylayout, item );

где itemродительский макет, где вы хотите добавить дочерний макет.


(еще позже) Мне трудно реализовать ваш ответ. Я попробовал код, который вы упомянули выше, но заменил «item» на: «R.layout.activity_layout« Я получаю «Нет подходящего метода для (int, int)» ». Могу ли я побеспокоить вас за ваши мысли?
Кайл

1
@ Кайл - еще позже. Вы не можете использовать Rресурсы как ссылки на объект, они просто ints. Вы должны использовать findViewByIdпередачу Rресурса, а затем набрать приведение к нужному объекту. Затем вы можете использовать его в вызовах функций, как inflate. (то есть ViewGroup item = (ViewGroup) findViewById(R.layout.activity_layout);... тогда вы можете использовать itemкак выше.)
Pimp Trizkit

Я предполагаю использовать RelativeLayoutвместо ViewGroupэтого в моем примере выше, поскольку вы не можете создать экземпляр базового класса ViewGroup. 5-минутное правило редактирования получило меня. LOL
Pimp Trizkit

Можно ли скрыть родительский вид и отобразить только дочерний вид
NovusMobile

Спасибо, этот метод помог, когда я не мог использовать getContext () в предыдущем примере, так как я использую фрагменты.
RightHandedMonkey

19

Полезно добавить к этому, несмотря на то, что это старый пост, что для добавления дочернего представления, раздуваемого из xml, к макету группы просмотра, необходимо вызвать inflate, чтобы понять, к какому типу группы просмотра оно относится. быть добавленным к. Подобно:

View child = getLayoutInflater().inflate(R.layout.child, item, false);

Метод inflate довольно перегружен и описывает эту часть использования в документах. У меня была проблема, когда одно представление, накаченное из xml, не выравнивалось в родительском элементе должным образом, пока я не сделал этот тип изменений.


Наконец, спасибо :) Это позволяет добавить несколько представлений к одному родителю, но без необходимости беспокоиться о LayoutParams - которые читаются из XML. Хорошая работа!
Sabo

13

Еще проще использовать

View child = View.inflate(context, R.layout.child, null)
item.addChild(child) //attach to your item

Использование не View.inflate()является лучшим способом, никакого ненужного LayoutInflaterили getSystemService(Context.LAYOUT_INFLATER_SERVICE)или какой - либо из всех этих неудобств! : D
Варун

8

инфляция макета

View view = null;
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
view = inflater.inflate(R.layout.mylayout, null);
main.addView(view);

6

Если вы не в деятельности, вы можете использовать статический from()метод из LayoutInflaterкласса, чтобы получить LayoutInflater, или запросить службу из метода контекста getSystemService()тоже:

LayoutInflater i;
Context x;       //Assuming here that x is a valid context, not null

i = (LayoutInflater) x.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//OR
i = LayoutInflater.from(x);

(Я знаю, что это почти 4 года назад, но все же стоит упомянуть)


4

Если вы хотите добавить один просмотр несколько раз, то вы должны использовать

   layoutInflaterForButton = getActivity().getLayoutInflater();

 for (int noOfButton = 0; noOfButton < 5; noOfButton++) {
        FrameLayout btnView = (FrameLayout) layoutInflaterForButton.inflate(R.layout.poll_button, null);
        btnContainer.addView(btnView);
    }

Если вам нравится

   layoutInflaterForButton = getActivity().getLayoutInflater();
    FrameLayout btnView = (FrameLayout) layoutInflaterForButton.inflate(R.layout.poll_button, null);

и

for (int noOfButton = 0; noOfButton < 5; noOfButton++) {
            btnContainer.addView(btnView);
        }

тогда будет выброшено исключение из всех готовых добавленных видов.


4

AttachToRoot установлен в True

Просто подумайте, что мы указали кнопку в файле макета XML с шириной макета и высотой макета, равными match_parent.

<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/custom_button">
</Button>

В этом событии нажатия кнопки мы можем установить следующий код для раздувания макета в этом действии.

LayoutInflater inflater = LayoutInflater.from(getContext());
inflater.inflate(R.layout.yourlayoutname, this);

Надеюсь, что это решение работает для вас.


3

Попробуйте этот код:

  1. Если вы просто хотите надуть свой макет:

View view = LayoutInflater.from(context).inflate(R.layout.your_xml_layout,null); // Code for inflating xml layout
RelativeLayout item = view.findViewById(R.id.item);   

  1. Если вы хотите накачать свой макет в контейнере (родительский макет):

LinearLayout parent = findViewById(R.id.container);        //parent layout.
View view = LayoutInflater.from(context).inflate(R.layout.your_xml_layout,parent,false); 
RelativeLayout item = view.findViewById(R.id.item);       //initialize layout & By this you can also perform any event.
parent.addView(view);             //adding your inflated layout in parent layout.


2

У меня было самое сложное время с этой ошибкой из-за моих уникальных обстоятельств, но в конце концов я нашел решение.

Моя ситуация: я использую отдельное представление (XML), которое содержит, а WebViewзатем открывается, AlertDialogкогда я нажимаю кнопку в моем основном представлении деятельности. Но так или иначе WebViewпринадлежал к основному виду деятельности (вероятно, потому что я извлекаю ресурс отсюда), поэтому прямо перед тем, как я назначил его своему AlertDialog(как представление), я должен был получить родительский из моих WebView, положить его в ViewGroup, затем удалите все взгляды на это ViewGroup. Это сработало, и моя ошибка ушла.

// set up Alert Dialog box
AlertDialog.Builder alert = new AlertDialog.Builder(this);
// inflate other xml where WebView is
LayoutInflater layoutInflater = (LayoutInflater)this.getSystemService
                (Context.LAYOUT_INFLATER_SERVICE);
View v = layoutInflater.inflate(R.layout.your_webview_layout, null);
final WebView webView = (WebView) v.findViewById(R.id.your_webview_id);

// more code...

.... позже, после того как я загрузил свой WebView....

// first, remove the parent of WebView from it's old parent so can be assigned a new one.
ViewGroup vg = (ViewGroup) webView.getParent();
vg.removeAllViews();

// put WebView in Dialog box
alert.setView(webView);
alert.show();

2

Если вы пытаетесь прикрепить дочернее представление к RelativeLayout? Вы можете сделать, следуя

RelativeLayout item = (RelativeLayout)findViewById(R.id.item);
View child = getLayoutInflater().inflate(R.layout.child, item, true);

1

С Kotlin вы можете использовать:

val content = LayoutInflater.from(context).inflate(R.layout.[custom_layout_name], null)

[your_main_layout].apply {
    //..
    addView(content)
}

-1

Я использовал приведенный ниже фрагмент кода для этого, и он работал для меня.

LinearLayout linearLayout = (LinearLayout)findViewById(R.id.item);
View child = getLayoutInflater().inflate(R.layout.child, null);
linearLayout.addView(child);
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.