10 September 2013

การเก็บค่าไว้ใน Value Resource

Updated on

บทความรอบนี้มาเจาะลึกเรื่องการใช้งาน Resource กันบ้าง
เพราะเห็นว่าผู้ที่หลงเข้ามาอ่านหลายๆคนยังใช้กันไม่เป็น


สำหรับ Resource เป็นอีกวิธีหนึ่งที่จะช่วยให้สามารถเก็บค่าใดๆไว้ได้
โดยไม่ต้องใช้โค๊ดจาวาเลย เพื่อให้สามารถจัดการกับข้อมูลเป็นสัดส่วน
เพราะในงานที่มีความซับซ้อนสูง การจัดข้อมูลให้เป็นสัดส่วนจะสำคัญมาก
เพราะจะทำให้เวลาแก้ไขหรือปรับปรุงใดๆ สามารถเข้าไปจัดการได้สะดวก
ซึ่งจะอยู่ในรูปของ xml ที่อยู่ในโฟลเดอร์ res ที่คุ้นเคยกันดีนั่นแหละ
แต่ในบทความนี้จะขอพูดถึงแค่ xml ที่อยู่ใน res/values อย่างเดียวนะ
เพราะมันมีเยอะเกินเลยขอแบ่งส่วนอธิบายดีกว่าจะได้อธิบายเยอะๆ
สำหรับในโฟลเดอร์ values ไฟล์ xml ที่เก็บไว้ในนั้นก็จะเป็น
ไฟล์จำพวกข้อมูลหรือค่าดิบๆที่เอาไว้เรียกใช้งานอีกทีหนึ่ง

ในการสร้างไฟล์สำหรับ values ไม่จำเป็นต้องตั้งชื่อไฟล์ตายตัว
ตั้งชื่อยังไงก็ได้เพื่อการจำที่ง่าย และจะสร้างกี่ไฟล์ก็ได้
ซึ่งจะเห็นได้ว่าทุกครั้งที่สร้างโปรเจคขึ้นมาใหม่จะมีไฟล์บ้างแล้ว


โดยไฟล์ dimens.xml จะใช้เก็บค่าขนาดต่างๆที่ใช้กับ Layout
string.xml จะใช้เก็บค่า Text หรือ String ที่ใช้กับ Layout
styles.xml จะใช้เก็บสไตล์หรือธีมของแอพฯที่ใช้กับแอพฯนั้นๆ

ซึ่งสามไฟล์นี้จะสร้างขึ้นมาให้ทุกครั้งจะเข้าไปแก้ไขก็ได้
หรือจะสร้างไฟล์ขึ้นมาใหม่ก็ได้ถ้าข้อมูลที่จะสร้างมีเยอะ
โดยเจ้าของบล็อกแบ่งประเภทของ Resource ใน Values ดังนี้


String ข้อมูลประเภท String
Style ข้อมูลสำหรับกำหนดรูปแบบในการแสดง Layout
Bool ข้อมูลประเภท Boolean
Color ข้อมูลประเภท Integer ที่ใช้กำหนดค่าสี RGB
Dimension ข้อมูลที่ใช้กำหนดขนาดต่างๆใน Layout
ID ใช้กำหนดชื่อ ID ของ Widget ใน Layout
Integer ข้อมูลประเภท Integer
Integer Array ข้อมูลประเภท Integer Array
Typed Array ข้อมูลแบบ Resource ใดๆ ในรูป Array

* Typed Array ก็คือการจับพวก Resource อย่าง Color, String, Bool มาเป็น Array

โดยเจ้าของบล็อกจะขอตัด Style กับ ID ออกไปก่อน
เพราะ Style เอาไว้เป็นบทความแยกก็ยังได้ ส่วน ID ไม่ได้ใช้หรอก
เพราะโดยปกติมักจะกำหนดชื่อ ID ของ Widget ใน Layout อยู่แล้ว

ทีนี้เจ้าของบล็อกจะยกตัวอย่างการใช้งานให้ดูเลย
โดยจะสร้างไฟล์ xml ขึ้นมาใหม่ ชื่อ variable.xml



สำหรับโค๊ดใน variable.xml ก็ยกตัวอย่างการใช้งานดังนี้เลย


