09 พฤศจิกายน 2555

[Android Code] การค้นหาคำใน List View


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

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

        ส่วนผู้ที่หลงเข้ามาอ่านคนใดจะประยุกต์ใช้งานก็ให้ดูที่ ArrayList<String> เป็นหัวใจสำคัญ ซึ่งจะไปเอาข้อมูลมาจากไหนก็แล้วแต่ ขอแค่ว่าดึงข้อมูลมาแล้วเก็บให้อยู่ในรูป ArrayList<String> เท่านี้ก็สามารถใช้คำสั่งจากในบทความนี้ได้เลย


Main.java
package app.akexorcist.listviewsearch;

import java.util.ArrayList;

import android.os.Bundle;
import android.app.Activity;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;

public class Main extends Activity {
    EditText editText1;
    ListView listView1;
    ArrayList<String> arr_list;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        arr_list = new ArrayList<String>();
        arr_list.add("apple");
        arr_list.add("avocado");
        arr_list.add("banana");
        arr_list.add("bamboo");
        arr_list.add("blackberry");
        arr_list.add("cabbage");
        arr_list.add("carrot");
        arr_list.add("corn");
        arr_list.add("durian");
        arr_list.add("eggplant");
        arr_list.add("fig");
        arr_list.add("garlic");
        arr_list.add("grape");
        arr_list.add("jojoba");
        arr_list.add("kale");
        arr_list.add("lettuce");
        arr_list.add("lychee");
        arr_list.add("macadamia");
        arr_list.add("mango");
        arr_list.add("mushroom");
        arr_list.add("nectarine");
        arr_list.add("onion");
        arr_list.add("pepper");
        arr_list.add("pineapple");
        arr_list.add("pumpkin");
        arr_list.add("radish");
        arr_list.add("raspberry");
        arr_list.add("spinach");
        arr_list.add("strawberries");
        arr_list.add("tomato");
        arr_list.add("turnip");
        arr_list.add("watermelon");

        listView1 = (ListView)findViewById(R.id.listView1);
        listView1.setAdapter(new ArrayAdapter(this
                , android.R.layout.simple_list_item_1, arr_list));
        
        editText1 = (EditText)findViewById(R.id.editText1);
        editText1.addTextChangedListener(new TextWatcher() {
            public void afterTextChanged(Editable arg0) {
                ArrayList<String> src_list = new ArrayList<String>();
                int textlength = editText1.getText().length();
                for(int i = 0 ; i < arr_list.size() ; i++){
                    try {
                        if(editText1.getText().toString()
                                .equalsIgnoreCase(arr_list.get(i)
                                .subSequence(0, textlength)
                                .toString())){
                            src_list.add(arr_list.get(i));
                        }
                    } catch (Exception e) { }
                }
                listView1.setAdapter(new ArrayAdapter(Main.this
                        , android.R.layout.simple_list_item_1
                        , src_list));
            }
            public void beforeTextChanged(CharSequence s, int start
                    , int count, int after) { }
            public void onTextChanged(CharSequence s, int start
                    , int before, int count) { }
            
        });
    }
}

สำหรับการทำงานของคำสั่ง เจ้าของบล็อกแนะนำให้สร้าง ArrayList<String>  2 ตัว
โดยที่ตัวแรกคือ arr_list เก็บ String Array ของชุดดั้งเดิมไว้ ส่วนอีกตัวก็ src_list
เก็บ String Array ที่จะเอามาแสดงเวลาผู้ใช้พิมคำที่จะค้นหา

จากนั้นก็ให้สร้าง Object ของ List View โดยให้แสดง arr_list ก่อน
แล้วก็ Object ของ EditText ต่อ โดยมีการสร้าง Listener ขึ้นมาด้วย
เป็น Text Changed Listener ซึ่งเป็น Listener เอาไว้ตรวจจับเวลาที่
ข้อความใน Edit Text มีการเปลี่ยนแปลง โดยจะประกอบไปด้วย 3 ฟังก์ชัน
beforeTextChanged คือ ก่อนที่ข้อความจะเปลี่ยนแปลง
afterTextChanged คือ หลังจากข้อความเปลี่ยนแปลงแล้ว
onTextChanged คือ ขณะที่ข้อความกำลังเปลี่ยนแปลง
สำหรับตัวอย่างนี้จะใช้แค่ afterTextChanged เท่านั้นแหละ

โดยจะสร้าง src_list ขึ้นมา เพื่อเก็บ String Array ที่เทียบกับคำที่จะค้นหา
และมีการเก็บจำนวนตัวอักษรที่พิมในช่อง Edit Text ด้วย
ส่วนการค้นหาคำก็ใช้ For วนลูปตามจำนวน String ที่เก็บไว้ใน arr_list
ด้วยการเทียบคำว่าเหมือนกับใน Edit Text หรือป่าว โดยคำที่เอามาเทียบ
จะตัดจำนวนคำให้เหลือเท่ากับ ที่พิมค้นหาในช่อง Edit Text
ถ้าสงสัยตรงนี้ให้ลองลบ .subSequence(0, textlength) ออก แล้วทดสอบดู
เมื่อมีคำไหนตรงกับที่ค้นหาก็จะให้เก็บคำนั้นๆไว้ใน src_list
และจะเห็นว่ามีการใช้ Try/Catch ด้วย เพราะว่าจะมี Exception เกิดขึ้นด้วย
เป็น ArrayOutOfBoundException เนื่องจากตอนค้นหาเจ้าของบล็อก
จะใช้คำสั่งตัดคำให้เหลือเท่ากับจำนวนคำที่พิมในช่องค้นหา
แต่ถ้าคำเมื่อคำที่ค้นหามีจำนวนตัวอักษรมากกว่าคำใน List View
ก็จะทำให้เกิด Exception นั่นเอง ซึ่งการ Catch ก็ไม่ได้ใส่อะไร ให้ข้ามไปเฉยๆ
เมื่อวนจนครบทุกตัวแล้ว ก็จะเอา src_list มาแสดงบน List View แทนของเก่า


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"
    android:background="#FFFFFF" >
    <EditText
        android:id="@+id/editText1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_margin="10dp"
        android:ems="10"
        android:lines="1" />
    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/editText1"
        android:layout_centerHorizontal="true"
        android:layout_margin="20dp" />
</RelativeLayout>


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


เพียงเท่านี้ก็ได้แล้ว ค้นหาคำที่ต้องการ
จะเอาไปประยุกต์ใช้ค้นหาคำอย่างอื่นก้ได้ 
ขอแค่เก็บคำเหล่านั้นไว้ใน ArrayList<String> ก็พอ

สำหรับผู้ที่หลงเข้ามาอ่านคนใดต้องการดาวน์โหลดไฟล์ตัวอย่าง
สามารถดาวน์โหลดได้จากที่นี่เลย ListViewSearch [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