Trong bài viết này, mình sẽ hướng dẫn các bạn custom một ListView. Thường thường, khi làm dự án thì leader sẽ giao cho bạn làm task này trong vòng 1 ngày. Nhưng mình nghĩ sau khi đọc bài hướng dẫn này, bạn chỉ cần bỏ ra nửa ngày để hoàn thành, còn nửa ngày còn lại bạn đi support những đồng nghiệp nữ :))
Sau đây, mình sẽ hướng dẫn từng bước một để bạn có 1 ListView trông thật chuyên nghiệp 😀 Trong từng bước mình cũng kết hợp đề cập đến những quy tắc trong lập trình Android bạn nên tuân thủ. Hãy tập trung tu luyện nhé, bài viết này rất hữu ích cho bạn.
Mình sẽ tạo 1 ListView chứa 1 list các bài hát. Mỗi item bao gồm 1 hình ảnh minh hoạ, tiêu đề, tên ca sĩ, lượt view, số like và số dislike.
Để tạo được ListView như vậy, các bạn cần phải thực hiện 6 bước sau:
Bước 1: Tạo mới một Project. Project Structure:
Bước 2: Code trong main layout:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<?xml version=“1.0” encoding=“utf-8”?>
<RelativeLayout 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” android:paddingLeft=“@dimen/activity_horizontal_margin”
android:paddingRight=“@dimen/activity_horizontal_margin”
android:paddingTop=“@dimen/activity_vertical_margin”
android:paddingBottom=“@dimen/activity_vertical_margin” tools:context=“.MainActivity”>
<ListView
android:id=“@+id/listview”
android:layout_width=“match_parent”
android:layout_height=“match_parent” />
</RelativeLayout>
|
Bước 3: Tạo view item cho ListView:
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
<?xml version=“1.0” encoding=“utf-8”?>
<LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:orientation=“horizontal”>
<LinearLayout
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:orientation=“horizontal”>
<ImageView
android:id=“@+id/img_illustration”
android:layout_width=“0dp”
android:layout_height=“100dp”
android:layout_weight=“2”
android:scaleType=“centerCrop”
android:src=“@drawable/image” />
<LinearLayout
android:layout_width=“0dp”
android:layout_height=“wrap_content”
android:layout_alignParentBottom=“true”
android:layout_marginLeft=“10dp”
android:layout_weight=“4”
android:orientation=“vertical”>
<TextView
android:id=“@+id/txt_title_event”
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:layout_weight=“5”
android:gravity=“center_vertical”
android:text=“Xin đừng hái hoa”
android:textColor=“@color/colorBlack”
android:textSize=“20dp” />
<TextView
android:id=“@+id/txt_author”
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:layout_alignParentRight=“true”
android:layout_weight=“1”
android:padding=“5dp”
android:text=“Hồ Quang Hiếu”
android:textColor=“@color/colorBlack” />
<LinearLayout
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:layout_alignParentBottom=“true”
android:orientation=“horizontal”>
<TextView
android:id=“@+id/txt_count_view”
android:layout_width=“0dp”
android:layout_height=“wrap_content”
android:layout_alignParentRight=“true”
android:layout_marginRight=“5dp”
android:layout_weight=“1”
android:drawableRight=“@drawable/ic_visibility_black_24dp”
android:gravity=“center_vertical”
android:padding=“5dp”
android:text=“1000”
android:textColor=“@color/colorBlack” />
<TextView
android:id=“@+id/txt_count_like”
android:layout_width=“0dp”
android:layout_height=“wrap_content”
android:layout_alignParentRight=“true”
android:layout_marginRight=“5dp”
android:layout_weight=“1”
android:drawableRight=“@drawable/ic_thumb_up_black_24dp”
android:gravity=“center_vertical”
android:padding=“5dp”
android:text=“1000”
android:textColor=“@color/colorBlack” />
<TextView
android:id=“@+id/txt_count_dislike”
android:layout_width=“0dp”
android:layout_height=“wrap_content”
android:layout_alignParentRight=“true”
android:layout_weight=“1”
android:drawableRight=“@drawable/ic_thumb_down_black_24dp”
android:gravity=“center_vertical”
android:padding=“5dp”
android:text=“1000”
android:textColor=“@color/colorBlack” />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<View
android:layout_width=“match_parent”
android:layout_height=“16dp”/>
</LinearLayout>
|
Mình lấy icon từ trang Material Icons, các bạn có thể vào đây tìm icon mình cần, rất nhiều icon free :3
Khi đặt id cho từng control, các bạn nên đặt từ gợi nhớ trước id. VD: img_illustration, txt_count_dislike… Khi bạn tham chiếu đến id, chỉ cần viết chữ gợi nhớ đầu, bạn sẽ thấy 1 list id sổ ra cho bạn lựa chọn. Nó sẽ rất hữu ích khi bạn làm việc với nhiều control.
Bước 4: Tạo Entity để lưu dữ liệu cho từng hàng của ListView:
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
|
package example.android.trinh.lap.customlistview.entities;
/**
* Created by thuynguyen on 1/26/16.
*/
public class Movie {
private String mName;
private String mAuthor;
private String mUrlImage;
private int mCountView;
private int mCountLike;
private int mCountDisLike;
public Movie() {}
public Movie(String name, String author, String urlImage, int countView, int countLike, int countDisLike) {
this.mName = name;
this.mAuthor = author;
this.mUrlImage = urlImage;
this.mCountView = countView;
this.mCountLike = countLike;
this.mCountDisLike = countDisLike;
}
public String getmName() {
return mName;
}
public void setmName(String mName) {
this.mName = mName;
}
public String getmAuthor() {
return mAuthor;
}
public void setmAuthor(String mAuthor) {
this.mAuthor = mAuthor;
}
public String getmUrlImage() {
return mUrlImage;
}
public void setmUrlImage(String mUrlImage) {
this.mUrlImage = mUrlImage;
}
public int getmCountView() {
return mCountView;
}
public void setmCountView(int mCountView) {
this.mCountView = mCountView;
}
public int getmCountLike() {
return mCountLike;
}
public void setmCountLike(int mCountLike) {
this.mCountLike = mCountLike;
}
public int getmCountDisLike() {
return mCountDisLike;
}
public void setmCountDisLike(int mCountDisLike) {
this.mCountDisLike = mCountDisLike;
}
}
|
Để tự động get và set cho các thuộc tính, các bạn thực hiện như sau:
Chuột phải chọn Generate…
Sau đó:
Chọn Getter and Setter
Bước 5: Tạo Adapter để truyền dữ liệu cho ListView:
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
72
73
74
75
76
77
78
79
80
81
|
package example.android.trinh.lap.customlistview.adapters;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
import example.android.trinh.lap.customlistview.R;
import example.android.trinh.lap.customlistview.entities.Movie;
/**
* Created by thuynguyen on 1/26/16.
*/
public class MovieAdapter extends BaseAdapter {
private ArrayList<Movie> mMovieList;
private LayoutInflater mLayoutInflater;
private Context mContext;
public MovieAdapter(Context context, ArrayList<Movie> movies) {
this.mContext = context;
this.mMovieList = movies;
this.mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return mMovieList != null ? mMovieList.size() : 0;
}
@Override
public Object getItem(int position) {
return mMovieList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mLayoutInflater.inflate(R.layout.item_listview, null);
holder.mImage = (ImageView) convertView.findViewById(R.id.img_illustration);
holder.mTitle = (TextView) convertView.findViewById(R.id.txt_title_event);
holder.mAuthor = (TextView) convertView.findViewById(R.id.txt_author);
holder.mCountView = (TextView) convertView.findViewById(R.id.txt_count_view);
holder.mCountLike = (TextView) convertView.findViewById(R.id.txt_count_like);
holder.mCountDisLike = (TextView) convertView.findViewById(R.id.txt_count_dislike);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Movie event = (Movie) getItem(position);
Picasso.with(mContext).load(event.getmUrlImage()).into(holder.mImage);
holder.mAuthor.setText(event.getmAuthor());
holder.mTitle.setText(event.getmName());
holder.mCountView.setText(String.valueOf(event.getmCountView()));
holder.mCountLike.setText(String.valueOf(event.getmCountLike()));
holder.mCountDisLike.setText(String.valueOf(event.getmCountDisLike()));
return convertView;
}
public class ViewHolder {
private ImageView mImage;
private TextView mTitle;
private TextView mAuthor;
private TextView mCountView;
private TextView mCountLike;
private TextView mCountDisLike;
}
}
|
Bước 6: Set Adapter cho ListView trong MainMainActivity:
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
|
package example.android.trinh.lap.customlistview.activities;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;
import java.util.ArrayList;
import example.android.trinh.lap.customlistview.R;
import example.android.trinh.lap.customlistview.adapters.MovieAdapter;
import example.android.trinh.lap.customlistview.entities.Movie;
public class MainActivity extends AppCompatActivity {
private ListView mListView;
private ArrayList<Movie> mMovieList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
setDataListView();
}
private void initView() {
mListView = (ListView) findViewById(R.id.listview);
}
private void initData() {
mMovieList = new ArrayList<>();
mMovieList.add(new Movie(“Con Bướm Xuân”, “Hồ Quang Hiếu”, “http://www.musicmusic.vn/FileClip/Photos/Hoquanghieu-conbuomxuan.jpg”, 1245, 1034, 20));
mMovieList.add(new Movie(“Chắc ai đó sẽ về”, “Sơn Tùng M – TP”, “https://i.ytimg.com/vi/H-fI_h_pXw8/maxresdefault.jpg”, 1234, 1050, 35));
mMovieList.add(new Movie(“Con gái có quyền điệu”, “Hari Won”, “https://i.ytimg.com/vi/6IhL_-PuDxw/maxresdefault.jpg”, 12454, 1040, 23));
mMovieList.add(new Movie(“Âm thầm bên em”, “Sơn Tùng M – TP”, “http://media.doisongphapluat.com/423/2015/8/22/sontung01.PNG”, 1245, 105, 56));
mMovieList.add(new Movie(“Tìm em”, “Hồ Quang Hiếu”, “http://image.mp3.zdn.vn/thumb_video/e/9/e907aad8342bfdf25d1a1be89a94aa67_1393816732.jpg”, 1245, 1000, 0));
mMovieList.add(new Movie(“Buông đôi tay nhau ra”, “Sơn Tùng M – TP”, “http://xmedia-nguoiduatin.cdn.vccloud.vn/thumb_x500x/2015/12/3/235/buong-doi-tay-nhau-ra-son-tung-4-1449109597.jpg”, 3556, 156, 53));
mMovieList.add(new Movie(“Con Bướm Xuân”, “Hồ Quang Hiếu”, “http://img.saobiz.net/d/2015/07/nhung-hinh-anh-dep-cua-ca-si-Ho-Quang-Hieu.jpg”, 1745, 1050, 54));
mMovieList.add(new Movie(“Con Bướm Xuân”, “Hồ Quang Hiếu”, “http://img.saobiz.net/d/2015/07/nhung-hinh-anh-dep-cua-ca-si-Ho-Quang-Hieu.jpg”, 175, 1000, 65));
mMovieList.add(new Movie(“Con Bướm Xuân”, “Sơn Tùng M – TP”, “http://img.saobiz.net/d/2015/07/nhung-hinh-anh-dep-cua-ca-si-Ho-Quang-Hieu.jpg”, 455, 1000, 6));
mMovieList.add(new Movie(“Ngã Tư Đường”, “Hồ Quang Hiếu”, “http://imgs.vietnamnet.vn/Images/2012/05/04/17/20120504170346_7.jpg”, 15745, 1030, 0));
mMovieList.add(new Movie(“Hết yêu”, “Hồ Quang Hiếu”, “http://img.saobiz.net/d/2015/07/nhung-hinh-anh-dep-cua-ca-si-Ho-Quang-Hieu.jpg”, 12745, 1045, 23));
mMovieList.add(new Movie(“Không phải dạng vừa đâu”, “Sơn Tùng M – TP”, “https://i.ytimg.com/vi/gJkkPK0aXFo/maxresdefault.jpg”, 75, 100, 0));
mMovieList.add(new Movie(“Con Bướm Xuân”, “Hồ Quang Hiếu”, “http://img.saobiz.net/d/2015/07/nhung-hinh-anh-dep-cua-ca-si-Ho-Quang-Hieu.jpg”, 125, 1000, 89));
mMovieList.add(new Movie(“Con Bướm Xuân”, “Hồ Quang Hiếu”, “http://img.saobiz.net/d/2015/07/nhung-hinh-anh-dep-cua-ca-si-Ho-Quang-Hieu.jpg”, 1677, 109, 78));
mMovieList.add(new Movie(“Con Bướm Xuân”, “Hồ Quang Hiếu”, “http://img.saobiz.net/d/2015/07/nhung-hinh-anh-dep-cua-ca-si-Ho-Quang-Hieu.jpg”, 1245, 60, 89));
mMovieList.add(new Movie(“Con Bướm Xuân”, “Hồ Quang Hiếu”, “http://img.saobiz.net/d/2015/07/nhung-hinh-anh-dep-cua-ca-si-Ho-Quang-Hieu.jpg”, 1245, 103, 34));
mMovieList.add(new Movie(“Con Bướm Xuân”, “Hồ Quang Hiếu”, “http://img.saobiz.net/d/2015/07/nhung-hinh-anh-dep-cua-ca-si-Ho-Quang-Hieu.jpg”, 1245, 1005, 90));
mMovieList.add(new Movie(“Con Bướm Xuân”, “Hồ Quang Hiếu”, “http://img.saobiz.net/d/2015/07/nhung-hinh-anh-dep-cua-ca-si-Ho-Quang-Hieu.jpg”, 1245, 106, 34));
mMovieList.add(new Movie(“Con Bướm Xuân”, “Hồ Quang Hiếu”, “http://img.saobiz.net/d/2015/07/nhung-hinh-anh-dep-cua-ca-si-Ho-Quang-Hieu.jpg”, 1245, 106, 90));
}
private void setDataListView() {
MovieAdapter movieAdapter = new MovieAdapter(this, mMovieList);
mListView.setAdapter(movieAdapter);
}
}
|
Mình khởi tạo dữ liệu trong hàm initData, sau đó truyền context(con trỏ this) và mảng dữ liệu(mMovieList) khi khởi tạo MoviewAdapter. Bạn dùng hàm setAdapter để truyền dữ liệu cho ListView.
Khi viết chương trình, các bạn nên tách thành các function nhỏ, mỗi method thực hiện 1 function. Không nên gộp quá nhiều function trong 1 method, sẽ gây khó khăn khi bạn đọc lại code hoặc người khác review code cho bạn.
Các bạn đừng quên thêm quyền Internet trong AndroidMenifest nhé!
1
|
<uses–permission android:name=“android.permission.INTERNET”/>
|
Dưới đây là project của mình, các bạn có thể download về tham khảo, nhưng các bạn nên tự tay code để có thể nhớ lâu. Trong khi code thì nên tự đặt cho mình câu hỏi: Cái này dùng để làm gì? Nó thực hiện như thế nào? Tại sao lại dùng nó? bla…bla… Google là nơi có tất cả các câu trả lời phù hợp cho câu hỏi của các bạn. :))
CustomListView
Xem thêm: node js, java 8, string boot và thông tin tuyển dụng Android tại Tuyển dụng lập trình viên Android
android,
lập trình android,