23 ธันวาคม 2555

[Android Code] การใช้ List View แสดงตัวเลือกเพื่อแสดงข้อมูลจากฐานข้อมูล


วันนี้ก็ควบสองบทความเลยละกัน ต่อจากของเก่าที่เป็นเรื่องของ List View

แต่คราวนี้จะประยุกต์กันเล็กน้อยจากตัวอย่างเดิมกันบ้าง
โดยจะให้แสดงรายชื่อสัตว์จำนวนหนึ่งบน List View
และเมื่อเลือกชื่อสัตว์ตัวไหน ก็จะแสดง Dialog ขึ้นมา
พร้อมกับแสดงข้อมูลของสัตว์ตัวนั้นๆ บน Dialog
โดยข้อมูลของสัตว์ทั้งหมดจะเก็บไว้ในฐานข้อมูล


หลักการคร่าวๆก็คือดึงรายชื่อสัตว์ที่มีทั้งหมดมาแสดงใน List View ก่อน
แล้วกำหนด Listener โดยใช้ onItemClickListener ให้กับ List View
เมื่อเลือกรายชื่อสัตว์ใดๆ ก็จะแสดง Dialog ขึ้นมา แล้วให้ดึงข้อมูลในฐานข้อมูล
แล้วนำมาแสดงด้วย Text View ที่มีทั้งหมด 6 ตัว เพื่อแสดงข้อมูลแต่ละอย่าง
สำหรับการสร้างฐานข้อมูลเบื้องต้นสามารอ่านได้จากบทความของเจ้าของบล็อกเลย


ส่วนข้อมูลที่ใช้ในตัวอย่างนี้ก็จะประกอบด้วยข้อมูลดังนี้



ทีนี้ก็มาดูที่โค๊ดตัวอย่างของเจ้าของบล็อกกันต่อเลย



Main.java
package app.akexorcist.listviewdatabasedialog;

import java.util.ArrayList;

import android.os.Bundle;
import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;

public class Main extends Activity {

    SQLiteDatabase mDb;
    Database mHelper;
    Cursor mCursor;
    
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mHelper = new Database(this);
        mDb = mHelper.getWritableDatabase();
        
        mCursor = mDb.rawQuery("SELECT * FROM " 
                + Database.TABLE_NAME, null);
        
        ArrayList<String> dirArray = new ArrayList<String>();
        
        mCursor.moveToFirst();
        while ( !mCursor.isAfterLast() ){
            dirArray.add(mCursor.getString(mCursor.getColumnIndex
                    (Database.COL_THNAME)));
            mCursor.moveToNext();    
        }
                
        ListView listView1 = (ListView)findViewById(R.id.listView1);
        listView1.setAdapter(new ArrayAdapter(this
                , android.R.layout.simple_list_item_1, dirArray));
        listView1.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> arg0, View arg1
                    , int arg2, long arg3) {
                mCursor.moveToPosition(arg2);
                
                final Dialog dialog = new Dialog(Main.this);
                dialog.requestWindowFeature
                        (dialog.getWindow().FEATURE_NO_TITLE);
                dialog.setContentView(R.layout.dialog_data);
                
                TextView textTHName = 
                        (TextView)dialog.findViewById(R.id.textTHName);
                textTHName.setText("Name [TH] : " 
                        + mCursor.getString(mCursor.getColumnIndex
                        (Database.COL_THNAME)));

                TextView textENName = 
                        (TextView)dialog.findViewById(R.id.textENName);
                textENName.setText("Name [EN] : " 
                        + mCursor.getString(mCursor.getColumnIndex
                        (Database.COL_ENNAME)));

                TextView textKingdom =
                        (TextView)dialog.findViewById(R.id.textKingdom);
                textKingdom.setText("Kingdom : " 
                        + mCursor.getString(mCursor.getColumnIndex
                        (Database.COL_KINGDOM)));

                TextView textPhylum = 
                        (TextView)dialog.findViewById(R.id.textPhylum);
                textPhylum.setText("Phylum : " 
                        + mCursor.getString(mCursor.getColumnIndex
                        (Database.COL_PHYLUM)));

                TextView textClass = 
                        (TextView)dialog.findViewById(R.id.textClass);
                textClass.setText("Class : " 
                        + mCursor.getString(mCursor.getColumnIndex
                        (Database.COL_CLASS)));

                TextView textOrder = 
                        (TextView)dialog.findViewById(R.id.textOrder);
                textOrder.setText("SOrder : " 
                        + mCursor.getString(mCursor.getColumnIndex
                        (Database.COL_ORDER)));
                
                Button buttonOK = 
                        (Button)dialog.findViewById(R.id.buttonOK);
                buttonOK.setOnClickListener(new OnClickListener() {
                    public void onClick(View v) {
                        dialog.cancel();
                    }
                });
                
                dialog.show();
            }
        });
    }
    
    public void onPause() {
        super.onPause();
        mHelper.close();
        mDb.close();  
    }
}

