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ủaListViewphụ thuộc vào việc sử dụngAdapternhư thế nào?- Adapter có nhiệm vụ gắn kết từng item trong
DataSourcevớ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,GridViewhaySpinner.
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ả.