powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Android [игнор отключен] [закрыт для гостей] / ExpandableListView : <TextView> + <CheckBox>
3 сообщений из 3, страница 1 из 1
ExpandableListView : <TextView> + <CheckBox>
    #39471696
AndroidNeedHelp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте, товарищи!
Как оказалось, новичку сделать простецкий список с галочками - проблема из глобальных
Суть проста: список представляет текст + checkbox.
Тыкаем на список (или чекбокс - не принципиально, хоть как-нибудь уже). В БД сохраняется единичка, на экране в квадратик ставится галочка. При следующей загрузке списка, состояние = 1 подгружается из БД и список отображается уже с галочкой, пока очередное нажатие её не снимет
Стыдно признаваться - сижу уже третий день

В качестве элемента ListView (строки) лежит свой layout:
LinearLayout
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <TextView
        android:id="@+id/txtJobText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:paddingBottom="5dp"
        android:paddingTop="5dp"
        android:text="TextView"
        android:textAlignment="textEnd" />
    <CheckBox
        android:id="@+id/chkJobChecker"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center" />
</LinearLayout>

Данные для ExpandableListView хранятся в SQLite
funGetJobsFromSQL()
Код: 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.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
    // Загрузка списка работ с группировками
    private void funGetJobsFromSQL(){
        String query;
        Cursor cursGrp, cursJob;
        // Создадим и откроем для чтения базу данных
        DbHelper mDbHelper = new DbHelper(this);
        SQLiteDatabase testDB = mDbHelper.getReadableDatabase();

        // Коллекция, где хранятся заголовки групп
        ArrayList<ItemJobs> arrJobsGrp = new ArrayList<ItemJobs>();
        // Коллекция подчинённых элементов - собственно сами работы
        ArrayList<ItemJobs> arrJobs = new ArrayList<ItemJobs>();
        // Создаем общую коллекцию для коллекций элементов - то есть, коллекция НАБОРОВ (по числу групп)
        ArrayList<ArrayList<ItemJobs>> arrJobsPack = new ArrayList<>();


        // открываем родительские элементы
        query = "SELECT JobID, JobText, ParentID, OnControl, JobChecked"
                + " FROM tblJobs"
                + " WHERE ParentID = 0";
        cursGrp = testDB.rawQuery(query, null);

        try {
            if (cursGrp.getCount() > 0) {
                // Проходим через все ряды
                while (cursGrp.moveToNext()) {
                    // Используем индекс для получения строки или числа
                    Integer JobID = cursGrp.getInt(cursGrp.getColumnIndex("JobID"));
                    String JobText = cursGrp.getString(cursGrp.getColumnIndex("JobText"));
                    Integer ParentID = cursGrp.getInt(cursGrp.getColumnIndex("ParentID"));
                    Integer OnControl = cursGrp.getInt(cursGrp.getColumnIndex("OnControl"));
                    Integer JobChecked = cursGrp.getInt(cursGrp.getColumnIndex("JobChecked"));
                    Integer IsChecked = 0; // в заголовках не используем

                    arrJobsGrp.add(
                            new ItemJobs(
                                    JobID.toString(),
                                    JobText,
                                    ParentID.toString(),
                                    OnControl.toString(),
                                    JobChecked.toString(),
                                    IsChecked.toString()
                            )
                    );

                    arrJobs = new ArrayList<ItemJobs>();

                    // открываем сами работы
                    query = "SELECT JB.JobID, JB.JobText, JB.ParentID, JB.OnControl, JB.JobChecked, CHK.IsChecked"
                            + " FROM tblJobs AS JB "
                            + " LEFT OUTER JOIN tblJobsChecked AS CHK "
                            + " ON CHK.JobID = JB.JobID AND CHK.MailID = " + sMailID + " AND CHK.RecordID = " + sRecordID + " AND CHK.PersID = " + sPersID + ""
                            + " WHERE JB.ParentID = " + JobID.toString()
                            + " ORDER BY JB.OnControl DESC, JB.JobText";
                    cursJob = testDB.rawQuery(query, null);
                    Log.d("", "Done");
                    try {
                        if (cursJob.getCount() > 0) {
                            // Проходим через все ряды
                            while (cursJob.moveToNext()) {
                                // Используем индекс для получения строки или числа
                                JobID = cursJob.getInt(cursJob.getColumnIndex("JobID"));
                                JobText = cursJob.getString(cursJob.getColumnIndex("JobText"));
                                ParentID = cursJob.getInt(cursJob.getColumnIndex("ParentID"));
                                OnControl = cursJob.getInt(cursJob.getColumnIndex("OnControl"));
                                JobChecked = cursJob.getInt(cursJob.getColumnIndex("JobChecked"));
                                IsChecked = cursJob.getInt(cursJob.getColumnIndex("IsChecked"));

                                arrJobs.add(
                                        new ItemJobs(
                                                JobID.toString(),
                                                JobText,
                                                ParentID.toString(),
                                                OnControl.toString(),
                                                JobChecked.toString(),
                                                IsChecked.toString()
                                        )
                                );
                                Log.d("", "Done");
                            }
                        }
                    } finally {
                        cursJob.close(); // Всегда закрываем курсор после чтения
                    }

                    try {
                        arrJobsPack.add(arrJobs);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        } finally {
            cursGrp.close(); // Всегда закрываем курсор после чтения
        }

        // список атрибутов групп для чтения
        String groupFrom[] = new String[] { "JobText" };
        // список ID view-элементов, в которые будет помещены атрибуты групп
        int groupTo[] = new int[] { R.id.txtJobGrp };
        // список атрибутов элементов для чтения
        String childFrom[] = new String[] { "JobText", "IsChecked" };
        // список ID view-элементов, в которые будет помещены атрибуты элементов
        int childTo[] = new int[] { R.id.txtJobText, R.id.chkJobChecker };

        // адаптер для списка с подгруппами
        SimpleExpandableListAdapter adapter = new SimpleExpandableListAdapter(
                this,
                arrJobsGrp,
                R.layout.item_lst_jobs_grp,
                groupFrom,
                groupTo,
                arrJobsPack,
                R.layout.item_lst_jobs,
                childFrom,
                childTo);

        ExpandableListView expListView = (ExpandableListView) findViewById(R.id.expListJobs);
        expListView.setAdapter(adapter);

        Log.d("", "Done");

    }

Обработку нажатия на элемент списка сделал - данные сохраняются в SQL
обработка нажатия на элемент списка
Код: 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.
        // переменная списка
        expListJobs = (ExpandableListView) findViewById(R.id.expListJobs);
        // Обработчик нажатия на элемент
        expListJobs.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
            public boolean onChildClick(ExpandableListView parent, View v,
                                        int groupPosition, int childPosition, long id) {
                ItemJobs itmItem = (ItemJobs) expListJobs.getExpandableListAdapter().getChild(groupPosition, childPosition);
                /*
                CheckBox cb = (CheckBox)v.findViewById( R.id.chkJobChecker );
                if( cb != null )
                    cb.toggle();
                */
                if (itmItem.get(itmItem.KEY_IsChecked) == "1") {
                    itmItem.put(itmItem.KEY_IsChecked, "0");
                    funUpdateJobState(itmItem.get(ItemJobs.KEY_JobID).toString(), false);
                } else {
                    itmItem.put(itmItem.KEY_IsChecked, "1");
                    funUpdateJobState(itmItem.get(ItemJobs.KEY_JobID).toString(), true);
                }

                Toast.makeText(ActivityPersEdit.this,
                        "groupPos: " + groupPosition + ", childPos: " + childPosition + ", id: " + id
                                +"\nKEY_JobID: " + itmItem.get(ItemJobs.KEY_JobID),
                        Toast.LENGTH_SHORT).show();
                return false;
            }
        });

Но как мне поставить эту галочку???
Интернет дал подсказку - что без перегрузки класса SimpleExpandableListAdapter - никак
Нашёл тут при мер для обычного ListView (не Expandable)

Пытаюсь делать по-аналогии, но появляются ошибки на ошибке!
перегруженный класс JobListAdapter
Код: 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.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CheckedTextView;
import android.widget.SimpleExpandableListAdapter;
import android.widget.TextView;

import java.util.List;
import java.util.Map;

// Перегружаем адаптер, чтобы отобразить галочки

public class JobListAdapter extends SimpleExpandableListAdapter {
    private List<? extends Map<String, ?>> mGroupData;
    private int mExpandedGroupLayout;
    private int mCollapsedGroupLayout;
    private String[] mGroupFrom;
    private int[] mGroupTo;

    private List<? extends List<? extends Map<String, ?>>> mChildData;
    private int mChildLayout;
    private int mLastChildLayout;
    private String[] mChildFrom;
    private int[] mChildTo;

    private LayoutInflater mInflater;

    public JobListAdapter(
            Context context,
            List<? extends Map<String, ?>> groupData,
            int groupLayout,
            String[] groupFrom,
            int[] groupTo,
            List<? extends List<? extends Map<String, ?>>> childData,
            int childLayout,
            String[] childFrom,
            int[] childTo) {
        super(context, groupData, groupLayout, groupFrom, groupTo, childData, childLayout, childFrom, childTo);
    }


    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        //return super.getChildView(groupPosition, childPosition, isLastChild, convertView, parent);

        View v;
        if (convertView == null) {
            v = newChildView(isLastChild, parent);
        } else {
            v = convertView;
        }
        bindView(v, mChildData.get(groupPosition).get(childPosition), mChildFrom, mChildTo);
        return v;

        /*
        View row = convertView;

        if (row == null) {
            LayoutInflater inflater = getLayoutInflater();
            row = inflater.inflate(R.layout.item_lst_jobs, parent, false);
        } 
        CheckBox chkJobChecker = (CheckBox) row.findViewById(R.id.chkJobChecker);
            chkJobChecker.setChecked(true);
        return row;
        */
        
    }

    private void bindView(View view, Map<String, ?> data, String[] from, int[] to) {
        int len = to.length;

        for (int i = 0; i < len; i++) {
            TextView v = (TextView)view.findViewById(to[i]);
            if (v != null) {
                v.setText((String)data.get(from[i]));
            }
        }
    }

}