สำหรับคำสั่งใน Main.java เริ่มแรกมาก็จะให้สร้างฐานข้อมูลกันก่อน
โดยจะเห็นว่า mCursor ใช้คำสั่ง SELECT * ซึ่งก็คือเลือกทุกคอลัมน์นั่นเอง
จากเดิมที่เจ้าของบล็อกมักจะกำหนดเป็นคอลัมน์ที่ต้องการดึงข้อมูลเท่านั้น
แต่ทีนี้เจ้าของบล็อกใช้ * (ดอกจันทร์) บ้าง เพราะจะเลือกข้อมูลทุกคอลัมน์
จากนั้นก็สร้าง dirArray ที่เป็น ArrayList<String> เพื่อเก็บชื่อสัตว์จาก mCursor
แล้วเอาไปแสดงใน List View เพื่อทำเป้นตัวเลือกที่เป็นรายชื่อสัตว์
แล้วก็สร้าง onItemClickLister ให้กับ List View เหมือนเคยนั่นแหละ
จากนั้นก็จะใช้คำสั่ง mCursor.moveToPosition(arg2); ก่อนอย่างแรก
สำหรับคำสั่งนี้จะเป็นคำสั่งเลื่อนเคอร์เซอร์ให้กับ mCursor 
โดย arg2 ก็คือให้ mCursor เลื่อนไปแถวนั้นๆ นั่นเอง
สมมติว่าผู้ใช้เลือก ยีราฟ ที่อยู่ในแถวที่ 3 ค่า arg2 ก็จะเป็น 2
(อย่าลืมว่าลำดับใน List View จะเริ่มนับแถวแรกเป็น 0)
เมื่อค่า arg2 เป็น 2 ก็จะให้ mCursor ใช้คำสั่ง moveToPosition
ดังนั้น mCursor ก็จะเลื่อนไปยังข้อมูลแถวที่ 3 ในฐานข้อมูล
ซึ่งข้อมูลในแถวที่ 3 ก็คือข้อมูลของ ยีราฟ นั่นเอง

จากนั้นก็จะให้สร้าง Dialog ขึ้นมาเพื่อแสดงข้อมูลของสัตว์ที่เลือก
Dialog ที่ใช้ก็เป็น Custom Dialog เหมือนเดิม โดยสามารถดูเพิ่มเติมได้จาก

จากนั้นก็ทำการประกาศ Text View ให้ครบทุกตัวที่สร้างไว้ 
แล้วกำหนดให้ Text View ดึงข้อมูลแต่ละคอลัมน์ในฐานข้อมูลมาแสดง
โดย Text View แต่ละตัวก็จะมีคอลัมน์ที่จะแสดงตายตัวอยู่แล้ว
แต่ด้วยเนื่องจาก mCursor ได้เลือกอยู่ในแถวของ ยีราฟ [moveToPosition(arg2)]
ดังนั้นข้อมูลในแต่ละคอลัมน์ที่ดึงมาแสดงก็คือข้อมูลของยีราฟ
แล้วก็ทำการสร้างปุ่มสำหรับปิดหน้าต่าง Dialog เหมือนเคย

