24 กันยายน 2556

[Android Design] เปลี่ยนภาพ Button ได้ดั่งใจด้วย Selector [Custom Button]


        บทความเก่าเอามาทำใหม่นะครับ กับการทำ Custom Button หรือก็คือการออกแบบภาพ Button ให้เป็นแบบที่ต้องการ


        สำหรับผู้ที่หลงเข้ามาอ่านมือใหม่หลายๆคน มักจะเข้าใจว่าถ้าอยากทำปุ่มที่เป็นภาพที่ออกแบบไว้จะต้องใช้ Image Button ซึ่งจริงๆแล้วเป็นความเข้าใจที่ไม่ถูกต้องซักเท่าไรนัก เพราะ Image Button ก็สืบทอดมาจาก Button นั้นแหละ แค่สามารถกำหนดให้ใส่ภาพลงไปโดยตรงใน Properties ได้

        แต่การทำให้เวลาปุ่มยังไม่ถูกกดเป็นภาพนึง และถูกกดเป็นอีกภาพก็ต้องใช้วิธีเช่นเดียวกับ Button อยู่ดี จึงไม่ต่างกันเลย ดังนั้นในมุมมองเจ้าของบล็อกแล้ว Image Button ไม่จำเป็นซักเท่าไร

        ในการทำให้ปุ่มแสดงภาพและเปลี่ยนภาพเวลากดที่ปุ่มนั้น จะใช้สิ่งที่เรียกว่า Selector เข้ามาจัดการให้ ซึ่งเป็น Resource แบบหนึ่ง สามารถสร้างขึ้นมาได้ด้วยการสร้างไฟล์ xml ใน res/drawable แล้วกำหนดคำสั่ง XML ให้ทำหน้าที่เป็น Selector นั่นเอง


        สำหรับการสร้าง Selector เพื่อใช้กับ Button จะมีขั้นตอนดังนี้

        ก่อนอื่นสร้างโฟลเดอร์ drawble ไว้ก่อน เนื่องจาก Selector นั้น ไม่มีผลกับรูปแบบของอุปกรณ์แอนดรอยด์ เช่น ขนาดหน้าจอ จึงไม่จำเป็นต้องสร้างแยกตามโฟลเดอร์ drawable แต่อย่างใด จึงให้สร้างไว้ใน drawable ไว้เลย ซึ่งเป็นโฟลเดอร์ Default เพื่อให้อุปกรณ์แอนดรอยด์ทุกแบบสามารถใช้งาน Selector ตัวนี้ได้



        จากนั้นก็คลิกขวาที่โฟลเดอร์ drawable เลือก New > Other...



        ที่หน้า New ให้เลือก Android XML File แล้วกดปุ่ม Next



        ต่อมาจะเป็นการกำหนดไฟล์ XML ให้เลือกที่ selector แล้วตั้งชื่อไฟล์ให้เรียบร้อย ตัวอย่างนี้ใช้ชื่อว่า selector_button.xml เมื่อกำหนดเสร็จแล้วก็กดปุ่ม Finish ได้เลย



        เปิดไฟล์ขึ้นมา จะเห็นว่ามีลักษณะคำสั่งคล้ายกับ Layout เพียงแต่ว่าจะเริ่มต้นด้วยแท็กของ Selector



        ภายในแท็กของ Selector ให้พิมว่า

        <item android:

        จากนั้นก็ลองกดปุ่ม Ctrl + Space Bar เพื่อเรียก Hint ดู



        จะพบว่ามีคำสั่งสำหรับ Item หลายๆอย่างให้เลือก ถ้าสังเกตดีๆพวกนี้คือคำสั่งเช็คเงื่อนไขในกรณีต่างๆซึ่งจะใช้วิธีเช็คว่าเป็น True หรือ False อย่างเช่น

        android:state_pressed="true"

        จะเป็นกรณีที่ Button ถูกกดนั่นเอง ถ้าเป็น False ก็คือไม่ถูกกด สำหรับ Selector บน Button จะมีเงื่อนไขหลักๆจะมีด้วยกันดังนี้



        อย่างกรณี Normal คือปุ่มแสดงอยู่ปกติ ไม่ถูกกด เงื่อนไขของมันก็คือปุ่มไม่ถูกกด ไม่ถูกโฟกัส และใช้งานได้ ซึ่งเงื่อนในกรณีอื่นๆก็จะแตกต่างกันออกไป ดังนั้นจึงสามารถกำหนดภาพที่จะแสดงสำหรับในแต่ละกรณีได้ดังนี้



        สำหรับ drawable ที่เอามากำหนดก็คือภาพที่เจ้าของสร้างเตรียมไว้ แล้วเอามาเก็บไว้ในโฟลเดอร์ drawable นั่นเอง


        ก่อนอื่นขอคั่นด้วยเรื่องสถานะของ Button หลักๆกันก่อน สำหรับสถานะของ Button จะมีด้วยกันหลักๆ 5 สถานะตามภาพข้างบน

        Normal คือสถานะปกติ คือปุ่มยังไม่ถูกกดและสามารถใช้งานได้ (กดได้)

        Focused เป็นสถานะเหมือนมี Cursor มาเลือกไว้ แต่ยังไม่ได้กดเลือก คล้ายๆกับ Cursor บนคอมพิวเตอร์แหละที่ผู้ใช้คลิกเลือกโฟลเดอร์ใดๆ แต่ยังไม่ได้กดเปิดโฟลเดอร์นั้นๆ สถานะนี้ปกติจะไม่ค่อยเห็นกัน ต้องลองต่อคีย์บอร์ดหรือจอยเกมเข้ากับเครื่องแล้วกดปุ่มลูกศร หรือไม่ก็ลองบน Emulator แล้วกดลูกศรทิศทางดู จะเห็น Cursor

