Giới thiệu
Trong hầu hết ứng dụng Android đều có sử dụng ListView. Vậy ListView là gì mà 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 (list). Ví dụ chúng ta có thể thấy là New Feeds trên facebook của bạn cũng sử dụng ListView hay đơn giản hơn là danh sách danh bạ trong máy của bạn. Trong loạt bài viết hướng dẫn về ListView tôi sẽ cùng cách bạn đi từ ListView cơ bản tới ListView 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áchmà chúng ta có thể scroll. ListView trong Android chỉ hổ trợ danh sách dọc Vertical, không hổ trợ danh danh sách ngang horizontal.
Video demo ListView:
Để sử dụng ListView chúng ta cần các thành phần như sau:
+ DataSource: chính là data mà chúng ta sử dụng để binding lên ListView.
+Adapter: là thành phần gắn kết DataSource với AdapterView. Là một thành phần rất quan trọng khi bạn sử dụng ListView. Performance của ListView phụ thuộc vào các mà bạn sử dụng Adapter như thế nào.
Adapter (Các Adapter thường dùng là ArrayAdapter, CursorAdapter) có nhiệm vụ gắn kết từng item trong DataSource với từng row trong AdapterView.
+ AdapterView: Là ViewGroup. AdapterView có các lớp con là ListView, GridView hay Spinner.
Sử dụng ListView cơ bản
Tiếp theo chúng ta sẽ cùng nhau tìm hiểu cách sử dụng ListView cơ bản nhất. Đó là ListView có các row hiển thị text.
Tạo project có tên là ListViewBasic.
Trong file activity_layout.xml tôi định nghĩa ListView như sau:
1 2 3 4 5 6 7 8 9 10 11 12 |
<?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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
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); } } |
Tôi sẽ giải thích dễ hiểu như dưới đây:
Bước 1: Chúng ta cần tạo Data để có thể gán vào ListView. Ở đây tôi 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à:
Đối số thứ nhất: Chính là Context ở đây do tôi đang đứng ở Activity nên truyền vào this.
Đối số thứ hai: Chính là file layout định nghĩa giao diện từng row trong ListView.
simple_list_item_1.xml là file được định nghĩa sẵn trong android SDK và có nội dung như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?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" /> |
Chúng ta thấy rằng mỗi row trong ListView sử dụng cho Adapter ở trên chính là một TextView mà thôi, từng item trong data sẽ được lấy ra là setText vào TextView này.
Đối số thứ ba chính là data mà chúng ta đã tạo ở trên.
ArrayAdapter này có nhiệm vụ là sẽ get từng item trong data và gắn data này vào các row. (Sẽ nói chi tiết ở bài sau).
Bước 3: Tiến hành setAdapter vừa tạo cho ListView
Tiến hành chạy thử chúng ta sẽ thấy kết quả như sau:
Các bạn thử kéo lên kéo xuống hay nói cách khác là scroll sẽ thấy đúng 100 item giống như data mà chúng ta đã tạo.
Các event thường dùng với ListView
ListView cung cấp cho chúng ta một số event dưới như dưới đây:
Listener khi người dùng click vào 1 item trên Listview.
1 2 3 4 5 6 |
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
1 2 3 4 5 6 7 |
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 cung cấp các thông tin khi bạn scroll ListView
1 2 3 4 5 6 7 8 9 10 11 |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/** * 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
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); } }); } } |
Thử chạy lại ứng dụng và xem kết quả như thế nào nhé!
Source code ListViewBasic.
Kết luận
Thông qua bài viết này tôi đã giới thiệu cho các bạn cách sử dụng ListView một cách cở bản. Qua những bài viết sau chúng ta sẽ cùng nhau tìm hiểu sâu về ListView cũng như cơ chế hoạt động của nó. Nếu có bất cứ thắc mắc nào trong bài viết này vui lòng để lại bình luận ở phía dưới bài viết hoặc có thể liên lạc quan fanpage Eitguide để được giải đáp.