variable.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <!-- String Type --> <string name="welcome" >Welcome</string> <string name="device_disable" >Device is disable</string> <!-- Boolean Type --> <bool name="is_true" >true</bool> <bool name="is_false" >false</bool> <!-- Color Type --> <color name="color_red" >#FF0000</color> <color name="color_translucent_red" >#77FF0000</color> <!-- Dimension Type --> <dimen name="layout_width" >10dp</dimen> <dimen name="layout_height" >50px</dimen> <dimen name="text_size" >22.5sp</dimen> <dimen name="target_lenght" >5pt</dimen> <dimen name="object_tick" >8mm</dimen> <dimen name="screen_size" >6.5in</dimen> <!-- Integer Type --> <integer name="max">100</integer> <integer name="min">20</integer> <!-- Integer Array Type --> <integer-array name="choice"> <item>4</item> <item>6</item> <item>12</item> <item>16</item> </integer-array> <!-- Typed Type (Color) --> <array name="primary_color"> <item>#FF0000</item> <item>#00FF00</item> <item>#0000FF</item> </array> <!-- Typed Type (String) --> <array name="charator_name"> <item>Keith</item> <item>Tilton</item> <item>Rebecca</item> <item>Bartley</item> </array> </resources>

จะเห็นได้เลยว่า xml สำหรับ values นั้นง่ายมาก เลยไม่รู้จะอธิบายอะไรมาก
ดูแล้วน่าจะเข้าใจกันไม่ยากนัก (ถ้าไม่เข้าใจช่วยตั้งจิตพยายามดูละกันนะ)
โดยข้อมูลแต่ละตัวจะต้องมีการตั้งชื่อด้วยโดยใช้เป็นตัวพิมเล็ก (นิยมใช้)
จากนั้นภายในแท็กของประเภท Values ก็จะกำหนดค่าลงไป
สำหรับ Dimension เจ้าของบล็อกแสดงตัวอย่างทั้งหมดลงไปแล้ว
ว่า Dimension สามารถใช้หน่วยอะไรได้บ้าง

ทีนี้มาดูการเรียกใช้ค่าเหล่านี้ในโค๊ด Java กันบ้าง

Main.java
package app.akexorcist.resourcevalues; import android.os.Bundle; import android.app.Activity; import android.content.res.TypedArray; public class Main extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); String str1 = getResources().getString(R.string.welcome); String str2 = getResources().getString(R.string.device_disable); boolean bool1 = getResources().getBoolean(R.bool.is_true); boolean bool2 = getResources().getBoolean(R.bool.is_false); int color1 = getResources().getColor(R.color.color_red); int color2 = getResources().getColor(R.color.color_translucent_red); float dimen1 = getResources().getDimension(R.dimen.layout_width); float dimen2 = getResources().getDimension(R.dimen.layout_height); float dimen3 = getResources().getDimension(R.dimen.text_size); float dimen4 = getResources().getDimension(R.dimen.target_lenght); float dimen5 = getResources().getDimension(R.dimen.object_tick); float dimen6 = getResources().getDimension(R.dimen.screen_size); int integer1 = getResources().getInteger(R.integer.max); int integer2 = getResources().getInteger(R.integer.min); int[] arr_int1 = getResources().getIntArray(R.array.choice); TypedArray arr_color = getResources().obtainTypedArray(R.array.primary_color); int color3 = arr_color.getColor(0, 0xFF0000); int color4 = arr_color.getColor(0, 0x00FF00); int color5 = arr_color.getColor(0, 0x0000FF); TypedArray arr_name = getResources().obtainTypedArray(R.array.charator_name); String str3 = arr_name.getString(0); String str4 = arr_name.getString(1); String str5 = arr_name.getString(2); String str6 = arr_name.getString(3); } }

เจ้าของบล็อกตีกรอบแยกตัวอย่างการดึงค่าของแต่ละแบบมาใช้งานแล้ว
จะเห็นว่าในการกำหนดว่าจะดึงข้อมูลจาก Resource มาใช้ต้องใช้ getResources()
จากนั้นก็ระบุรูปแบบของ Resource แล้วระบุตัวที่ต้องการดึงมาใช้
โดยจะต้องสร้างตัวแปรประเภทนั้นๆมาเก็บค่าไว้ด้วย เพื่อนำไปใช้งาน
ส่วน Dimension จะเป็นแบบ Float ทั้งหมด (จึงกำหนดแบบมีทศนิยมได้)


