Giới thiệu
Trong hầu hết ứng dụng Android đều có sử dụng ListView. Vậy ListView là gì? Nó lại quan trọng như vậy. Đơn giản ListView là một View dùng để chứa các View dưới dạng danh sách. Ví dụ New Feeds trên facebook cũng sử dụng ListView hay đơn giản hơn là danh sách ở danh bạ trong máy. Trong loạt bài viết hướng dẫn về ListView, sẽ đi từ cơ bản tới nâng cao.
Tổng quan về ListView
ListView
là một ViewGroup
, sắp xếp các View
con trong nó dưới dạng danh sách, và nó có thể cuộn. ListView
trong Android chỉ hỗ trợ danh sách dạng chiều dọc, không hỗ trợ danh danh sách dạng chiều ngang.
Để sử dụng ListView
cần các thành phần như sau:
DataSource
: chính là dữ liệu sử dụng để binding lênListView
.Adapter
: là thành phần gắn kết DataSource với AdapterView. Đồng thời cũng là một thành phần rất quan trọng khi sử dụngListView
. Hiệu năng củaListView
phụ thuộc vào việc sử dụngAdapter
như thế nào?- Adapter có nhiệm vụ gắn kết từng item trong
DataSource
với từng row trongAdapterView
, các Adapter thường dùng làArrayAdapter
,CursorAdapter
.
- Adapter có nhiệm vụ gắn kết từng item trong
AdapterView
: làViewGroup
, có các lớp con làListView
,GridView
haySpinner
.
Sử dụng ListView cơ bản
Tạo project có tên là ListViewBasic.
Trong file activity_layout.xml định nghĩa ListView
như sau:
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.eitguide.nguyennghia.listviewbasic.MainActivity"> <ListView android:id="@+id/lv_items" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout>
File MainActivity.java
package com.eitguide.nguyennghia.listviewbasic; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.Adapter; import android.widget.ArrayAdapter; import android.widget.ListView; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private ListView lvItems; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lvItems = (ListView)findViewById(R.id.lv_items); // 1. Prepare data to binding for ListView List<String> data = new ArrayList<>(); for(int i = 0; i < 100; i++) data.add("Item " + i); // 2. Create Adapter with data and row ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, data); // 3. Set Adapter for ListView lvItems.setAdapter(adapter); } }
Giải thích code
Bước 1: tạo data
để có thể gán vào ListView
, project này tạo tạo 100 item kiểu String
để gắn vào ListView
.
Bước 2: tạo ArrayAdapter
với 3 thông số truyền vào là:
this
: là Context, do đang ở Activity hiện tại nên truyền vàothis
.android.R.layout.simple_list_item_1
: là tập tin layout định nghĩa giao diện từng dòng trongListView
.data
: dữ liệu đã tạo ở trên.
simple_list_item_1.xml là file được định nghĩa sẵn trong Android SDK và có nội dung như sau:
<?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2006 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceListItemSmall" android:gravity="center_vertical" android:paddingStart="?android:attr/listPreferredItemPaddingStart" android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" android:minHeight="?android:attr/listPreferredItemHeightSmall" />
Mỗi dòng trong ListView
sử dụng cho Adapter
ở trên chính là một TextView
. Từng item trong data sẽ được lấy ra là setText
vào TextView
này.
ArrayAdapter
có nhiệm vụ là get từng item trong data và gắn data này vào các row.
Bước 3: Tiến hành setAdapter
vừa tạo cho ListView
Tiến hành chạy sẽ thấy kết quả như sau và cuộn lên hoặc cuộn xuống sẽ thấy đúng 100 item giống như dữ liệu đã tạo.
Các event thường dùng với ListView
Listener khi người dùng click vào 1 item trên ListView
lvItems.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(MainActivity.this, data.get(position), Toast.LENGTH_SHORT).show(); } });
Listener khi người dùng nhấn giữ vào 1 item trên ListView
lvItems.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(MainActivity.this, data.get(position), Toast.LENGTH_SHORT).show(); return false; } });
Listener cung cấp các thông tin khi cuộn ListView
lvItems.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { Log.e(TAG, "onScrollStateChanged: " + scrollState); } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { Log.e(TAG, "onScroll: " + "firstVisibleItem: " + firstVisibleItem + ", visibleItemCount: " + visibleItemCount + ", totalCount: " + totalItemCount); } });
scrollState
được gửi qua method onScrollStateChanged
gồm các giá trị có các ý nghĩa như dưới đây:
/** * The view is not scrolling. Note navigating the list using the trackball counts as * being in the idle state since these transitions are not animated. */ public static int SCROLL_STATE_IDLE = 0; /** * The user is scrolling using touch, and their finger is still on the screen */ public static int SCROLL_STATE_TOUCH_SCROLL = 1; /** * The user had previously been scrolling using touch and had performed a fling. The * animation is now coasting to a stop */ public static int SCROLL_STATE_FLING = 2;
Source code đầy đủ file MainActivity.java
package com.eitguide.nguyennghia.listviewbasic; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.AbsListView; import android.widget.Adapter; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.Toast; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private ListView lvItems; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lvItems = (ListView) findViewById(R.id.lv_items); // Prepare to binding for ListView final List<String> data = new ArrayList<>(); for (int i = 0; i < 100; i++) data.add("Item " + i); // Create Adapter with data and row ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, data); // Set Adapter for ListView lvItems.setAdapter(adapter); lvItems.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(MainActivity.this, data.get(position), Toast.LENGTH_SHORT).show(); } }); lvItems.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(MainActivity.this, data.get(position), Toast.LENGTH_SHORT).show(); return false; } }); lvItems.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { Log.e(TAG, "onScrollStateChanged: " + scrollState); } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { Log.e(TAG, "onScroll: " + "firstVisibleItem: " + firstVisibleItem + ", visibleItemCount: " + visibleItemCount + ", totalCount: " + totalItemCount); } }); } }
Chạy lại ứng dụng và xem kết quả.