Пример из тынца не заработал (строчки закомментированы /* */), потому что компилятор не смог найти getLayoutInflater()
Хорошо, понимаю, не маленький... Зашёл в библиотеку класса - скопировал код:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
        View v;
        if (convertView == null) {
            v = newChildView(isLastChild, parent);
        } else {
            v = convertView;
        }
        bindView(v, mChildData.get(groupPosition).get(childPosition), mChildFrom, mChildTo);
        return v;



Он начал ругаться на то что не может найти bindView
Перегрузил и этот метод, благо, он маленький...
Но теперь AndrStudio не нравится mChildData, mChildFrom, mChildTo
Я их, конечно, постарался объявить в классе (глянув, на родительский)
вот так
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
public class JobListAdapter extends SimpleExpandableListAdapter {
    private List<? extends Map<String, ?>> mGroupData;
    private int mExpandedGroupLayout;
    private int mCollapsedGroupLayout;
    private String[] mGroupFrom;
    private int[] mGroupTo;

    private List<? extends List<? extends Map<String, ?>>> mChildData;
    private int mChildLayout;
    private int mLastChildLayout;
    private String[] mChildFrom;
    private int[] mChildTo;

    private LayoutInflater mInflater;

    public JobListAdapter(.......


но эти переменные не заполняются!
Я думал, что методы и переменные родительского класса наследуются, но я что-то вообще в тупике...
Подскажите, что мне делать?
Присвоить им значения как это делается в родительском классе?
пример из package android.widget
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
public SimpleExpandableListAdapter(Context context,
            List<? extends Map<String, ?>> groupData, int expandedGroupLayout,
            int collapsedGroupLayout, String[] groupFrom, int[] groupTo,
            List<? extends List<? extends Map<String, ?>>> childData,
            int childLayout, int lastChildLayout, String[] childFrom,
            int[] childTo) {
        mGroupData = groupData;
        mExpandedGroupLayout = expandedGroupLayout;
        mCollapsedGroupLayout = collapsedGroupLayout;
        mGroupFrom = groupFrom;
        mGroupTo = groupTo;
        
        mChildData = childData;
        mChildLayout = childLayout;
        mLastChildLayout = lastChildLayout;
        mChildFrom = childFrom;
        mChildTo = childTo;
        
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }


Или я свернул вообще не туда и есть способ легче?
Нужно всего-то - "галочки"...

спс, ув. модератору :)
...
Рейтинг: 0 / 0
ExpandableListView : <TextView> + <CheckBox>
    #39471890
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я просто там направление, может этого будет достаточно https://www.google.com/search?q=android viewholder
Мне хватало... А там и галочки и кнопочки можно разместить и запомнить.
...
Рейтинг: 0 / 0
ExpandableListView : <TextView> + <CheckBox>
    #39472452
AndroidNeedHelp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
wadman , спасибо!
Паттерн ViewHolder я всё-же использовать не стал, но подсмотрел в одном из примеров, что переменные класса всё-таки инициализируются в конструкторе
Я так и сделал - и это был тот шаг, до которого я не дошёл вчера. Всё заработало
Ну а так как в класс передаётся массив данных mChildData, то через него я и определяю, нужна галочка или нет:

Код: java
1.
2.
3.
4.
5.
6.
        CheckBox chkJobChecker = (CheckBox) row.findViewById(R.id.chkJobChecker);
        if (mChildData.get(groupPosition).get(childPosition).get("IsChecked") == "1") {
            chkJobChecker.setChecked(true);
        } else {
            chkJobChecker.setChecked(false);
        }


Полный код класса:
перегруженный ListAdapter
Код: 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.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
package ru.spline.brykalien.splinemobile.ListItems;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CheckedTextView;
import android.widget.SimpleExpandableListAdapter;
import android.widget.TextView;

import java.util.List;
import java.util.Map;

import ru.spline.brykalien.splinemobile.R;

// Перегружаем адаптер, чтобы отобразить свои галочки

public class JobListAdapter extends SimpleExpandableListAdapter {
    private List<? extends Map<String, ?>> mGroupData;
    private int mExpandedGroupLayout;
    private int mCollapsedGroupLayout;
    private String[] mGroupFrom;
    private int[] mGroupTo;

