Android Button และการรับ Event ด้วย OnClick
วันนี้พอดีมีน้องคนหนึ่งสอบถามมาเกี่ยวกับ Button ก็เลยทำเป็นบทความมาให้ซะเลย วันนี้จะมาพูดถึงเรื่อง Button ใน Android ครับ เป็นการใช้งาน Button
และการ implements OnClickListener
เพื่อให้ Button รับค่าต่างๆจากผู้ใช้งาน
จริงๆเรื่องนี้ไม่ได้เป็นเรื่องที่ใหม่ หรือยุ่งยากอะไรเลย เพียงแต่ถ้าเป็นมือใหม่ หรือเพิ่งหัดเขียน Android ก็อาจจะงงอยู่บ้างเล็กน้อย
Button คืออะไร?
Button นั้นเป็น View ตัวนึง ที่ผู้ใช้สามารถกดหรือคลิกได้ Button นั้นเป็นได้ทั้งตัวอักษร หรือว่าจะเป็นรูปภาพ หรือแม้แต่จะเป็น Button ที่มีทั้งภาพและตัวอักษรในปุ่มเดียวกันก็ได้
รูปจาก developer.android.com
วิธีการสร้างปุ่ม Button ด้วย XML
การสร้างปุ่ม Button โดยใช้ไฟล์ xml มีโครงสร้างดังนี้
การสร้าง Button เฉพาะตัวอักษร ด้วยคลาส Button
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is Button" />
การสร้าง Button ด้วยรูปภาพ โดยใช้คลาส ImageButton
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />
การสร้าง Button โดยใช้ทั้งตัวอักษรและรูปภาพ โดยเพิ่มแท็ก android:drawableLeft
ในคลาส Button
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/I'm Button"
android:drawableLeft="@drawable/ic_launcher" />
วิธีการสร้างปุ่ม Button ด้วย Java
หากเราต้องการสร้าง Button ในไฟล์ Java ก็สามารถทำได้เช่นกัน แต่ว่าแบบนี้ เป็นสร้างคลาสขึ้นมาเฉยๆนะครับ โดยปกติจำเป็นต้องมี Root Layout เช่น LinearLayout หรือ RelativeLayout แล้วถึงทำการ addView()
Button ที่เราสร้างถึงจะแสดงครับ ฉะนั้นก็จำเป็นจะต้องมีไฟล์ xml ที่ข้างในมี LinearLayout หรือ RelativeLayout
ส่วนวิธีการสร้างก็ตามนี้
// Button เฉพาะอักษร
Button button = new Button(this);
button.setLayoutParams(new ActionBar.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
button.setText("This is Button");
// Button ด้วยรูปภาพ
ImageButton imageButton = new ImageButton(this);
imageButton.setLayoutParams(new ActionBar.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
imageButton.setImageResource(R.drawable.ic_launcher);
// Button ทั้งรูปและตัวอักษร
Button button2 = new Button(this);
button2.setLayoutParams(new ActionBar.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
button2.setText("I'm Button");
button2.setCompoundDrawables(getResources().
getDrawable(R.drawable.ic_launcher), null, null, null);
Button และการ onClick
สำหรับวิธีการรับค่าจากผู้ใช้ เราจะใช้การรับ event แบบ onClick
ซึ่งวิธีการรับ event นั้นทำได้หลายแบบครับ แบบหลักๆเลย คือ
- การรับ event ด้วยการใช้ attribute ของ Botton ชื่อว่า
android:onClick
- ใช้
OnClickListener
(การใช้แบบนี้ก็แบ่งเป็นย่อยๆได้อีก แล้วแต่ความสะดวกหรือจุดประสงค์ของงานนั้นๆ)
ตัวอย่างการใช้ Button
มาลองดูตัวอย่างการใช้งาน Button กันครับ ทดลองสร้างโปรเจ็คใหม่เลย เมื่อได้โปรเจ็คใหม่แล้ว ในที่นี้ผมจะอ้างอิง 2 ไฟล์คือ
- MainActivity.java สำหรับเขียนโค๊ดต่างๆ
- activity_main.xml สำหรับแสดง Layout
จุดประสงค์หลักของตัวอย่างนี้คือ ต้องการโชว์ตัวอย่างการรับ Event จาก Button วิธีมี 4 วิธี ดังนั้น ผมจะสร้างปุ่ม Button ทั้งหมด 4 ปุ่ม และตั้งชื่อเป็น button1
ถึง button4
(จริงๆ อันนี้เป็นตัวอย่างการตั้งชื่อที่ไม่ดีนะครับ ชื่อควรตั้งให้สื่อความหมายนะครับ) เลเอาท์จะได้ดังนี้
โค๊ด activity_main.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:text="Button1"/>
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button2"
android:layout_below="@+id/button1"
android:layout_marginTop="32dp"/>
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button3"
android:layout_below="@+id/button2"
android:layout_marginTop="32dp"/>
<Button
android:id="@+id/button4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button4"
android:layout_below="@+id/button3"
android:layout_marginTop="32dp"/>
</RelativeLayout>
วิธีที่ 1: android:onClick
วิธีแรก ใช้การกำหนด attribute ฉะนั้น button1 ให้ทำการเพิ่ม android:onClick
เข้าไปด้วย จะได้เป็นแบบนี้
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:onClick="showMessage"
android:text="Button1"/>
showMessage
นั้นคือชื่อเมธอด ที่เราจะต้องไปกำหนดในคลาส ฉะนั้นเปิดคลาส MainActivity
แล้วก็ประกาศเมธอดขึ้นมาใหม่ โดยให้ชื่อเดียวกัน จะได้ดังนี้
public void showMessage(View view) {
Toast.makeText(this, "Button1 Clicked!", Toast.LENGTH_SHORT).show();
}
โดยเงื่อนไขการสร้างเมธอดแบบนี้คือ ต้องเป็น public
ต้อง return void และสุดท้ายต้องรับ parameter เป็น View (มันก็คือ View นั้นๆที่ถูกคลิ๊ก ซึ่ง Button มันก็คือ View ตัวหนึ่งใน Android นั่นเอง)
เมื่อสั่งรันโปรแกรม หากกดที่ปุ่ม Button1 ก็จะโชว์ข้อความว่า "Button1 Clicked!"
วิธีที่ 2: Implements View.OnClickListener
ตัวอย่างวิธีที่สอง จะใช้ Button2 วิธีนี้จะใช้การ implements View.OnClickListener
ฉะนั้นตรงส่วน xml ก็ไม่มีการเปลี่ยนแปลง จะแก้ไขเฉพาะในไฟล์ MainActivity
ที่คลาส MainActivity
ทำการ implements View.OnClickListener
จากนั้นก็ทำการ override เมธอด onClick
ดังนี้ (ViewOnClickListener อยู่ใน android.view.View
)
public class MainActivity extends ActionBarActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void showMessage(View view) {
Toast.makeText(this, "Button1 Clicked!", Toast.LENGTH_SHORT).show();
}
@Override
public void onClick(View v) {
Toast.makeText(this, "Button2 Clicked!", Toast.LENGTH_SHORT).show();
}
}
จากนั้นเราจำเป็นที่จะต้องทำการสร้าง Button โดยเชื่อมกับ button2 ใน xml จากนั้นก็เรียกเมธอด setOnClickListener
ดังนี้
Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(this);
setOnClickListener(this)
: this นั้นหมายถึง View.OnClickListener ที่ได้ implements มา ไม่ใช่ Activity หรือ Context นะครับ ฉะนั้นอย่าสับสน
วิธีที่ 3: Annonymous Inner Class
ตัวอย่างวิธีที่สาม จะใช้ Button3 จริงๆ มันก็คือการ setOnClickListener
แบบตัวอย่างที่ 2 แต่ต่างกันแค่ ไม่ได้ implements View.OnClickListener
แต่เป็นการส่งสร้าง inner class ส่งไปแทนที่ this ดังตัวอย่างนี้
Button button3 = (Button) findViewById(R.id.button3);
button3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(),
"Button3 Clicked!", Toast.LENGTH_SHORT).show();
}
});
จุดสังเกต จากที่เราต้อง implements ตรงคลาสเลย เราก็มาทำการสร้าง new Interface แทน เป็นแบบ Anonymous คือไม่มีชื่อ
วิธีที่ 4 : ตั้งชื่อ View.OnClickListener
ตัวอย่างวิธีที่สี่ จะใช้ Button4 ส่วนการทำงาน ก็เหมือนกับวิธีที่ 2 และ 3 เลย ต่างกันแค่วิธีส่งเจ้า View.OnClickListener
นั้นเอง สำหรับวิธีนี้ คือการตั้งชื่อให้มันเลย ฉะนั้น ก็ทำการสร้าง interface ชื่อว่า Button4OnClick
แบบนี้
View.OnClickListener Button4OnClick = new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(),
"Button4 Clicked!", Toast.LENGTH_SHORT).show();
}
};
ส่วนปุ่ม Button4 ก็ setOnClickListener
โดยใช้ Button4OnClick
แบบนี้
Button button4 = (Button) findViewById(R.id.button4);
button4.setOnClickListener(Button4OnClick);
ลองรันโปรแกรม ทดสอบดูแต่ละปุ่มครับ สำหรับโค๊ดทั้งหมด ดูได้ที่ gist นี้ครับ
- Authors
- Name
- Chai Phonbopit
- Website
- @Phonbopit