5 / 5 / 0
Регистрация: 02.04.2013
Сообщений: 88
1

Создание блока Лэйаутов со своей структурой из кода

21.08.2013, 17:06. Показов 1905. Ответов 22
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте. В общем такая задача:
Есть блок состоящий из LinearLayout, текстового поля и еще одного Linearlayout. В каждом LinearLayout свои эллементы. В общем структура не важна. Есть LinearLayout содержащий некую структуру. Из xml файла берутся данные, в зависимости от которых должно быть построенно определенное количество таких блоков с Лэйаутами и заполненно данными из xml-файла(каждый блок своими данными). Создавать всю эту структуру программно(из кода) очень сложно(нужно создать Лэйаут с параметрами, потом создать следующий лэйаут со своими параметрами и своими эллементами, указав родительский объект ранее созданный лэйаут). Получится очень сложно и громоздко в коде. Мне решение видится в создании какого-нибудь шаблона, где прописана структура эллементов и их параметры. В зависимости от данных из xml-файла создаем нужное количество блоков из такого шаблона, и заполняем их данными.
Вопрос в том, как реализовать такой шаблон?
Может светлые умы что подскажут?
ЗЫ: Фрагменты не предлагать, реализовать нужно для андроид 2.3. Фрагменты только с 3 Андроида.
Спасибо.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
21.08.2013, 17:06
Ответы с готовыми решениями:

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

Нужно ли определение блока кода при одной строке кода?
Вопрос исключительно блока с одной строкой кода. Объясните пожалуйста, каким образом стоит...

Создание модели со сложной структурой
Добрый вечер. Сегодня столкнулся с такой проблемой, при создании метода добавления для модели со...

Внедрение кода своей DLL в процесс
Есть DLL сл. содержания: var form: TForm1; begin form := TForm1.Create(nil); ...

22
Android Developer
131 / 131 / 6
Регистрация: 05.07.2013
Сообщений: 205
21.08.2013, 17:43 2
Termit___, мне видится два решения такой задачи. Опишу первый. Нужно определится сколько будет схожих блоков (логических блоков), и как они должны выглядеть. Для каждого логического блока создаётся свой xml файл разметки и форматируется так, как должен выглядеть блок. Далее создаётся класс, наследник LinearLayout, в котором инициализируется разметка и все необходимые View'ы. Пишутся методы для вывода данных (это могут быть отдельные методы для отдельных полей или только один, принимающий какой-либо объект, который содержит информацию о всех полях). А дальше проще, во время парсинга xml'ки с данными, создаются нужные View'шки логических блоков, им устанавливаются данные и это всё помещается в ScrollView на форме. Если у всех View'шек есть схожие параметры, то можно вообще применить паттерн Фабрика, что упростит создание и манипуляции с блоками..
0
5 / 5 / 0
Регистрация: 02.04.2013
Сообщений: 88
21.08.2013, 17:55  [ТС] 3
Количество схожих блоков будет разное в зависимости от того какой xml файл передастся с предыдущего активити(зависит от выбора пользователя в том Активити). В том то и весь интерес, что блоков должно быть столько, сколько будет указано в xml файле. У View-эллементов параметры раззные - расположение, цвет теста, картинка, отступы и т.д.
Что есть паттерн Фабрика? 0_о

Добавлено через 1 минуту
Если быть точнее то количество может быть 1,2,3 или 10.

Добавлено через 3 минуты
Есть еще такая мысль: Создать эти блоки вручную в лэйауте. Сразу максимальное количество(10) И в зависимости от того сколько будет нужно, из кода лишние удалить(например если нужно чтобы осталось 3, то 7 эллементов удаляем). И обращаться к статически созданным из программы будет проще, чем к динамически(программно) созданным. Как считаете?
0
Android Developer
131 / 131 / 6
Регистрация: 05.07.2013
Сообщений: 205
21.08.2013, 18:01 4
Termit___, вы не поняли. Я имею ввиду не общее количество View'ов, а количество логических единиц. Допустим есть блок ИК (инфо о клиенте: имя, адрес, телефон) и есть блок ИЗ (инфо о задании: название, тип, количество исполнителей, прогресс выполнения, дата завершения). Количество блоков ИК и ИЗ может измерятся сотнями, но логических единиц всегда две и выглядят они практически одинаково. Вот для них и создать собственные View'вы. Шаблоны на вашем языке.
Паттерн фабрика
0
5 / 5 / 0
Регистрация: 02.04.2013
Сообщений: 88
21.08.2013, 19:38  [ТС] 5
Цитата Сообщение от Wenceslaus Посмотреть сообщение
Далее создаётся класс, наследник LinearLayout, в котором инициализируется разметка и все необходимые View'ы.
Можно поподробнее об этом? Как в классе инициализировать разметку? Один фиг в коде прописвать надо? Или можно как то прописать всю структуру с параметрами в xml-файле, к которуму бует обращаться класс при создании View-элементов?
0
1162 / 986 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
21.08.2013, 20:51 6
Java
1
2
3
LayoutInflater inflater = LayoutInflater.from(context);
View viewType1 = inflater.inflate(R.layout.view1, parent, false);
View viewType2 = inflater.inflate(R.layout.view2, parent, false);
0
5 / 5 / 0
Регистрация: 02.04.2013
Сообщений: 88
22.08.2013, 09:47  [ТС] 7
V0v1k, Не могли бы Вы пояснить? viewType1 что это? Создаваемый view с параметрами наследуемыми от R.layout.view1?

Добавлено через 28 минут
Т.е. достаточно вручную создать 1 блок, а остальные инфлэйтером "клонировать" нужное количество раз? Я прваильно понял?
0
1162 / 986 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
22.08.2013, 11:28 8
Цитата Сообщение от Termit___ Посмотреть сообщение
Т.е. достаточно вручную создать 1 блок, а остальные инфлэйтером "клонировать" нужное количество раз? Я прваильно понял?
типа того.
Цитата Сообщение от Termit___ Посмотреть сообщение
viewType1 что это?
ну, как писал Wenceslaus, это блок ИК, и так создаете сколько вам нужно экземпляров, viewType2 это блок ИЗ, тоже создаете сколько нужно экземпляров
Java
1
2
3
4
5
6
7
8
9
10
for(...){
      viewType1 = inflater.inflate(R.layout.view1, parent, true); //если true, viewType1  автоматически добавится в parent
      TextView tv = viewType1.findViewById(...);
       ...
}
for(...){
      viewType2 = inflater.inflate(R.layout.view2, parent, true);
      TextView tv = viewType2.findViewById(...);
       ...
}
1
Android Developer
131 / 131 / 6
Регистрация: 05.07.2013
Сообщений: 205
22.08.2013, 12:08 9
Termit___, куда уж подробнее? Попробую на примере объяснить. Есть некая xml структура
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
 
    <TextView
        android:id="@+id/txt_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="name" />
 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
 
        <TextView
            android:id="@+id/txt_adress"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="adress" />
 
        <TextView
            android:id="@+id/txt_phone"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="phone" />
 
    </LinearLayout>
 