ภาพตัวอย่าง ใช้จอยเกมต่อเข้ากับ Nexus 10  แล้วควบคุม Cursor เพื่อเลือกแอพที่จะเปิดได้
ในภาพ Google+ จะอยู่ในสถานะ Focus  ส่วนแอปพลิเคชันอื่นๆจะอยู่ในสถานะ Normal

        Pressed เป็นสถานะเมื่อถูกกด เมื่อผู้ใช้กดลงบน Button นั้นๆ

        Disable คือสถานะไม่สามารถกดได้ เอาไว้เวลาไม่ต้องการให้ผู้ใช้กด อย่างเช่นกำลังโหลดไฟล์อยู่ จึงทำการ Disable ปุ่มแสดงไฟล์นั้นๆก่อน แล้วรอให้ทำการโหลดไฟล์จนเสร็จค่อยให้ปุ่มนั้นสามารถกดได้ (Normal)

        Disable Focused คือ Button ถูก Focus เมื่ออยู่ในสถานะ Disable (ในสถานะ Disable นั้นสามารถ Focus ได้แต่ Press ไม่ได้นะเออ)


        เจ้าของบล็อกเก็บภาพนี้ไว้ใน drawable-mdpi เพราะทำภาพมาสำหรับ mdpi ซึ่งภาพที่ใช้ใน Selector นี้สามารถแยกเก็บในโฟลเดอร์ตามคุณสมบัติได้เลย สามารถทำภาพปุ่มสำหรับ ldpi mdpi hdpi xhdpi และ xxhdpi ได้ (ในตัวอย่างนี้ขี้เกียจ จึงมีแค่ภาพสำหรับ mdpi เพราะเอาภาพมาจาก Android)



        อย่าลืมว่านี่เป็นแค่ขั้นตอนการสร้าง Selector เท่านั้นนะ ต้องไปกำหนด Selector ให้กับ Button ที่ต้องการใน Layout ด้วย

        โดยเจ้าของบล็อกก็มาที่ Layout ของโปรเจค แล้วเพิ่ม Button ลงไป



        ทีนี้ที่ Properties ของ Button กดปุ่มสามจุดที่อยู่ท้ายแถวของ Background



        จะมีหน้าต่าง Reference Chooser แสดงขึ้นมา เพื่อเลือกภาพที่จะกำหนดเป็น Background ก็เลือก Selector ที่สร้างไว้ได้เลย



        Button ก็จะใช้ภาพที่กำหนดไว้ใน Selector แล้ว ภาพที่ใช้มีข้อความอยู่แล้วก็ลบข้อความ Text บน Button ออกด้วย ไม่งั้นเดี๋ยวข้อความจะซ้อนกัน



มาดูที่หน้าโค๊ด xml ของ Layout ดูบ้าง เผื่ออยากดูแบบโค๊ดกัน



        ทีนี้ให้ลองทดสอบบนเครื่องดู ภาพ Button ก็จะเป็นไปตามเงื่อนไขที่กำหนด สำหรับ Focused ต้องลองบนพวก Emulator นะ ให้ลองกดลูกศรบนคีย์บอร์ดดู เพื่อทำการ Focused ไปที่ปุ่มนั้นๆ ส่วน Disable จะต้องเขียนโค๊ดสั่งให้ Disable ถึงจะเห็น เพราะการทำงานโดยปกติแล้ว Button จะแสดงอยู่แค่ Normal กับ Pressed

        สำหรับ Focused และ Disable Focused ก็ไม่จำเป็นมากซักเท่าไร ก็ตัดออกไปได้ ก็เหลือแค่ Normal, Pressed และ Disable เท่านั้นที่สำคัญ ดังนั้นในโค๊ดของ Selector ก็เหลือโค๊ดแค่ส่วนที่สำคัญดังนี้



        และในกรณีที่ Button นั้นๆ ไม่ได้ถูกสั่งให้ Disable อยู่แล้ว ก็สามารถตัด Disable ออกได้เลยเช่นกัน ให้เหลือแค่ Normal กับ Pressed แค่สองกรณีก็พอ



        ก็ขอให้นำไปใช้ตามการใช้งานละกันนะ เอาไปคิดดูเองว่า Button ของผู้ที่หลงเข้ามาอ่านมีการทำงานในกรณีใดบ้าง เพราะจะได้ไม่ต้องทำภาพสำหรับเงื่อนไขที่ไม่ได้ใช้งานเลย

        ถ้า Button ตัวนั้นเป็นแค่ Button ปกติมีไว้กดก็ใช้แค่ Normal กับ Pressed แต่ถ้ามีการ Disable ปุ่มเพื่อให้กดไม่ได้ในลางครั้ง ก็ต้องเพิ่ม Disable ด้วย เพื่อที่จะได้แสดงภาพ Button ที่มีสถานะเป็น Disable อยู่ ส่วน Focused กับ Disable Focused ไม่ค่อยจำเป็น ตัดออกก็ได้

        อ้ออย่างสุดท้าย ถ้าขี้เกียจทำภาพ สามารถใช้ Shape ได้นะ กำหนดชื่อไฟล์ของ Shape ลงไปใน android:drawable ของ Selector ได้เลย [Android Design] สร้างภาพง่ายๆจาก XML ด้วย Shape [Drawable Resource]


        สำหรับผู้ที่หลงเข้ามาอ่านคนใดที่ต้องการไฟล์ตัวอย่างสามารถดาวน์โหลดได้ที่

                Custom Button [Google Drive]

                Custom Button [GitHub]

                Custom Button [Sleeping For Less]




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

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