    private List<? extends List<? extends Map<String, ?>>> mChildData;
    private int mChildLayout;
    private int mLastChildLayout;
    private String[] mChildFrom;
    private int[] mChildTo;

    private LayoutInflater mInflater;

    public JobListAdapter(
            Context context,
            List<? extends Map<String, ?>> groupData,
            int groupLayout,
            String[] groupFrom,
            int[] groupTo,
            List<? extends List<? extends Map<String, ?>>> childData,
            int childLayout,
            String[] childFrom,
            int[] childTo) {

        super(context, groupData, groupLayout, groupFrom, groupTo, childData, childLayout, childFrom, childTo);

        mGroupData = groupData;
        mExpandedGroupLayout = groupLayout;
        mCollapsedGroupLayout = groupLayout;
        mGroupFrom = groupFrom;
        mGroupTo = groupTo;

        mChildData = childData;
        mChildLayout = childLayout;
        mLastChildLayout = childLayout;
        mChildFrom = childFrom;
        mChildTo = childTo;

        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }


    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        //return super.getChildView(groupPosition, childPosition, isLastChild, convertView, parent);

        View row;
        if (convertView == null) {
            row = newChildView(isLastChild, parent);
        } else {
            row = convertView;
        }

        CheckBox chkJobChecker = (CheckBox) row.findViewById(R.id.chkJobChecker);
        if (mChildData.get(groupPosition).get(childPosition).get("IsChecked") == "1") {
            chkJobChecker.setChecked(true);
        } else {
            chkJobChecker.setChecked(false);
        }

        bindView(row, mChildData.get(groupPosition).get(childPosition), mChildFrom, mChildTo);
        return row;
    }

    private void bindView(View view, Map<String, ?> data, String[] from, int[] to) {
        int len = to.length;

        for (int i = 0; i < len; i++) {
            TextView v = (TextView)view.findViewById(to[i]);
            if (v != null) {
                v.setText((String)data.get(from[i]));
            }
        }
    }

}

...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / Android [игнор отключен] [закрыт для гостей] / ExpandableListView : <TextView> + <CheckBox>
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]