</LinearLayout>
В ней настраиваете весь внешний вид.
Есть класс View, который инициализирует разметку
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public class BlockView extends LinearLayout {
    
    private TextView name;
    private TextView adress;
    private TextView phone;
    
    public BlockView(Context context) {
        super(context);
        init();
    }
    
    public BlockView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
 
    public BlockView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }
 
    private void init(){
        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.block, this, true);
        name = (TextView) findViewById(R.id.txt_name);
        adress = (TextView) findViewById(R.id.txt_adress);
        phone = (TextView) findViewById(R.id.txt_phone);
    }
 
    public String getName() {
        return name.getText().toString();
    }
 
    public void setName(String name) {
        this.name.setText(name);
    }
 
    public String getAdress() {
        return adress.getText().toString();
    }
 
    public void setAdress(String adress) {
        this.adress.setText(adress);
    }
 
    public String getPhone() {
        return phone.getText().toString();
    }
 
    public void setPhone(String phone) {
        this.phone.setText(phone);
    }
 
 
}
В нём содержаться методы доступа к элементам, дополнительные преобразования текста (к примеру, перевод строки или написание только в верхнем регистре) и пр. настройки (если нужны) также пишутся здесь
И уже в самом коде, где идёт парсинг xml с данными вы и создаёте нужные блоки, примерно так
Java
1
2
3
4
5
6
7
while (xml.hasNext()) {
    BlockView blockView = new BlockView(MainActivity.this);
    blockView.setName(xml.getName());
    blockView.setAdress(xml.getAdress());
    blockView.setPhone(xml.getPhone());
    scrollView.addView(blockView);
}
Здесь описан только один блок, ведь остальные делаются аналогично, если понятен принцип.
Но, если такие логические блоки будут у вас использоваться только в одном месте и на одном Activity, можно не заморачиваться и сделать, как советовал V0v1k. Возможно именно так вам и проще будет реализовывать.
0
5 / 5 / 0
Регистрация: 02.04.2013
Сообщений: 88
23.08.2013, 12:20  [ТС] 10
V0v1k, Огромное спасибо! Все получилось. Вчера весь день кодил, сегодня докодил(обьем большой кроме этой задачи был). Все строится как я и хотел. Вы меня спасли уже 105 раз. Еще раз спасибо. =)
0
5 / 5 / 0
Регистрация: 02.04.2013
Сообщений: 88
25.08.2013, 11:40  [ТС] 11
Люди, подскажите еще немного. Вот создались эти блоки элементов нужное количество раз. А как обратиться к этим элементам? Нужно поменять значение(например в TextView), а меняется только в самом первом блоке столько раз сколько проходит цикл и остается значение последнего эллемента. Остальные эллементы в блоках остаются по умолчанию как в xml файле лэйауте из которого берется структура для инфлэйтера.
Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
for (int i=0; i < 2; ++i) {
         LayoutInflater inflater = getLayoutInflater();
         View block = inflater.inflate(R.layout.sub, ll_sub_1, true);
         TextView tv_sub_1_1 = (TextView) findViewById(R.id.tv_sub_1_1);
                      if (i==0){
                        tv_sub_1_1.setText("Текст берем из места 0");
}          
                     if (i==1){
                        tv_sub_1_1.setText("Текст берем из места 1");
}          
                      if (i==2){
                       tv_sub_1_1.setText("Текст берем из места 2");
}

После отработки такого кода получается список из блоков:
Тест берем из места 2
TextView
TextView

Хотя нужно:
Текст берем из места 0
Текст берем из места 1
Текст берем из места 2

Это конечно сильно урощено(структура посложнее), но суть проблемы отражает. Подскажите, где я торможу?
0
1162 / 986 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
25.08.2013, 12:36 12
Java
1
 TextView tv_sub_1_1 = (TextView) block.findViewById(R.id.tv_sub_1_1);
0
5 / 5 / 0
Регистрация: 02.04.2013
Сообщений: 88
25.08.2013, 13:13  [ТС] 13
Не. То же самое.
0
1162 / 986 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
25.08.2013, 13:19 14
должно работать
0
5 / 5 / 0
Регистрация: 02.04.2013
Сообщений: 88
25.08.2013, 20:14  [ТС] 15
Нет и все. Уже перепробовал по всякому. И цикл крутил-менял по разному, и условие. Меняет только элементы в первом блоке, остальные по умолчанию. Можно как то еще реализовать это дело?
0
1162 / 986 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
25.08.2013, 20:20 16
можете выложить проект?
0
5 / 5 / 0
Регистрация: 02.04.2013
Сообщений: 88
25.08.2013, 20:56  [ТС] 17
Кода из активити недостаточно будет? 0_о
0
1162 / 986 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
25.08.2013, 21:07 18
неа, но можете вдобавок и его отдельно скопировать.
0
5 / 5 / 0
Регистрация: 02.04.2013
Сообщений: 88
26.08.2013, 12:54  [ТС] 19
Нашел в одном уроке по андроиду:
Обратите внимание - третий параметр inflate мы указал и false. Т.е. мы не стали сразу добавлять создаваемый View-элемент к linLayout, а делаем это в конце кода методом addView. Этому есть объяснение. Если бы мы указал и true -то метод добавил бы item к linLayout и вернул бы нам linLayout, общий для всех пунктов списка. Через linLayout заполнять TextView необходимым нам текстом было бы затруднительно. Поэтому мы получаем пункт
item ( FrameLayout) , заполняем его TextView данными и только потом помещаем к остальным пунктам в
linLayout методом addView.
Интересно почему затруднительно? Ктонибудь знает? Видимо поэтому у меня не заполняется данными так как надо. Может как то воспользоваться false и addView?

Добавлено через 2 минуты
V0v1k, Код проблемного активити я отправил в ЛС.
0
1162 / 986 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
26.08.2013, 16:01 20
нужен весь проект.

Добавлено через 2 часа 22 минуты
первый косяк
Java
1
2
3
4
5
6
7
8
9
10
11
for (int i=0; i < sub_q; ++i) {
               Integer x = 0;
               if (x==0) {
                            x=x+1;
                                      ...
              }
              if (x==1) {
                            x=x+1;
                                       ...
            }
}
здесь всегда будут оба if'а выполняться при каждой итерации. зачем вы "x" добавили? вам "i" мало?

я бы это сделал через ListView.

Добавлено через 7 минут
и да, в уроке правильно подмечено, делайте так
Java
1
2
View block_skill = inflater.inflate(R.layout.sub, ll_sub_1, false);
ll_sub_1.addView(block_skill);
а вообще лучше ListView использовать.

Добавлено через 15 минут
и в активити Second тоже ListView используйте.
1
26.08.2013, 16:01
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.08.2013, 16:01
Помогаю со студенческими работами здесь

Создание динамического массива в соответствии со структурой файла
Добрый день. Помогите написать программу, она должна открыть файл, посчитать сколько там строк,...

Создание моделей в Django с json подобной структурой
Имеется django модель, описывающая заведение. Необходимо определить поле, которое будет хранить...

Возврат кода ошибки из своей функции, возможно ли
Доброго времени суток. Пишу функцию, которая возвращает строку. Как быть с кодом возврата, если...

Создание формы для ввода данных с иерархичной структурой
Есть база данных с созданной иерархичной структурой к сожалению мне не удается создать форму...

Создание базы данных SQL. Управление данными и структурой таблиц
Здравствуйте добрые люди)) Моя программа работает с БД MSAccess мне сказали чтоб база должна...

После окончания работы со структурой, она будет почищена сборщиком. Что произойдет со структурой в неуправляемой памяти
Доброго времени суток. Прочитал закрепленный топик &quot;Класс Marshal, использование PInvoke,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru