Урок 40. LayoutInflater. Учимся использовать.

Обсуждение уроков
Аватара пользователя
Nialon
Сообщения: 22
Зарегистрирован: 12 ноя 2013, 19:19

Re: Урок 40. LayoutInflater. Учимся использовать.

Сообщение Nialon » 30 ноя 2014, 23:29

Привет всем. Столкнулся с такой занозой в коде.
При Инфляции нового элемента дублируется их getID номер.
После этого нельзя с ними работать и особенно удалять. Просто стирается первый найденный.
Я думал идентификаторы СТРОГО уникальные, андрюха сам автоматизирует процесс генерации, нифига.
Функции генерации не откопал, зато решил сделать через getID(родной ID + случайные цифры) == null.
Так вот, кто заметил, кто как решает эту проблему? ))

Выше был пост удаление вьюшек по индексу. Возьму на заметку.

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Урок 40. LayoutInflater. Учимся использовать.

Сообщение Foenix » 01 дек 2014, 07:45

По ссылке в подписи.
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

Аватара пользователя
doter.ua
Сообщения: 1106
Зарегистрирован: 23 ноя 2013, 16:08
Откуда: Ukraine

Re: Урок 40. LayoutInflater. Учимся использовать.

Сообщение doter.ua » 01 дек 2014, 14:34

"Инфлируемый элемент" .setId(уникальный_ид) профит. В адаптерах по дефолту не ставятся ИД для элементов, они идентифицируются по позиции, которую можно найти на входе в OnItemClick.
Семь раз отмерь - поставь студию.
Эклипс не студия, ошибка вылетит - не исправишь.
Скажи мне кто твой друг, и оба поставили студию.
Студия - свет, а эклипс - тьма.

akhan
Сообщения: 4
Зарегистрирован: 08 янв 2015, 13:43

Re: Урок 40. LayoutInflater. Учимся использовать.

Сообщение akhan » 12 янв 2015, 07:52

Всем привет.
Как я понял - инфлейтор позволяет парсить xml файл и "выдернуть" оттуда вью элемент.
Но зачем?
Почему нельзя описать, программно создать необходимый вью в том же исходнике перед его использованием?
Как в уроках 16 и 17?
Например,
Button btn1 = new Button(this);
btn1.setText("Button1");
linLayout.addView(btn1, leftMarginParams);

Аватара пользователя
klblk
Сообщения: 1097
Зарегистрирован: 18 окт 2012, 11:17
Откуда: г. Красноярск

Re: Урок 40. LayoutInflater. Учимся использовать.

Сообщение klblk » 12 янв 2015, 08:45

akhan писал(а):Всем привет.
Как я понял - инфлейтор позволяет парсить xml файл и "выдернуть" оттуда вью элемент.
Но зачем?
Почему нельзя описать, программно создать необходимый вью в том же исходнике перед его использованием?
Как в уроках 16 и 17?
Например,
Button btn1 = new Button(this);
btn1.setText("Button1");
linLayout.addView(btn1, leftMarginParams);
Это уроки, и тут рассматриваются разные подходы.
Но неужели вам проще программно создавать View? А если их будет полтора десятка с различными параметрами и различной степенью вложенности?

akhan
Сообщения: 4
Зарегистрирован: 08 янв 2015, 13:43

Re: Урок 40. LayoutInflater. Учимся использовать.

Сообщение akhan » 12 янв 2015, 09:29

klblk писал(а):
akhan писал(а):Всем привет.
Как я понял - инфлейтор позволяет парсить xml файл и "выдернуть" оттуда вью элемент.
Но зачем?
Почему нельзя описать, программно создать необходимый вью в том же исходнике перед его использованием?
Как в уроках 16 и 17?
Например,
Button btn1 = new Button(this);
btn1.setText("Button1");
linLayout.addView(btn1, leftMarginParams);
Это уроки, и тут рассматриваются разные подходы.
Но неужели вам проще программно создавать View? А если их будет полтора десятка с различными параметрами и различной степенью вложенности?
Я имел ввиду для создания простых списков с одним TextView. Или TextView c флажком. Ради этого создавать отдельный файл, думаю не оптимально и растратно.

Аватара пользователя
klblk
Сообщения: 1097
Зарегистрирован: 18 окт 2012, 11:17
Откуда: г. Красноярск

Re: Урок 40. LayoutInflater. Учимся использовать.

Сообщение klblk » 12 янв 2015, 11:29

Для создание списков есть ListView, читайте дальше уроки.

Радислав Гандопас
Сообщения: 9
Зарегистрирован: 29 апр 2015, 09:47

Re: Урок 40. LayoutInflater. Учимся использовать.

Сообщение Радислав Гандопас » 03 июн 2015, 11:00

Смотрим лог:
Class of view1: class android.widget.LinearLayout
Class of layoutParams of view1: class android.widget.LinearLayout$LayoutParams
Class of view2: class android.widget.RelativeLayout
Class of layoutParams of view2: class android.widget.LinearLayout$LayoutParams

Соответственно LayoutParams для view1 и view2 будет LinearLayout$LayoutParams, т.к. linLayout и relLayout имеют родителя LinearLayout. И LayoutParams берут от него.
Что-то не понятно почему LayoutParams для обоих View одинаковые, ведь родителей мы указывали разных. relLayout и linLayout судя по коду имеют разных родителей и судя по библиотекам LinearLayout не является родителем для RelativeLayout.

Радислав Гандопас
Сообщения: 9
Зарегистрирован: 29 апр 2015, 09:47

Re: Урок 40. LayoutInflater. Учимся использовать.

Сообщение Радислав Гандопас » 03 июн 2015, 11:03

