Hướng dẫn custom listview trong android

Thông qua bài hướng dẫn custom listview trong android, các bạn sẽ học cách customize layout cho ListView theo ý của mình và biết cách “trang điểm” để tạo ra một ListView đẹp. Lưu ý nếu bạn chưa từng làm việc với ListView, chúng tôi khuyên các bạn nên bắt đầu với bài giảng ListView trong android và bất cứ lúc nào bạn cần để hiển thị nhiều dữ liệu và làm cho nó dễ dàng để điều hướng, bạn hãy nghĩ ngay đến ListView mà xử lý tạo ra danh sách cuộn.

Hướng dẫn custom listview trong android – Bắt đầu

Tải project mẫu và giải nén

Mở Android Studio -> chọn File -> chọn Open -> chọn project mẫu đã tải và giải nén (Trong hình project mẫu chúng tôi chứa ở D:\Lecture\Tutorials\Android)

huong-dan-custom-listview-trong-android-1

Bulid và run, bạn sẽ nhìn thấy như hình bên dưới:

huong-dan-custom-listview-trong-android-2

Hướng dẫn custom listview trong android – Thêm ListView

Mở res/layout/activity_main.xml, thêm một ListView và đặt id là module_list_view

huong-dan-custom-listview-trong-android-3

Mở MainActivity.java và thêm một biến cho ListView

private ListView lvModule;

Thêm đoạn code sau vào bên trong phương thức onCreate

lvModule = (ListView) findViewById(R.id.module_list_view);
final ArrayList<Module> moduleList = Module.getModulesFromFile("modules.json", this);

String[] datas = new String[moduleList.size()];

for(int i = 0; i < moduleList.size(); i++){
    Module m = moduleList.get(i);
    datas[i] = m.title;
}

ArrayAdapter aa = new ArrayAdapter(this, android.R.layout.simple_list_item_1, datas);
lvModule.setAdapter(aa);

Build và run, bạn sẽ nhìn thấy kết quả như hình:

huong-dan-custom-listview-trong-android-4

Hướng dẫn custom listview trong android – Xây dựng Adapter

Chuột phải java/gsth.vn.modules -> chọn New -> chọn Java Class -> nhập ModuleAdapter

huong-dan-custom-listview-trong-android-5

Và bổ sung thêm extends BaseAdapter như bên dưới

public class ModuleAdapter extends BaseAdapter {

}

Thêm đoạn code sau vào lớp ModuleAdapter

private Context context;
private LayoutInflater li;
private ArrayList<Module> data;

public ModuleAdapter(Context context, ArrayList<Module> data) {
    this.context = context;
    this.data = data;
    this.li = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

Thêm tiếp các phương thức getCount()getItem()getItemId và getView() bằng cách nhấn tổ hợp phím Alt + Ins -> chọn Override Methods…

huong-dan-custom-listview-trong-android-6

Tại màn hình Select Methods to Override/Implement -> chọn các phương thức getCount()getItem()getItemId và getView()

huong-dan-custom-listview-trong-android-7

Kết quả nhận được

@Override
public int getCount() {
    return 0;
}

@Override
public Object getItem(int i) {
    return null;
}

@Override
public long getItemId(int i) {
    return 0;
}

@Override
public View getView(int i, View view, ViewGroup viewGroup) {
    return null;
}

Đối với phương thức getCount() chúng ta thay đổi lại như sau (chú ý phần tô màu đỏ)

@Override
public int getCount() {
    return data.size();
}

Bổ sung thêm và thay đổi xử lý cho phương thức getView() như sau

@Override
public View getView(int i, View view, ViewGroup viewGroup) {
    ViewHolder vh;
    if(view == null) {
        view = li.inflate(R.layout.list_item_module, null);

        vh = new ViewHolder();
        vh.ivThumbnail = (ImageView) view.findViewById(R.id.module_list_thumbnail);
        vh.tvTitle = (TextView) view.findViewById(R.id.module_list_title);
        vh.tvSubtitle = (TextView) view.findViewById(R.id.module_list_subtitle);
        vh.tvDetail = (TextView) view.findViewById(R.id.module_list_detail);

        view.setTag(vh);
    }
    else{
        vh = (ViewHolder) view.getTag();
    }

    Module m = data.get(i);

    vh.tvTitle.setText(m.title);
    vh.tvSubtitle.setText(m.subTitle);
    vh.tvDetail.setText(m.detail);
    Picasso.with(context).load(m.imageUrl).into(vh.ivThumbnail);

    return view;
}

Bổ sung thêm lớp nội ViewHolder

private static class ViewHolder {
    public TextView tvTitle;
    public TextView tvSubtitle;
    public TextView tvDetail;
    public ImageView ivThumbnail;
}

Mở MainActivity.java, thêm đoạn code sau trong phương thức onCreate

ModuleAdapter aa = new ModuleAdapter(this, moduleList);

huong-dan-custom-listview-trong-android-12

Mở build.gradle (Module:app) và thêm đoạn code sau và chọn Sync Now

compile 'com.squareup.picasso:picasso:2.5.2'

huong-dan-custom-listview-trong-android-8

Mở lớp ModuleAdapter, nhấn tổ hợp phím Alt + Enter -> chọn Import Class để Android Studio tự động bổ sung đoạn code import com.squareup.picasso.Picasso;

huong-dan-custom-listview-trong-android-9

Cấp quyền truy cập internet cho ứng dụng tại AndroidManifest.xml

<!-- Permission: Allow Connect to Internet -->
<uses-permission android:name="android.permission.INTERNET" />

huong-dan-custom-listview-trong-android-10

Build và run, bạn sẽ nhìn thấy kết quả sau

huong-dan-custom-listview-trong-android-11

Hướng dẫn custom listview trong android – Trang điểm cho ListView (Styling)

Trong phần này chúng tôi sẽ hướng dẫn các bạn cách thiết lập font chữ và màu chữ cho các TextView. Những font chữ sử dụng được chứa tại assets/fonts và màu chữ được khai báo values/colors.xml

Thiết lập font chữ

Mở ModuleAdapter.java và bổ sung đoạn code sau trong phương thức getView(). Lưu ý đoạn code được bổ sung ở vị trí trước lệnh return.

Typeface tfTitle =
        Typeface.createFromAsset(context.getAssets(), "fonts/JosefinSans-Bold.ttf");
vh.tvTitle.setTypeface(tfTitle);

Typeface tfSubtitle =
        Typeface.createFromAsset(context.getAssets(), "fonts/JosefinSans-SemiBoldItalic.ttf");
vh.tvSubtitle.setTypeface(tfSubtitle);

Typeface tfDetail =
        Typeface.createFromAsset(context.getAssets(), "fonts/Quicksand-Bold.otf");
vh.tvDetail.setTypeface(tfDetail);

Build và run, kết quả thu được sẽ như sau

huong-dan-custom-listview-trong-android-13

Thiết lập màu chữ

Mở lớp ModuleAdapter và bổ sung đoạn code sau (Lưu ý đoạn code bổ sung nằm phiá trên phương thức khởi tạo)

private HashMap<String, Integer> hmColor = new HashMap<String, Integer>() {{
    put("Android", R.color.colorLowCarb);
    put("iOS", R.color.colorLowFat);
}};

Thêm đoạn code bên dưới vào phía trên lệnh return của phương thức getView()

vh.tvDetail.setTextColor(ContextCompat.getColor(context, hmColor.get(m.detail)));

Build và run, chúng ta sẽ thấy kết quả như sau

huong-dan-custom-listview-trong-android-14

Hướng dẫn custom listview trong android -Tương tác người dùng

Chúng ta đã tạo xong ListView và đã thiết lập màu chữ, font chữ; tuy nhiên nếu người dùng click hoặc long click thì chương trình chưa có xử lý. Vậy trong phần này chúng tôi sẽ hướng dẫn các bạn cách đăng ký và xử lý sự kiện click của người dùng vào một item trong ListView. Cụ thể khi người dùng chọn vào một nội dung trong ListView, một bài viết chi tiết sẽ được hiển thị. Lưu ý bài viết này là link của một website. Bên dưới là cách thực hiện.

Tạo một Activity mới

Chuột phải java/gsth.vn.modules -> chọn New -> chọn Activity -> chọn Empty Activity -> nhập ModuleDetailActivity tại Activity Name -> chọn Finish

huong-dan-custom-listview-trong-android-15

Mở res/layout/activity_module_detail.xml và thêm một WebView

huong-dan-custom-listview-trong-android-16

Mở MainActivity.java và bổ sung đoạn code sau vào phía sau lệnh lvModule.setAdapter(aa); trong phương thức onCreate()

lvModule.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Module m = moduleList.get(position);
        Intent i = new Intent(getApplicationContext(), ModuleDetailActivity.class);
        i.putExtra("title", m.title);
        i.putExtra("url", m.instructionUrl);
        startActivity(i);
    }
});

Mở ModuleDetailActivity.java và thêm đoạn code trong phương thức onCreate()

WebView wv = (WebView)findViewById(R.id.detail_web_view);

Intent i = getIntent();
String title = i.getExtras().getString("title");
String url = i.getExtras().getString("url");

setTitle(title);
wv = (WebView) findViewById(R.id.detail_web_view);
wv.loadUrl(url);

Build và run. Khi chúng ta chọn vào nội dung ListView trong Android, một bài viết sẽ được hiên thị

huong-dan-custom-listview-trong-android-17