Лекция
Привет, Вы узнаете о том , что такое одиночный, Разберем основные их виды и особенности использования. Еще будет много подробных примеров и описаний. Для того чтобы лучше понимать что такое одиночный, множественный выбор в listview , настоятельно рекомендую прочитать все из категории Программирование мобильных устройств Android и IOs.
В этом уроке:
- используем список ListView для одиночного и множественного выбора элементов
Бывает необходимость предоставить пользователю возможность выбрать один или несколько элементов из списка. Давайте посмотрим, как это можно реализовать.
Создадим проект:
Project name: P0431_SimpleListChoice
Build Target: Android 2.3.3
Application name: SimpleListChoice
Package name: ru.startandroid.develop.p0431simplelistchoice
Create Activity: MainActivity
Нарисуем экран main.xml:
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> android:id="@+id/btnChecked" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Get checked items"> android:id="@+id/lvMain" android:layout_width="match_parent" android:layout_height="wrap_content">
Список lvMain и кнопка btnChecked, по нажатию, на которую будем выводить в лог отмеченные в списке элементы.
Предлагаю вспомнить, что у нас есть файлы ресурсов и мы можем их использовать. Найдем в нашем проекте файл с ресурсами res/values/strings.xml и добавим туда массив строк с именами. В итоге у меня получился файл с таким содержимым:
Hello World, MainActivity! SimpleListChoice Иван Марья Петр Антон Даша Борис Костя Игорь Анна Денис Вадим Ольга Сергей
Из этого списка мы будем получать массив имен. Это удобнее и правильнее, чем перечислять все элементы массива в java-коде.
Кодим MainActivity.java:
package ru.startandroid.develop.p0431simplelistchoice;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
public class MainActivity extends Activity implements OnClickListener {
final String LOG_TAG = "myLogs";
ListView lvMain;
String[] names;
/** Called when the activity is first created. Об этом говорит сайт https://intellect.icu . */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lvMain = (ListView) findViewById(R.id.lvMain);
// устанавливаем режим выбора пунктов списка
lvMain.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
// Создаем адаптер, используя массив из файла ресурсов
ArrayAdapter adapter = ArrayAdapter.createFromResource(
this, R.array.names,
android.R.layout.simple_list_item_single_choice);
lvMain.setAdapter(adapter);
Button btnChecked = (Button) findViewById(R.id.btnChecked);
btnChecked.setOnClickListener(this);
// получаем массив из файла ресурсов
names = getResources().getStringArray(R.array.names);
}
public void onClick(View arg0) {
// пишем в лог выделенный элемент
Log.d(LOG_TAG, "checked: " + names[lvMain.getCheckedItemPosition()]);
}
}
Мы устанавливаем для списка режим выбора - CHOICE_MODE_SINGLE. Это значит, что список будет хранить позицию последнего нажатого пункта и мы всегда можем запросить у него эту информацию. Далее мы создаем адаптер, но не через обычный конструктор, а с использованием метода createFromResource. Параметры на вход почти те же, что и в обычном конструкторе, только вместо массива данных, мы указываем массив строк в ресурсах, который мы создали чуть раньше. В качестве layout-ресурса для пунктов используем системный simple_list_item_single_choice. Он как раз заточен под такое использование.
Далее мы, находим кнопку btnChecked и присваиваем ей Activity в качестве обработчика. И в конце считываем наш массив имен из файла-ресурса в массив строк.
В обработчике нажатия кнопки мы выводим в лог имя из массива. В качестве индекса используем позицию пункта в списке. Последовательность элементов в массиве и в списке совпадают.
Все сохраняем, запускаем и видим список. Выделяем какой-нить пункт:
Жмем кнопку Get checked items и смотрим лог:
checked: Даша
Все верно.
Теперь чуть изменим код программы и получим список с множественным выбором.
// устанавливаем режим выбора пунктов списка
lvMain.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
// Создаем адаптер, используя массив из файла ресурсов
ArrayAdapter adapter = ArrayAdapter.createFromResource(
this, R.array.names,
android.R.layout.simple_list_item_multiple_choice);
(замените только жирный курсивный текст)
Мы заменили CHOICE_MODE_SINGLE на CHOICE_MODE_MULTIPLE и теперь список будет хранить позиции выделенных элементов. Также мы заменилиsimple_list_item_single_choice на simple_list_item_multiple_choice – пункты списка теперь будут позволять множественный выбор.
Метод onClick перепишем следующим образом:
public void onClick(View arg0) {
// пишем в лог выделенные элементы
Log.d(LOG_TAG, "checked: ");
SparseBooleanArray sbArray = lvMain.getCheckedItemPositions();
for (int i = 0; i < sbArray.size(); i++) {
int key = sbArray.keyAt(i);
if (sbArray.get(key))
Log.d(LOG_TAG, names[key]);
}
}
Мы получаем позиции выделенных элементов в виде объекта SparseBooleanArray. Он представляет собой Map(int, boolean). Ключ (int) – это позиция элемента, а значение (boolean) – это выделен пункт списка или нет. Причем SparseBooleanArray хранит инфу не о всех пунктах, а только о тех, с которыми проводилидействие (выделяли и снимали выделение). Мы перебираем его содержимое, получаем позицию пункта и, если пункт выделен, то выводим в лог имя из массива, соответствующее позиции пункта.
Все сохраняем, запускаем приложение. Выделяем несколько элементов:
Жмем кнопку Get checked items и смотрим лог:
checked:
Марья
Антон
Костя
Что мы выделили, то нам список и вернул.
Как видим, отличие обычного списка от списка с возможностью выделения пунктов заключается только в разных режимах ChoiceMode и в использовании разных layout-ресурсов для пунктов списка.
Кстати, здесь мы снова видим, зачем нужен Context при создании адаптера. Без него адаптер не смог бы добраться до файла ресурсов. Метода getResources у адаптера нет, и он использует указанный контекст, который содержит такой метод.
На следующем уроке:
- рассматриваем события ListView: нажатие - onItemClick, выделение - onItemSelect, прокрутка - onScroll
В заключение, эта статья об одиночный подчеркивает важность того что вы тут, расширяете ваше сознание, знания, навыки и умения. Надеюсь, что теперь ты понял что такое одиночный, множественный выбор в listview и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Программирование мобильных устройств Android и IOs
Из статьи мы узнали кратко, но содержательно про одиночный
Здравствуйте.
Заметил такую штуку.
Компилятор постоянни ругался на слова и комментарии на Русском языке.
т.е. создать массив
String names = Иван , Марья , Петр , Антон , Даша , Борис , Костя , Игорь , Анна , Денис , Андрей ;
я не мог. при сохранении выдавалась ошибка:
Save could not be completed. Try File Save As... if the problem persists.
Reason:
Some characters cannot be mapped using Cp1252 character encoding.
Either change the encoding or remove the characters which are not supported by the Cp1252 character encoding.
Причина ясна нужно включить поддержку Русского языка. Подскажите где? )))
Самое интересное, что если хранить всё в файле ресурсов, то никаких ошибок не возникает и всё выводится на ура )
какую версию андроида используешь? и пробывал ли на разных? я всегда тестирую на 2.3.3 и 4.0.3 то бывают разные ошибки.
Метод ArrayAdapter. FromResource на выходе дает ArrayAdapter CharSequence . Поэтому приходится так объявлять переменную.
А когда сами создаем адаптер, просто используем знакомый всем String.
Хотя можно делать и так:
КОД: ВЫДЕЛИТЬ ВСЁ
ArrayAdapter CharSequence adapter = new ArrayAdapter CharSequence (this, android.R.layout.simple_list_item_1, names);
А в массив names можно сложить String, т.к. String наследует интерфейс CharSequence и адаптер запросто будет с ним работать.
Комментарии
Оставить комментарий
Программирование мобильных устройств Android и IOs
Термины: Программирование мобильных устройств Android и IOs