This lesson:
- considering ListView events - onItemClick, onItemSelect, onScroll
Interacting with the list, we might have a necessity to process such events as list item click or scroll. Let’s look how to do that.
Create a project:
Project name: P0441_SimpleListEvents
Build Target: Android 2.3.3
Application name: SimpleListEvents
Package name: ru.startandroid.develop.p0441simplelistevents
Create Activity: MainActivity
Let’s code the 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>
There is only the ListView on the screen.
The same way with the previous lesson we will add the list of names into the resources ( 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>Ivan</item> <item>Maria</item> <item>Petr</item> <item>Anton</item> <item>Dasha</item> <item>Boris</item> <item>Kostja</item> <item>Igor</item> <item>Anna</item> <item>Denis</item> <item>Vadim</item> <item>Olga</item> <item>Sergey</item> </string-array> </resources>
Let’s code 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"); } }); } }
Now look at the code. We define views, create the adapter and assign it to the list. Next, we assign two listeners to the list:
1) OnItemClickListener processes the list item click
Provides us with the onItemClick method (onItemClick(AdapterView<?> parent, View view, int position, long id)), where:
parent is a parent-view of the clicked item;
view is a clicked item;
position is a number of the item in the list;
id is an identifier;
We will display in logs the id and the position of the item that was clicked.
2) OnItemSelectedListener processes the list item selection
Provides us with the onItemSelected method which parameters are almost similar with the onItemClick method. No need to repeat them.
We also have the onNothingSelected method, it processes the situation when neither of the list items is selected.
Now let’s save and launch the app.
Let’s click any item, Peter for example. Look in logs:
itemClick: position = 2, id = 2
It’s alright. Because the position is counted from zero, so Peter has the position number 2. (In our case the position equals to id, I didn’t meet cases when it’s not so, but for sure, they may exist).
Now roll the mouse wheel and push up and down arrows on your keyboard. You can see that the list items are selecting.
So, in logs we can see:
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
I.e. the listener carries information about what list item was selected. I see no usage for this function, but as it exists, I decided to tell about it.
Let’s now click any list item. We can can see that the selection has disappeared. Logs:
itemSelect: nothing
itemClick: position = 3, id = 3
Nothing is selected and the third list item was clicked.
Let’s add one more listener to the list:
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 processes the list scrolling.
Methods:
1) onScrollStateChanged(AbsListView view, int scrollState) processes the scrolling state.
view is the scrolling view;
scrollState is a scrolling state. It may have three values:
SCROLL_STATE_IDLE = 0, when the list has stopped scrolling.
SCROLL_STATE_TOUCH_SCROLL = 1, when the list has begun scrolling.
SCROLL_STATE_FLING = 2, when the list was scrolled, i.e. when the finger was removed from the screen and the scroll is going on by inertia.
I had disabled the logging raw with a comment. We will enable it later.
2) onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) is for scroll processing.
view is a scrolling view
firstVisibleItem is the first visible list item on the screen;
visibleItemCount is a number of visible items;
totalItemCount is a number of items in the list;
Moreover, for firstVisibleItem and visibleItemCount
And for the parameters firstVisibleItem and visibleItemCount, the item is considered visible on the screen even if it is not completely visible.
Let’s save and launch the project.
Now scroll the list with the mouse cursor (like with a finger) and look in logs. There is too many data. I won’t show it here. The principle is clear: firstVisibleItem and visibleItemCount are changing.
Now let’s disable with comment the onScroll method logging (or it will spam) and enable 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); } });
Let’s save and launch.
Now we need to catch the list, scroll it to both up and down and release. Look in logs:
scrollState = 1
scrollState = 0
Two events worked: the list started scrolling, the list finished scrolling.
Let’s try to catch the list, scroll it and release.
scrollState = 1
scrollState = 2
scrollState = 0
We see three events - scrolling started, the list was scrolled, the scrolling is over.
Full lesson code:
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); } }); } }
The next lesson:
- creating ExpandableListView
Присоединяйтесь к нам в Telegram:
- в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.
- в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Compose, Kotlin, RxJava, Dagger, Тестирование, Performance
- ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня