В этом уроке:

- рассматриваем события ListView: нажатие - onItemClick, выделение - onItemSelect, прокрутка - onScroll

 

При взаимодействии со списком может возникнуть необходимость обрабатывать события – нажатие на пункт и прокрутка. Попробуем это сделать.

 

Создадим проект:

Project name: P0441_SimpleListEvents
Build Target: Android 2.3.3
Application name: SimpleListEvents
Package name: ru.startandroid.develop.p0441simplelistevents
Create Activity: MainActivity

 

Нарисуем экран main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">
    <ListView
        android:id="@+id/lvMain"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </ListView>
</LinearLayout>

На экране только ListView.

 

Так же, как и на прошлом уроке добавим список имен в ресурс res/values/strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, MainActivity!</string>
    <string name="app_name">SimpleListEvents</string>
    <string-array name="names">
        <item>Иван</item>
        <item>Марья</item>
        <item>Петр</item>
        <item>Антон</item>
        <item>Даша</item>
        <item>Борис</item>
        <item>Костя</item>
        <item>Игорь</item>
        <item>Анна</item>
        <item>Денис</item>
        <item>Вадим</item>
        <item>Ольга</item>
        <item>Сергей</item>
    </string-array>
</resources>

 

Пишем код MainActivity.java:

package ru.startandroid.develop.p0441simplelistevents;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class MainActivity extends Activity {

  final String LOG_TAG = "myLogs";

  ListView lvMain;

  /** Called when the activity is first created. */
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    lvMain = (ListView) findViewById(R.id.lvMain);

    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
        this, R.array.names, android.R.layout.simple_list_item_1);
    lvMain.setAdapter(adapter);

    lvMain.setOnItemClickListener(new OnItemClickListener() {
      public void onItemClick(AdapterView<?> parent, View view,
          int position, long id) {
        Log.d(LOG_TAG, "itemClick: position = " + position + ", id = "
            + id);
      }
    });

    lvMain.setOnItemSelectedListener(new OnItemSelectedListener() {
      public void onItemSelected(AdapterView<?> parent, View view,
          int position, long id) {
        Log.d(LOG_TAG, "itemSelect: position = " + position + ", id = "
            + id);
      }

      public void onNothingSelected(AdapterView<?> parent) {
        Log.d(LOG_TAG, "itemSelect: nothing");
      }
    });

  }
}

Смотрим код. Мы находим экранные элементы, создаем и присваиваем списку адаптер. Далее списку мы присваиваем два обработчика событий:

 

1) OnItemClickListener – обрабатывает нажатие на пункт списка

Предоставляет нам метод onItemClick(AdapterView<?> parent, View view, int position, long id), где

parent – View-родитель для нажатого пункта, в нашем случае - ListView
view – это нажатый пункт, в нашем случае – TextView из android.R.layout.simple_list_item_1
position – порядковый номер пункта в списке
id – идентификатор элемента,

Мы в лог будем выводить id и position для элемента, на который нажали.

 

2) OnItemSelectedListener – обрабатывает выделение пунктов списка (не check, как на прошлом уроке)

Предоставляет нам метод onItemSelected полностью аналогичен по параметрам методу onItemClick описанному выше. Не буду повторяться.

Также есть метод onNothingSelected – когда список теряет выделение пункта и ни один пункт не выделен.

 

Все сохраним и запустим приложение.

 

Ткнем какой-нибудь элемент, например - Петр. Смотрим лог:

itemClick: position = 2, id = 2

Все верно. Т.к. позиция считается не с единицы, а с нуля – Петр имеет позицию 2. (В нашем случае id равен position. Я пока не встречал случаев id != position, но наверняка они есть)

 

Теперь покрутите колесо мышки или понажимайте клавиши вверх вниз на клавиатуре. Видно что идет визуальное выделение элементов списка.

А в логах мы видим такие записи:

itemSelect: position = 2, id = 2
itemSelect: position = 3, id = 3
itemSelect: position = 4, id = 4
itemSelect: position = 5, id = 5
itemSelect: position = 4, id = 4
itemSelect: position = 3, id = 3
itemSelect: position = 2, id = 2

Т.е. обработчик фиксирует какой пункт выделен. Честно говоря, я не очень понимаю как можно использовать такое выделение. Но обработчик для него есть и я решил про него рассказать. Пусть будет.

 

Снова нажмем теперь на любой пункт списка, мы видим, что выделение пропало. Логи:

itemSelect: nothing
itemClick: position = 3, id = 3

Ничего не выделено и нажат пункт с позицией 3.

 

Давайте добавим к списку еще один обработчик:

    lvMain.setOnScrollListener(new OnScrollListener() {
      public void onScrollStateChanged(AbsListView view, int scrollState) {
        // Log.d(LOG_TAG, "scrollState = " + scrollState);
      }

      public void onScroll(AbsListView view, int firstVisibleItem,
          int visibleItemCount, int totalItemCount) {
        Log.d(LOG_TAG, "scroll: firstVisibleItem = " + firstVisibleItem
            + ", visibleItemCount" + visibleItemCount
            + ", totalItemCount" + totalItemCount);
      }
    });

 