ส่วน Resource แบบ Array ก็ระบุตัวที่ต้องการดึงเหมือนกับ Array ปกติเลย
แต่จะเห็นว่า Color Array มีความพิเศษกว่าชาวบ้านเค้าหน่อย
ในตัวอย่างนี้เจ้าของบล็อกให้ตัวแปร color3, color4 และ color5
ดึงค่ามาจาก primary_color ตัวแรกสุดเหมือนกันทั้งสามตัว ก็คือ 0
แต่จะเห็นว่ามีพารามิเตอร์ต่อท้ายอีกตัวนึงที่เจ้าของบล็อกกำหนดต่างกัน
ซึ่งก็คือกรณีที่ไม่สามารถดึงค่าจาก Array ได้ จะใช้คำนี้เป็น Default แทน
ดังนั้นสมมติว่าถ้า primary_color ไม่มีข้อมูลลำดับที่ 0 (จริงๆมันมี)
ตัวแปรทั้ง 3 ก็จะกำหนดค่าที่เตรียมไว้ให้แตกต่างกันไป

ขอพูดถึงคำสั่ง getResources() กันต่ออีกหน่อย จะเห็นว่าเรียกใช้ได้เลย
ทั้งนี้ก็เพราะว่าตัวคำสั่งเรียกใช้ในขอบเขตของ OnCreate นั่นเอง
ในขอบเขตธรรมดาของ Activity จะพิม gerResources() ได้เลย
รวมไปถึง If, For , While หรือ Siwtch-Case ด้วย (ต้องอยู่ใน Activity)
โดยจะสามารถเรียกใช้แบบตัวอย่างก็ได้หรือระบุชื่อ Activity ก็ได้ดังนี้
getResources() this.getResources() Main.this.getResources()

แต่สมมติว่าเจ้าของบล็อกเรียกใช้ใน onClickListener
จะไม่สามารถใช้ getResources() ธรรมดาๆได้เลย
เพราะว่าคำสั่งจะไปอยู่ในขอบเขตของ Listener ทันที
ดังนั้นการเรียกใช้ Resource ภายใต้ขอบเขต Listener จะใช้
Main.this.getResources()

จึงจะทำให้ดึง Resource ภายใต้ขอบเขตของ Listener ได้
* กรณีที่ชื่อ Activity ไม่ใช่ชื่อ Main ก็ให้แก้ไขให้ตรงด้วยล่ะ

ทีนี้เมื่ออธิบายการใช้งานในโค๊ด Java กันไปแล้ว
ทีนี้มาดูการเรียกใช้งานใน xml ของ Layout กันบ้าง
เพราะ Resource ก็สามารถนำมาใช้งานใน Layout ได้เช่นกัน

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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".Main" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:layout_margin="@dimen/layout_width" android:text="@string/welcome" android:textColor="@color/color_red" android:textSize="@dimen/text_size" /> </RelativeLayout>



เพียงเท่านี้เจ้าของบล็อกก็สามารถนำ Resource ใน Values
มากำหนด Properties ให้กับ Button ใน Layout ได้แล้ว

เห็นมั้ยล่ะ ไม่ยากเลย ขอแค่พยายามทำความเข้าใจดีๆ
ให้มองว่า Values ก็เปรียบเสมือนโฟลเดอร์ที่ให้กำหนดค่าต่างๆเก็บไว้
แล้วนำมาใช้งานใน Layout หรือโค๊ด Java ตามที่ต้องการ

แต่ทำไปเพื่ออะไรกันล่ะ?

สำหรับคำถามนี้ก็จะอยู่ในบทความนี้
[Android Design] การทำงานของโฟลเดอร์ใน Resource [res]

โฟลเดอร์ Resource ทุกโฟลเดอร์สามารถแยกตามคุณสมบัติเครื่องที่ใช้ได้
ดังนั้นจะช่วยให้ผู้ที่หลงเข้ามาอ่านกำหนดค่าแยกตามคุณสมบัติเครื่องได้
อย่างเช่นเครื่องขนาดเล็กใช้ Dimension ที่กำหนด Button ให้มีขนาดน้อย
แต่ในเครื่องขนาดใหญ่ก็กำหนด Dimension ที่กำหนด Button ให้มีขนาดใหญ่
หรือจะกำหนด String ที่ใช้แสดงข้อความบน Layout แยกตามภาษาของเครื่องได้
ซึ่งค่าจาก Resource เหล่านี้ก็จะขึ้นอยู่กับผู้ใช้แล้วล่ะว่าจะประยุกต์ใช้ยังไง


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


ขอให้ลองนำไปฝึกใช้ให้บ่อยๆ
เพราะจะมีประโยชน์ในการพัฒนามาก