Как определить повторно используемые виджеты в ListViews - PullRequest
0 голосов
/ 14 февраля 2012

У меня есть то, что я считаю странной дилеммой, хотя YMMV.

Я использую файл макета, который описывает каждую строку / строку в ListView (ничего особенного в этом нет).У меня есть идентификатор, назначенный каждому, например:

android: id = "@ + id / checkBox1" android: id = "@ + id / checkBox2" android: id = "@ + id / checkBox3"
android: id =" @ + id / contactLabel "// a TextView

Теперь это, кажется, не имеет смысла, так как эти идентификаторы должны быть уникальными, так каков идентификатор второгострока?То есть, если «строка 1» учитывает указанные идентификаторы checkbox1, checkbox2, checkbox3 и contactLabel, какими будут идентификаторы «строки 2»?

Мне любопытно, но мне также нужно знать, потому чтоЯ хочу сохранить значения флажков в объекте SharedPreferences.

Кто знает, как обойти это?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Обновление

Первое, что мне нужно решить, это как реагировать на нажатие на ListView.Это моя текущая головоломка, связанная со всем этим:

ListView не знает, что на него нажали, или не скажет мне

Я добавил это событиеобработчик моего ListActivity:

  @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        String item = (String) getListAdapter().getItem(position);
        Toast.makeText(this, item + " selected", Toast.LENGTH_LONG).show();
    }

... но он не вызывается.Я нажимаю на контакты, которые отображаются, но не идти.

Я тоже попробовал это так:

lv.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view,
        int position, long id) {
        Toast.makeText(getApplicationContext(),
            "Click ListItem Number " + position, Toast.LENGTH_LONG)
            .show();
    }
});

... все еще нет радости ... Я установил контрольные точки на обеих линиях "Тост", и они никогда не достигаются.

Я прочитал здесь:

http://www.vogella.de/articles/AndroidListView/article.html#listsactivity_layout

... что, "Если вам нужно больше просто ListView в вашей деятельности, вы можете использовать свой собственный макет для ListActivity.«

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

Далее говорится:« В этом случае ваш макет должен иметь ListView.элемент с атрибутом android: id, установленным в @android: id / list. "

Итак, я добавил это в свой макет:

... но это не даетразница так или иначе.

1 Ответ

1 голос
/ 14 февраля 2012

Идентификаторы для элементов в виджете ListView ссылаются через их родительское представление, когда вы раздуваете его с помощью getView() метода.

Для уточнения, у вас будет что-то вроде этого ListView adapter.

public View getView(int position, View convertView, ViewGroup viewGroup) {
        if (convertView == null) {
            convertView = LayoutInflater.from(ctx).inflate(R.layout.list_view_item, null);
            }

Нет, новый экземпляр представления существует как convertView.Вы можете получить доступ к своим виджетам, используя covertView.findViewById(R.id.checkBox1), convertView.findViewById(R.id.checkBox2) и т. Д.

Каждое из этих представлений является дочерним элементом вашего ListView.Вы можете ссылаться на каждый отдельный вид из вашего ListView, используя методы getChildCount() и getChildAt() из объекта ListView.Однако, поскольку рекомендуется использовать представление convertView для повторного использования представлений, в этом случае вы будете иметь только ссылки на представления на экране одновременно.

Кроме того, что касается SharedPreferences,все представления в вашем ListView заполнены подклассом Adapter, который будет фактическим объектом, который помещает значения в виджеты Checkbox и TextView.У этого Adapter есть набор данных, который вы предоставляете.Почему бы не ссылаться на значения из набора данных напрямую, вместо того, чтобы пытаться найти их в элементах списка, которые в любом случае заполняются из набора данных?Вы можете писать в набор данных из ListView, когда кто-то щелкает по CheckBox, поэтому у вас есть легко упорядоченная ссылка на все элементы в ListView.


ОБНОВЛЕНИЕ: Добавленофиктивный исходный код

ОК.Давайте начнем с гипотетического списка.Мы хотим отобразить, скажем, пять пунктов в списке.Для простоты я предполагаю, что у каждого есть TextView и Checkbox.Итак, мой контейнерный класс:

class Item {
    String textView;
    boolean checked;
}

Теперь в моем Activity, где я хочу отобразить этот список, я поместил ArrayList элементов (вы можете использовать практически любую структуру данных) в качестве переменной класса,Затем я получаю ссылку ListView и назначаю ей адаптер.

class MyActivity extends Activity {
    ArrayList<Item> listItems;
    .....
    onCreate(Bundle icicle) {
        .....
        ListView listView = (ListView) findViewById(R.id.listView1); // this will be you list view
        MyAdapter listAdapter = new MyAdapter();
        listView.setAdapter(listAdapter);
        ....
        // Rest of your Activity
        ....
        MyAdapter extends BaseAdapter {

            int getItemCount() {
                return listItems.size();
            }

            Item getItem(int position) {
                return listItems.get(position);
            }

            View getView(int position, View convertView, ViewGroup parent) {
                // Here's the important part
                Item currentItem = listItems.getItem(position); // Since the array is a class variable, you can do either get or getItem

                ..... // do the standard individual item inflating ....

                checkbox = convertView.findViewById(R.id.checkbox);
                checkbox.OnItemSelectedListener( new OnItemSelectedListener() { // or whatever listener there should be... I didn't check
                    ... // do whatever...
                    currentItem.setChecked(true);
            }

Когда вы хотите получить какие элементы были нажаты, просто переберите класс Item и найдите, какие из них являются истинными, или выполните любое действие, которое вы хотитев пределах Listener, поскольку у вас есть ссылка, идентифицирующая отдельных членов набора данных ListView (здесь listItems ArrayList).

Извинения за любые ошибки.Не проверял.

...