[Android] การใช้งาน BaseAdapter

หลังจากตัวอย่างในตัวอย่างที่แล้ว ที่เราสร้าง ListActivity โดยแต่ละรายการมีรูปที่แตกต่างกันโดยใช้ SimpleAdapter วันนี้เราจะมาใช้ Adapter อีกตัวหนึ่งคือ BaseAdapter โดยวิธีการนี้เราต้องสร้าง class ขึ้นมาโดยสืบทอด BaseAdapter วิธีนี้เราสามารถควบคุมการแสดงผลได้มากกว่าที่ผ่านมา ตัวอย่างที่เราจะทำวันนี้ดัดแปลงมาจากตัวอย่างที่แล้ว โดยในแต่ละรายการจะมีจำนวน และให้ highlight แถวที่มีจำนวนน้อยกว่าหรือเท่ากับเกณฑ์ต่ำ โดยแต่ละรายการมีเกณฑ์ไม่เท่ากัน ลองดูผลลัพธ์ครับ


activity_main.xml
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />
row.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:gravity="center_vertical"
    >
 <TextView 
     android:id="@+id/name"
     android:layout_width="0dp"
     android:layout_height="match_parent"
     android:layout_weight="1"
     android:gravity="center_vertical"
     android:drawableLeft="@drawable/ico_apple"
     android:drawablePadding="10dp"
     />
 <TextView 
     android:id="@+id/num"
     android:layout_width="wrap_content"
     android:layout_height="match_parent"
     android:gravity="center_vertical"
     android:paddingRight="20dp"
     />    
</LinearLayout>


MainActivity.java
package com.simplelist;

import java.util.ArrayList;

import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends ListActivity {

 private ArrayList<Fruit> list;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  list =new ArrayList<Fruit>();
  list.add(new Fruit("Apple", R.drawable.ico_apple, 10, 5));
  list.add(new Fruit("Banana", R.drawable.ico_banana, 4, 5));
  list.add(new Fruit("Coconut", R.drawable.ico_coconut, 7, 10));
  list.add(new Fruit("Durian", R.drawable.ico_durian, 20, 15));
  list.add(new Fruit("Guava", R.drawable.ico_guava, 11, 5));
  list.add(new Fruit("Mango", R.drawable.ico_mango, 10, 4));
  list.add(new Fruit("Mangosteen", R.drawable.ico_mangosteen, 7, 1));
  list.add(new Fruit("Rambutant", R.drawable.ico_rambutant, 6, 5));
  
  CustomAdapter adapter = new CustomAdapter(this, R.layout.row, list);

  setListAdapter(adapter);
 }
 
 @Override
 public void onListItemClick(ListView lv, View v, int position, long id){
  Toast.makeText(this, "You click " + list.get(position).getName(), Toast.LENGTH_SHORT).show();
 }
}
Fruit.java
package com.simplelist;

public class Fruit {

 private String name;
 private int image;
 private int remain;
 private int warning_number;
 
 public Fruit(String name, int image, int remain, int warning_number){
  this.name = name;
  this.image = image;
  this.remain = remain;
  this.warning_number = warning_number;
 }
 
 public String getName(){return name;}
 
 public int getImage(){return image;}
 
 public int getRemain(){return remain;}
 
 public boolean isLower(){return remain <= warning_number;}
}
CustomAdapter.java
package com.simplelist;

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class CustomAdapter extends BaseAdapter{

 private ArrayList<Fruit> mList;
 private int mLayoutId;
 private Context mCtx;
 LayoutInflater inflater;
 
 public CustomAdapter(Context ctx, int layoutId, ArrayList<Fruit> list){
  this.mCtx = ctx;
  this.mList = list;
  this.mLayoutId = layoutId;
  inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 }
 
 @Override
 public int getCount() {
  return mList.size();
 }

 @Override
 public Object getItem(int position) {
  return mList.get(position);
 }

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

 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
  View v = inflater.inflate(mLayoutId, parent, false);
  Fruit fruit = mList.get(position);
  TextView tvName = (TextView) v.findViewById(R.id.name);
  TextView tvNum = (TextView) v.findViewById(R.id.num);
  tvName.setText(fruit.getName());
  tvNum.setText(Integer.toString(fruit.getRemain()));
  tvName.setCompoundDrawablesWithIntrinsicBounds(fruit.getImage(), 0, 0, 0);
  if(fruit.isLower()){
   v.setBackgroundColor(Color.RED);
  }
  return v;
 }
}
ใน activity_main.xml สร้าง ListView ขึ้นมากำหนด id เป็น android:id/list เพื่อเราจะได้ extends ListActivity ใน MainActivity สร้าง ArrayList เก็บ Fruit ชื่อ list เราสร้าง class ชื่อ Fruit ขึ้นมากโดยเก็บ name, id รูปภาพ , จำนวน, เกณฑ์ขึ้นต่ำ จากนั้นก็ add fruit ใส่ใน list
  list = new ArrayList<Fruit>();
  list.add(new Fruit("Apple", R.drawable.ico_apple, 10, 5));
  list.add(new Fruit("Banana", R.drawable.ico_banana, 4, 5));
  list.add(new Fruit("Coconut", R.drawable.ico_coconut, 7, 10));
  list.add(new Fruit("Durian", R.drawable.ico_durian, 20, 15));
  list.add(new Fruit("Guava", R.drawable.ico_guava, 11, 5));
  list.add(new Fruit("Mango", R.drawable.ico_mango, 10, 4));
  list.add(new Fruit("Mangosteen", R.drawable.ico_mangosteen, 7, 1));
  list.add(new Fruit("Rambutant", R.drawable.ico_rambutant, 6, 5));
จากนั้น ทำการ new CustomAdapter โดย class CustomAdapter นั้น extends มาจาก BaseAdapter มี method getCount, getItem, getItemId, getView โดยเฉพาะใน method getView เราทำการนำค่าจาก object fruit ไปใส่ใน View และเช็คว่าจำนวนต่ำกว่าเกณฑ์หรือไม่ ถ้าต่ำกว่าก็ใส่พื้นหลังสีแดง
 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
  View v = inflater.inflate(mLayoutId, parent, false);
  Fruit fruit = mList.get(position); //get current object
  TextView tvName = (TextView) v.findViewById(R.id.name);
  TextView tvNum = (TextView) v.findViewById(R.id.num);
  tvName.setText(fruit.getName());
  tvNum.setText(Integer.toString(fruit.getRemain()));
  tvName.setCompoundDrawablesWithIntrinsicBounds(fruit.getImage(), 0, 0, 0); // กำหนดรูปให้กับ textview parameter เรียงตามนี้ left, top, right, bottom  เราใส่ด้านซ้ายก็ใส่ตัวแรกตัวเดียว ที่เหลือใส่ 0
  if(fruit.isLower()){ // เช็คว่าต่ำกว่าหรือไม่
   v.setBackgroundColor(Color.RED);
  }
  return v;
 }
เสร็จแล้วลอง run ดูจากตัวอย่างนี้เราจะได้วิธีการแสดงผลที่มากขึ้นเพราะเราสามารถควบคุมได้มากกว่าตัวอย่างก่อนๆ ลองหาวิธีการของตัวเองดูครับว่าชอบแบบไหนแล้วใช้ให้เหมาะกับสถานการณ์