Day 27 : AdapterKit

Day 27 : AdapterKit Cover Image

สวัสดีครับ บทความนี้เป็นบทความที่ 27 แล้วนะครับ ที่ผมจะมาเขียน ในซีรีย์ Learn 30 Android Libraries in 30 days

สำหรับบทความทั้งหมด อ่านได้จากด้านล่างครับ

สำหรับวันนี้ขอนำเสนอเรื่อง Adapter-Kit AdapterKit

เป็น Library ที่เอาไว้ช่วยให้เราทำ Custom ListView ได้ง่ายขึ้น เพราะตัว Adapter-Kit จะมี คลาส Adapter มาให้แล้ว อย่างเช่น เมื่อเรา ต้องการที่จะทำ Custom Adapter 4-5 แบบ แทนที่จะต้องมาสร้าง Adapter ทุกๆแบบ ก็ใช้แค่ Adapter-Kit ตัวเดียวเท่านั้นครับ หากยังไม่เห็นภาพ มาดูตัวอย่างกันดีกว่า

Installation

ขั้นตอนการติดตั้ง เปิดไฟล์ build.gradle ขึ้นมา แล้วเพิ่ม dependencies ลงไปดังนี้

dependencies {
    compile 'com.mobsandgeeks:adapter-kit:0.5.3'
}

กด Sync Gradle เป็นอันเรียบร้อย

Usage

การใช้งาน Adapter-Kit มีคลาสที่จำเป็นอยู่นั่นก็คือ

  • InstantAdapter : เป็นเหมือน Custom Adapter ของเรา ตัวเดียว ใช้ได้ตลอดงาน
  • ListView : อันนี้แน่นอนอยู่แล้ว เป็น ListView ธรรมดา
  • Model.class : อันนี้เป็นคลาส โมเดล เช่น คลาส Player คลาส Book คลาส Student เป็นต้น
  • List<Model> : เป็น List ของคลาสโมเดล ปกติเวลาเรา ใส่ค่าให้ Adapter จะเป็นพวก Array หรือว่า List อยู่แล้ว ซึ่งคล้ายๆกัน

การสร้างออปเจ็ค InstantAdapter ใช้คำสั่งนี้

List<Model> model = new ArrayList<Model>();
InstantAdapter adapter = new InstantAdapter(
        this,
        R.layout.list_item,
        Model.class,
        model);

โดย parameter มีดังนี้ - this คือ Context - R.layout.list_item: คือ resourceId (ชื่อ Layout) - Model.class : คลาสโมเดลของเรา - model : List ของคลาสโมเดล

จากนั้นก็สั่ง setAdapter() ปกติครับ

ListView listView = ...
listView.setAdapter(adapter);

สร้างโปรเจ็ค

มาลองสร้างโปรเจ็คดูกัน เริ่มแรก ทำการสร้างเลเอาท์ ภายในก็มีแค่ ListView

<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/list_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

</ListView>

ต่อมา เลเอาท์ของ listitem แต่ละ row ใน ListView ตั้งชื่อว่า `listitem.xml`

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:orientation="vertical"
              android:padding="5dp" >

    <TextView
        android:id="@+id/name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/club"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="right"
        android:textSize="15sp" />

</LinearLayout>

ต่อมาสร้างคลาส Java ชื่อว่า AdapterKitActivity แล้วทำการเซตเลเอาท์ และ binding ListView ดังนี้

package com.devahoy.learn30androidlibraries.day27;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.ListView;

import com.devahoy.learn30androidlibraries.R;

public class AdapterKitActivity extends ActionBarActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_adapter_kit);

        ListView listView = (ListView) findViewById(R.id.list_view);
    }
}

ตัว InstantAdapter มันใช้ คลาสโมเดล ด้วย ฉะนั้นผมสร้างคลาสโมเดลชื่อ Player ขึ้นมา มีแค่ name และ club ครับ

//Player.java

package com.devahoy.learn30androidlibraries.day27;

public class Player {

    public Player(String name, String club) {
        setName(name);
        setClub(club);
    }
    private String name;
    private String club;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getClub() {
        return club;
    }

    public void setClub(String club) {
        this.club = club;
    }
}

กลับมาที่ Activity อีกครั้ง คราวนี้ก็สร้างออปเจ็ค ของ InstantAdapter ที่เมธอด onCreate() ดังนี้

package com.devahoy.learn30androidlibraries.day27;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.ListView;

import com.devahoy.learn30androidlibraries.R;
import com.mobsandgeeks.adapters.InstantAdapter;

import java.util.ArrayList;
import java.util.List;