ส่วนใน onPause ก็เอาไว้ปิดฐานข้อมูลเวลาที่ Activity หยุดทำงานลงนั่นเอง
หรือจะปิดทันที่ที่ดึงข้อมูลเสร็จแล้วก็ได้เช่นกัน แล้วแต่สะดวกเลย

main.xml
<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" >
    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:layout_margin="30dp"
        android:scrollingCache="false" />
</RelativeLayout>

Database.java
package app.akexorcist.listviewdatabasedialog;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

class Database extends SQLiteOpenHelper {
    private static final String DB_NAME = "Animal";
    private static final int DB_VERSION = 1;
    
    public static final String TABLE_NAME = "AnimalData";

    public static final String COL_THNAME = "c_name_th";
    public static final String COL_ENNAME = "c_name_en";
    public static final String COL_KINGDOM = "c_kingdom";
    public static final String COL_PHYLUM = "c_phylum";
    public static final String COL_CLASS = "c_class";
    public static final String COL_ORDER = "c_order";
    
    public Database(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }

    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE "+ TABLE_NAME 
                +" (_id INTEGER PRIMARY KEY AUTOINCREMENT, " 
                + COL_THNAME + " TEXT, " + COL_ENNAME + " TEXT, " 
                + COL_KINGDOM + " TEXT, " + COL_PHYLUM + " TEXT, " 
                + COL_CLASS + " TEXT, " + COL_ORDER + " TEXT);");
        
        db.execSQL("INSERT INTO "+ TABLE_NAME +" (" + COL_THNAME 
                + ", " + COL_ENNAME + ", " + COL_KINGDOM + ", " 
                + COL_PHYLUM + ", " + COL_CLASS + ", " + COL_ORDER 
                + ") VALUES ('นกแก้ว', 'Parrots', 'Animalia', 'Chordata'" 
                + ", 'Aves', 'Psittaciformes');");  
        db.execSQL("INSERT INTO "+ TABLE_NAME +" (" + COL_THNAME 
                + ", " + COL_ENNAME + ", " + COL_KINGDOM + ", " 
                + COL_PHYLUM + ", " + COL_CLASS + ", " + COL_ORDER 
                + ") VALUES ('สิงโต', 'Lion', 'Animalia', 'Chordata'" 
                + ", 'Mammalia', 'Carnivora');");  
        db.execSQL("INSERT INTO "+ TABLE_NAME +" (" + COL_THNAME 
                + ", " + COL_ENNAME + ", " + COL_KINGDOM + ", " 
                + COL_PHYLUM + ", " + COL_CLASS + ", " + COL_ORDER 
                + ") VALUES ('ยีราฟ', 'Giraffe', 'Animalia', 'Chordata'" 
                + ", 'Mammalia', 'Artiodactyla');");  
        db.execSQL("INSERT INTO "+ TABLE_NAME +" (" + COL_THNAME 
                + ", " + COL_ENNAME + ", " + COL_KINGDOM + ", " 
                + COL_PHYLUM + ", " + COL_CLASS + ", " + COL_ORDER 
                + ") VALUES ('ค้างคาว', 'Bat', 'Animalia', 'Chordata'" 
                + ", 'Mammalia', 'Eutheria');");  
        db.execSQL("INSERT INTO "+ TABLE_NAME +" (" + COL_THNAME 
                + ", " + COL_ENNAME + ", " + COL_KINGDOM + ", " 
                + COL_PHYLUM + ", " + COL_CLASS + ", " + COL_ORDER 
                + ") VALUES ('จิงโจ้', 'Kangaroo', 'Animalia', 'Chordata'" 
                + ", 'Mammalia', 'Diprotodontia');");  
        db.execSQL("INSERT INTO "+ TABLE_NAME +" (" + COL_THNAME 
                + ", " + COL_ENNAME + ", " + COL_KINGDOM + ", " 
                + COL_PHYLUM + ", " + COL_CLASS + ", " + COL_ORDER 
                + ") VALUES ('ซาลาแมนเดอร์', 'Salamanders', 'Animalia'" 
                + ", 'Chordata', 'Amphibia', 'Caudata');");  
        db.execSQL("INSERT INTO "+ TABLE_NAME +" (" + COL_THNAME 
                + ", " + COL_ENNAME + ", " + COL_KINGDOM + ", " 
                + COL_PHYLUM + ", " + COL_CLASS + ", " + COL_ORDER 
                + ") VALUES ('กวาง', 'Deer', 'Animalia', 'Chordata'" 
                + ", 'Mammalia', 'Artiodactyla');");  
        db.execSQL("INSERT INTO "+ TABLE_NAME +" (" + COL_THNAME 
                + ", " + COL_ENNAME + ", " + COL_KINGDOM + ", " 
                + COL_PHYLUM + ", " + COL_CLASS + ", " + COL_ORDER 
                + ") VALUES ('ปลาโลมา', 'Dolphin', 'Animalia', 'Chordata'" 
                + ", 'Mammalia', 'Cetacea');");  
        db.execSQL("INSERT INTO "+ TABLE_NAME +" (" + COL_THNAME 
                + ", " + COL_ENNAME + ", " + COL_KINGDOM + ", " 
                + COL_PHYLUM + ", " + COL_CLASS + ", " + COL_ORDER 
                + ") VALUES ('ม้าน้ำ', 'Seahorses', 'Animalia', 'Chordata'" 
                + ", 'Actinopterygii', 'Syngnathiformes');");  
    }
    
    public void onUpgrade(SQLiteDatabase db, int oldVersion
            , int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS "+ TABLE_NAME);
        onCreate(db);
    }
}