Радислав Гандопас писал(а):
Смотрим лог:
Class of view1: class android.widget.LinearLayout
Class of layoutParams of view1: class android.widget.LinearLayout$LayoutParams
Class of view2: class android.widget.RelativeLayout
Class of layoutParams of view2: class android.widget.LinearLayout$LayoutParams

Соответственно LayoutParams для view1 и view2 будет LinearLayout$LayoutParams, т.к. linLayout и relLayout имеют родителя LinearLayout. И LayoutParams берут от него.
Что-то не понятно почему LayoutParams для обоих View одинаковые, ведь родителей мы указывали разных. relLayout и linLayout судя по коду имеют разных родителей и судя по библиотекам LinearLayout не является родителем для RelativeLayout.
Или это все потому что LayoutParams является вложенным в LinearLayout? Или еще потому что сам RelativeLayout является вложенным в LinearLayout?

Аватара пользователя
doter.ua
Сообщения: 1106
Зарегистрирован: 23 ноя 2013, 16:08
Откуда: Ukraine

Re: Урок 40. LayoutInflater. Учимся использовать.

Сообщение doter.ua » 03 июн 2015, 20:27

Радислав Гандопас писал(а): Что-то не понятно почему LayoutParams для обоих View одинаковые, ведь родителей мы указывали разных. relLayout и linLayout судя по коду имеют разных родителей и судя по библиотекам LinearLayout не является родителем для RelativeLayout.
Изображение
Figure 1. Visualization of a view hierarchy with layout parameters associated with each view.
Семь раз отмерь - поставь студию.
Эклипс не студия, ошибка вылетит - не исправишь.
Скажи мне кто твой друг, и оба поставили студию.
Студия - свет, а эклипс - тьма.

rainman
Сообщения: 1
Зарегистрирован: 04 ноя 2020, 03:15

Re: Урок 40. LayoutInflater. Учимся использовать.

Сообщение rainman » 04 ноя 2020, 04:38

Отличная и очень нужная тема. Немного поковырялся, вот что накодил. Короткие понятные примеры добавления и удаления View. Доступ к дочерним View.

MainActivity.java

Код: Выделить всё

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    // Объявляем переменные
    EditText et_item_desc;
    LayoutInflater inflater;
    View item_layer;
    LinearLayout ll_item_list;
    FrameLayout fl_item;
    TextView tv_item_desc, tv_item_id;
    int item_id;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    // метод добавления макета в список

    public void AddItem(View view) {

        inflater = getLayoutInflater();
        item_layer = inflater.inflate(R.layout.item, null); //находим макет
        ll_item_list = findViewById(R.id.ll_item_list); // объявляем родителя для макета
        et_item_desc = findViewById(R.id.et_item_desc); // TV ввода description
        ll_item_list.addView(item_layer); //добавляю макет

        // получаем количество строк
        item_id = ll_item_list.getChildCount();
        String str_item_id = String.valueOf(item_id);


        // находим текствью
        fl_item = (FrameLayout) ll_item_list.getChildAt(item_id - 1); // Определяем последний добавленный макет по индексу ("-1" потому что нумерация с нуля)
        tv_item_id = (TextView) fl_item.getChildAt(0); // находим Textview 1 по индексу
        tv_item_desc = (TextView) fl_item.getChildAt(1); // находим Textview 2 по индексу

        // присваеваем текст
        tv_item_id.setText(str_item_id); // номер строки
        tv_item_desc.setText("Пользовательский текст №: " + str_item_id); // тут все понятно (это для теста, чтоб не вводить текст вручную)
        // tv_item_desc.setText(String.valueOf(et_item_desc.getText())); // раскомментируй (рабочий вариант заполнение десприпшена макета)
    }

    // удаляем макет по индексу
    public void DelItem(View view){
        fl_item = (FrameLayout) view.getParent(); // определяем родителя
        ll_item_list = (LinearLayout) fl_item.getParent(); // определяем родителя
        int id = ll_item_list.indexOfChild(fl_item); // получаем индекс
        ll_item_list.removeViewAt(id); // удаляем макет по индексу

        // обновляем TextView с поцией макета в родителе
        for (int i = id; i <= ll_item_list.getChildCount() - 1; i++){  //начиная с удаленного индекса до последнего в списке ("-1" потому что нумерация с нуля)
            fl_item = (FrameLayout) ll_item_list.getChildAt(i); // Находим макет по индексу
            tv_item_id = (TextView) fl_item.getChildAt(0); // находим textviw по индексу
            tv_item_id.setText(String.valueOf(i + 1)); // переписываем порядковый номер
        }
    }
}
item.xml

Код: Выделить всё

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

    <TextView
        android:id="@+id/tv_item_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="10dp"
        android:text="10" />

    <TextView
        android:id="@+id/tv_item_desc"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="40dp" />

    <Button
        android:id="@+id/btn_item_del"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_gravity="right"
        android:layout_marginRight="10dp"
        android:background="@android:drawable/ic_delete"
        android:onClick="DelItem" />

    <Button
        android:id="@+id/btn_item_edit"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_gravity="right"
        android:layout_marginRight="50dp"
        android:background="@android:drawable/ic_menu_edit" />
</FrameLayout>
activity_main.xml

Код: Выделить всё

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn_item_add"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:background="@android:drawable/ic_input_add"
        android:onClick="AddItem"
        app:layout_constraintBottom_toBottomOf="@+id/et_item_desc"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="@+id/et_item_desc" />

    <EditText
        android:id="@+id/et_item_desc"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:autofillHints=""
        android:ems="10"
        android:inputType="textPersonName"
        app:layout_constraintEnd_toStartOf="@+id/btn_item_add"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ScrollView
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/et_item_desc">

        <LinearLayout
            android:id="@+id/ll_item_list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical" />
    </ScrollView>

</androidx.constraintlayout.widget.ConstraintLayout>

Ответить