OnScrollListener – обрабатывает прокрутку списка.

Методы:

1) onScrollStateChanged(AbsListView view, int scrollState) - обработка состояний прокрутки 

view – это прокручиваемый элемент, т.е. ListView
scrollState – состояние списка. Может принимать три значения:

SCROLL_STATE_IDLE = 0, список закончил прокрутку
SCROLL_STATE_TOUCH_SCROLL = 1, список начал прокрутку
SCROLL_STATE_FLING = 2, список «катнули», т.е. при прокрутке отпустили палец и прокрутка дальше идет «по инерции»

Вывод в лог я пока закаментил, чтобы не мешалось. Чуть позже раскаментим.

 

2) onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) - обработка прокрутки 

view – прокручиваемый элемент
firstVisibleItem – первый видимый на экране пункт списка
visibleItemCount – сколько пунктов видно на экране
totalItemCount – сколько всего пунктов в списке

Причем для параметров firstVisibleItem и visibleItemCount пункт считается видимым на экране даже если он виден не полностью.

Все сохраним и запустим.

Теперь потаскайте список туда-сюда курсором (как будто пальцем) и смотрите логи. Там слишком много всего выводится. Я не буду здесь выкладывать. Но принцип понятен – меняется первый видимый пункт (firstVisibleItem) и может на единицу меняться кол-во видимых пунктов (visibleItemCount).

 

Теперь закоментируем вывод в лог в методе onScroll (чтобы не спамил нам лог) и раскаментим в onScrollStateChanged.

    lvMain.setOnScrollListener(new OnScrollListener() {
      public void onScrollStateChanged(AbsListView view, int scrollState) {
        Log.d(LOG_TAG, "scrollState = " + scrollState);
      }

      public void onScroll(AbsListView view, int firstVisibleItem,
          int visibleItemCount, int totalItemCount) {
        //Log.d(LOG_TAG, "scroll: firstVisibleItem = " + firstVisibleItem
        //    + ", visibleItemCount" + visibleItemCount
        //    + ", totalItemCount" + totalItemCount);
      }
    });

 

Сохраняем, запускаем.

Схватим список, немного потягаем туда сюда и отпустим. Смотрим лог:

scrollState = 1
scrollState = 0

Отработали два события – список начал прокрутку, список закончил прокрутку.

 

Попробуем взять список, «катнуть» его и отпустить.

scrollState = 1
scrollState = 2
scrollState = 0

Видим три события – прокрутка началась, список «катнули», прокрутка закончилась.

 

Полный код урока:

package ru.startandroid.develop.p0441simplelistevents;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class MainActivity extends Activity {

  final String LOG_TAG = "myLogs";

  ListView lvMain;

  /** Called when the activity is first created. */
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    lvMain = (ListView) findViewById(R.id.lvMain);

    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
        this, R.array.names, android.R.layout.simple_list_item_1);
    lvMain.setAdapter(adapter);

    lvMain.setOnItemClickListener(new OnItemClickListener() {
      public void onItemClick(AdapterView<?> parent, View view,
          int position, long id) {
        Log.d(LOG_TAG, "itemClick: position = " + position + ", id = "
            + id);
      }
    });

    lvMain.setOnItemSelectedListener(new OnItemSelectedListener() {
      public void onItemSelected(AdapterView<?> parent, View view,
          int position, long id) {
        Log.d(LOG_TAG, "itemSelect: position = " + position + ", id = "
            + id);
      }

      public void onNothingSelected(AdapterView<?> parent) {
        Log.d(LOG_TAG, "itemSelect: nothing");
      }
    });

    lvMain.setOnScrollListener(new OnScrollListener() {
      public void onScrollStateChanged(AbsListView view, int scrollState) {
        Log.d(LOG_TAG, "scrollState = " + scrollState);
      }

      public void onScroll(AbsListView view, int firstVisibleItem,
          int visibleItemCount, int totalItemCount) {
        Log.d(LOG_TAG, "scroll: firstVisibleItem = " + firstVisibleItem
            + ", visibleItemCount" + visibleItemCount
            + ", totalItemCount" + totalItemCount);
      }
    });

  }
}

 

 


На следующем уроке:

- строим список-дерево ExpandableListView


Присоединяйтесь к нам в Telegram:

- в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

- в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Compose, Kotlin, RxJava, Dagger, Тестирование, Performance 

- ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня




Language

Автор сайта

Дмитрий Виноградов

Подробнее можно посмотреть или почитать.

Никакие другие люди не имеют к этому сайту никакого отношения и просто занимаются плагиатом.

Социальные сети

 

В канале я публикую ссылки на интересные и полезные статьи по Android

В чате можно обсудить вопросы и проблемы, возникающие при разработке



Группа ВКонтакте



Поддержка проекта

Яндекс
410011180491924

WebMoney
R248743991365
Z551306702056

Paypal