สำหรับ Database.java ก็เป็นส่วนที่ใช้สร้างฐานข้อมูลทั่วไป
โดยข้อมูลที่กำหนดก็เป็นข้อมูลจากภาพตารางข้างบนที่แปะไว้แล้ว
ส่วนรายละเอียดของการสร้างฐานข้อมูลสามารถอ่านได้ที่
[Android Code] SQLite บน Android เบื้องต้น (แอบละเอียด)


dialog_data.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:background="#FFFFFF"
    android:gravity="center" >
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_margin="30dp" > 
        <TextView
            android:id="@+id/textTHName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:text="Thai Name"
            android:textColor="#000000"
            android:textSize="18sp" />
        <TextView
            android:id="@+id/textENName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:text="English"
            android:textColor="#000000"
            android:textSize="18sp" />
        <TextView
            android:id="@+id/textKingdom"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:text="Kingdom"
            android:textColor="#000000"
            android:textSize="18sp" />
        <TextView
            android:id="@+id/textPhylum"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:text="Phylum"
            android:textColor="#000000"
            android:textSize="18sp" />
        <TextView
            android:id="@+id/textClass"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:text="Class"
            android:textColor="#000000"
            android:textSize="18sp" />
        <TextView
            android:id="@+id/textOrder"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="30dp"
            android:text="Order"
            android:textColor="#000000"
            android:textSize="18sp" />
        <Button
            android:id="@+id/buttonOK"
            android:layout_width="80dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="OK" />
    </LinearLayout>
</LinearLayout>

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="app.akexorcist.listviewdatabasedialog"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="8" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="app.akexorcist.listviewdatabasedialog.Main"
            android:label="@string/app_name" 
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

เพียงเท่านี้ก็เรียบร้อยแล้วสำหรับการประยุกต์การใช้งาน List View
เหมาะสำหรับการเอาไปแสดงข้อมูลต่างๆ โดยที่ข้อมูลเก็บไว้ในฐานข้อมูล
ซึ่งตัวอย่างนี้ใช้ Custom Dialog จึงทำให้สามารถออกแบบหน้าต่าง Dialog ได้


สำหรับผู้ที่หลงเข้ามาอ่านที่อยากจะเอาไฟล์ตัวอย่างไปลอง
ก็ดาวน์โหลดจากตรงนี้ได้เลย List View Database Dialog [Google Drive]




เหล่าพันธมิตรแอนดรอยด์

Devahoy Layer Net NuuNeoI The Cheese Factory Somkiat CC Mart Routine Artit-K Arnondora Kamonway Try to be android developer Oatrice Benz Nest Studios Kotchaphan@Medium Jirawatee@Medium Travispea@Medium