public class AdapterKitActivity extends ActionBarActivity {

    private List<Player> mPlayers;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_adapter_kit);

        ListView listView = (ListView) findViewById(R.id.list_view);

        initData();

        InstantAdapter adapter = new InstantAdapter(
                this,
                R.layout.list_item,
                Player.class,
                mPlayers);
        listView.setAdapter(adapter);
    }

    private void initData() {

        mPlayers = new ArrayList<Player>();

        mPlayers.add(new Player("Leonel Messi", "Barcelona"));
        mPlayers.add(new Player("Cristiano Ronaldo", "Real Madrid"));
        mPlayers.add(new Player("Teerasil Dangda", "UD Almeria"));
        mPlayers.add(new Player("Steven Gerrard", "Liverpool"));
        mPlayers.add(new Player("Arjen Robben", "Bayern"));
        mPlayers.add(new Player("Wayne Rooney", "Man Utd"));
        mPlayers.add(new Player("Sergio Aguero", "Man City"));
        mPlayers.add(new Player("Eden Hazard", "Chelsea"));
        mPlayers.add(new Player("Pipop On-Mo", "Chonburi FC"));
        mPlayers.add(new Player("Carmero Gonzalez", "Buriram Utd"));
    }
}

ด้านบนเป็นการสร้างข้อมูลจำลองขึ้นมาเพื่อเก็บใส่ List<Player> เพื่อเอาไว้ตอนสร้าง InstantAdapter ทดสอบ รันโปรแกรม

Result

อ้าวเห้ย! ทำไมไม่มีข้อมูลแสดง หว่า…????

ลืมไปหนึ่งอย่าง ไม่สงสัยหรอ ว่าทำไม แค่เราส่ง model กลับ layout ไปให้ InstantAdapter มันรู้ได้ไง ว่าตรงไหนจะต้องเป็น TextView ของ name อันไหนเป็น TextView ของ club จริงๆแล้ว ต้องไปแก้ที่คลาส Model ครับ เปิดไฟล์ Player.java ขึ้นมา แล้วเพิ่ม @InstantText(viewId = id) ที่เมธอด getName() และ getClub() ดังนี้

@InstantText(viewId = R.id.name)
public String getName() {
    return name;
}

@InstantText(viewId = R.id.club)
public String getClub() {
    return club;
}

จากโค๊ดด้านบน เราสั่งให้มันหา id ที่ชื่อ name จากนั้น ก็เซตค่า name ให้ ซึ่งก็คือ เซตค่า ์Player.name ให้กับ TextView นั่นเอง เช่นเดียวกัน อีกเมธอด คือการเซต Player.club ให้กับ TextView ที่มีไอดีชื่อ club ครับ ทดสอบรันใหม่อีกครั้ง คราวนี้ได้ผลลัพธ์แบบนี้

Result2

CircularAdapter

ัตัว Adapter-Kit ยังมี CircularAdapter ซึ่งช่วยให้เราแสดง ListView แบบ inifity เลย การสร้างก็ง่ายมาก แบบนี้

CircularListAdapter circularListAdapter = new CircularListAdapter(adapter);
listView.setAdapter(circularListAdapter);

การสร้างออปเจ็ค CircularListAdapter จาก InstantAdapter ของเรา จากนั้นก็ให้ ListView setAdapter() จาก adapter เดิมเป็น CircularListAdapter ทีนี้ลองรันดูใหม่ เมื่อ scroll ลงมาเรื่อยๆ ก็จะเป็น Endless ListView เลย

Result3

สรุป

จริงๆยังมีส่วน Section อีกนะครับ แต่ขี้เกียจทำละครับ ไม่ไหว หากใครสนใจ ลองไปศึกษาเพิ่มเติม จาก Sample ของ Adapter-Kit ดูนะครับ จากการลองใช้แล้ว ก็พบว่ามันยังมีข้อจำกัดอยู่พอสมควร ผมลองใช้กับ ImageView แล้วพบว่ามันไม่สามารถทำได้ เพราะว่าเห็น annotation ที่ใช้ได้ มีแค่ @InstantText() สำหรับ TextView อย่างเดียว เดี่ยวถ้ายังไง ลองเล่นเพิ่มเติม แล้วพบว่ามันสามารถทำพวก View อื่นๆ นอกเหนือจาก TextView ได้จะมาอัพเดทละกันครับ

Chai Chai Phonbopit : MEAN Stack @Nextzy • ผู้ชายธรรมดาๆ ที่ชื่นชอบ Android, JavaScript (Node.js) และ Open Source มีงานอดิเรกเป็น Acoustic Guitar และ Football

บทความล่าสุด