Android onClick ใน XML เทียบกับ OnClickListener


87

ฉันตระหนักดีว่ามีการถามคำถามที่ใช้คำคล้าย ๆ กันมาก่อน แต่นี่ต่างออกไป ฉันค่อนข้างใหม่ในการพัฒนาแอพ Android และฉันมีคำถามสามข้อเกี่ยวกับความแตกต่างระหว่างandroid:onclick=""แอตทริบิวต์ XML และsetOnClickListenerวิธีการ

  1. อะไรคือความแตกต่างระหว่างทั้งสอง? พบความแตกต่างระหว่างการใช้งานทั้งสองในเวลาคอมไพล์หรือรันไทม์หรือทั้งสองอย่าง

  2. กรณีการใช้งานใดบ้างที่เอื้อต่อการนำไปใช้งาน

  3. การใช้แฟรกเมนต์ใน Android ทำให้ตัวเลือกการใช้งานแตกต่างกันอย่างไร


2
สำหรับ # 2: คุณควรระมัดระวังในการใช้ xml onclickเนื่องจากคุณต้องแน่ใจว่าทุกคลาสใช้วิธีนั้น นี่เป็นการสมมติว่าคุณใช้เค้าโครงมากกว่าหนึ่งครั้ง อย่างไรก็ตามหากคุณต้องมีอินเทอร์เฟซ java เพื่อให้แน่ใจว่าเมธอดอยู่ในคลาสทั้งหมดที่ใช้งานได้คุณก็ไม่ต้องกังวล
Uxonith

การไม่มีอินเทอร์เฟซ java ตามที่คุณอธิบายไว้นั้นค่อนข้างเหมือนกับการขยายหรือการใช้ OnClickListener?
KG6ZVP

ฉันเคยพิจารณาเรื่องนี้มาก่อนแล้วและฉันคิดว่ามันมีมากกว่าความชอบเล็กน้อย แต่ฉันขอโทษที่ฉันไม่สามารถพูดอะไรได้มากกว่านี้เพราะมันผ่านมาสักพักแล้ว ฉันชอบandroid:onclickเวลาที่มันสะดวก แต่ฉันรู้ว่าบางครั้งมันก็ทำให้เกิดปัญหาขึ้นและฉันก็จำไม่ได้เหมือนกัน :)
Uxonith

xml onClick ไม่ทำงานกับองค์ประกอบโครงร่างที่ซ้อนกันซึ่งสูงเกินจริงแบบไดนามิกในระดับ API 19
Amit Kaushik

1
ฉันไม่ค่อยเห็นรหัสจากคนอื่นที่ใช้ android: onClick และเป็นสิ่งที่สับสนที่สุดเมื่อคุณดูรหัสของใครบางคน เนื่องจากไม่มีความเป็นไปได้ทั้งหมดของ setOnClickListener เกือบทุกคนใช้ setOnClickListener เท่านั้นในความคิดของฉัน
Christian

คำตอบ:


124

ความแตกต่างระหว่าง OnClickListener กับ OnClick:

  • OnClickListener เป็นอินเทอร์เฟซที่คุณต้องใช้และสามารถตั้งค่าเป็นมุมมองในโค้ดจาวา
  • OnClickListener คือสิ่งที่รอให้ใครบางคนคลิกจริงๆโดย onclick จะกำหนดว่าจะเกิดอะไรขึ้นเมื่อมีคนคลิก
  • เมื่อเร็ว ๆ นี้ Android ได้เพิ่มแอตทริบิวต์ xml ในมุมมองที่เรียกว่า android: onclick ซึ่งสามารถใช้เพื่อจัดการการคลิกโดยตรงในกิจกรรมของมุมมองโดยไม่จำเป็นต้องใช้อินเทอร์เฟซใด ๆ
  • คุณสามารถสลับการใช้งานตัวฟังหนึ่งกับอีกคนหนึ่งได้อย่างง่ายดายหากคุณต้องการ
  • OnClickListener ช่วยให้คุณสามารถแยกการกระทำ / พฤติกรรมของเหตุการณ์การคลิกออกจากมุมมองที่ทริกเกอร์เหตุการณ์ แม้ว่าในกรณีง่ายๆนี่ไม่ใช่เรื่องใหญ่สำหรับการจัดการเหตุการณ์ที่ซับซ้อน แต่อาจหมายถึงความสามารถในการอ่านและบำรุงรักษาโค้ดได้ดีขึ้น
  • เนื่องจาก OnClickListener เป็นอินเทอร์เฟซคลาสที่ใช้งานจึงมีความยืดหยุ่นในการกำหนดตัวแปรอินสแตนซ์และวิธีการที่ต้องการเพื่อจัดการกับเหตุการณ์ อีกครั้งนี่ไม่ใช่เรื่องใหญ่ในกรณีธรรมดา ๆ แต่สำหรับกรณีที่ซับซ้อนเราไม่ต้องการผสมตัวแปร / วิธีการที่เกี่ยวข้องกับการจัดการเหตุการณ์ด้วยรหัสของ View ที่เรียกเหตุการณ์
  • onClick with function binding ใน XML Layout เป็นการผูกระหว่าง onClick กับฟังก์ชันที่จะเรียกใช้ ฟังก์ชันต้องมีอาร์กิวเมนต์เดียว (มุมมอง) เพื่อให้ onClick ทำงานได้

ทั้งสองทำงานในลักษณะเดียวกันเพียงแค่ตั้งค่าผ่านรหัสจาวาและอีกอันผ่านรหัส xml

การติดตั้งโค้ด setOnClickListener:

Button btn = (Button) findViewById(R.id.mybutton);

btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    myFancyMethod(v);
    }
});

// some more code

public void myFancyMethod(View v) {
    // does something very interesting
}

การใช้งาน XML:

<?xml version="1.0" encoding="utf-8"?>
<!-- layout elements -->
<Button android:id="@+id/mybutton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Click me!"
    android:onClick="myFancyMethod" />
<!-- even more layout elements -->

ประสิทธิภาพ:

ทั้งสองเหมือนกันในด้านประสิทธิภาพ Xml ถูกแยกวิเคราะห์ล่วงหน้าเป็นรหัสไบนารีขณะคอมไพล์ ดังนั้นจึงไม่มีการ over-head ใน Xml

ข้อ จำกัด :

android: onClick ใช้สำหรับ API ระดับ 4 เป็นต้นไปดังนั้นหากคุณกำหนดเป้าหมาย <1.6 คุณจะไม่สามารถใช้งานได้


`Xml ถูกแยกวิเคราะห์ล่วงหน้าเป็นรหัสไบนารีในขณะคอมไพล์ 'คำสั่งนี้หมายความว่าอย่างไร? เนื่องจากฉันได้เห็น dexcode ของ apk ซึ่งมี android: onClick ในไฟล์ manifest แต่ฉันไม่พบรหัสใด ๆ ที่ตั้งค่าผู้ฟัง
VicX

คำอธิบายที่ยอดเยี่ยม +1
Zia Ur Rahman

1
ที่จริงมีค่าใช้จ่ายบางอย่างในXML เมื่อมีการคลิกปุ่มสำหรับครั้งแรกที่สะท้อนให้เห็นถึงถูกนำมาใช้ในการกำหนดวิธีการที่ควรจะเรียก อย่างไรก็ตามนี่อาจเป็นเรื่องเล็กน้อยสำหรับกรณีการใช้งานส่วนใหญ่ (และการเพิ่มประสิทธิภาพก่อนกำหนดเป็นรากฐานของความชั่วร้ายทั้งหมด)
Yoel

22

ฉันตกใจที่ไม่มีใครพูดถึงเรื่องนี้ แต่โปรดระวังแม้ว่าandroid:onClickXML ดูเหมือนจะเป็นวิธีที่สะดวกในการจัดการกับการคลิก แต่การsetOnClickListenerใช้งานจะทำอะไรเพิ่มเติมนอกเหนือจากการเพิ่มไฟล์onClickListener. อันที่จริงมันทำให้คุณสมบัติมุมมองclickableเป็นจริง

แม้ว่าอาจไม่มีปัญหาในการใช้งาน Android ส่วนใหญ่ตามตัวสร้างโทรศัพท์ปุ่มมักจะเป็นค่าเริ่มต้นที่คลิกได้ = จริง แต่ตัวสร้างอื่น ๆ ในโทรศัพท์บางรุ่นอาจมีค่าเริ่มต้น clickable = false ในมุมมองที่ไม่ใช่ปุ่ม

ดังนั้นการตั้งค่า XML จึงไม่เพียงพอคุณต้องคิดตลอดเวลาเพื่อเพิ่ม android:clickable="true"ปุ่ม non และหากคุณมีอุปกรณ์ที่ค่าเริ่มต้นคือคลิกได้ = true และคุณลืมแม้แต่ครั้งเดียวที่จะใส่แอตทริบิวต์ XML นี้คุณจะไม่สังเกตเห็น ปัญหาที่รันไทม์ แต่จะได้รับคำติชมจากตลาดเมื่อถึงมือลูกค้าของคุณ!

นอกจากนี้เราไม่สามารถมั่นใจได้ว่า proguard จะทำให้สับสนและเปลี่ยนชื่อแอตทริบิวต์ XML และ class method ได้อย่างไรดังนั้นจึงไม่ปลอดภัย 100% ที่จะไม่มีจุดบกพร่องในวันหนึ่ง

ดังนั้นหากคุณไม่ต้องการมีปัญหาและไม่เคยคิดถึงเรื่องนี้ก็ควรใช้setOnClickListenerหรือไลบรารีเช่น ButterKnife พร้อมคำอธิบายประกอบ@OnClick(R.id.button)


1
คุณมีประสบการณ์ (หรือเคยเห็นที่ไหนสักแห่ง) ที่เกิดข้อผิดพลาดเนื่องจากความสับสนเมื่อใช้งานandroid:onClickหรือไม่?
อัก

ขอบคุณครับ! คำตอบของคุณมีประโยชน์มาก!
Yi Shen

13

เพียงแค่:

หากคุณมีandroid:onClick = "someMethod" ใน xmlจะมองหาpublic void someMethodในคลาสกิจกรรมของคุณ OnClickListenerเรียกว่าขวาจากกิจกรรมของคุณViewและจะมีการเชื่อมโยงกับบางโดยเฉพาะอย่างยิ่ง ตัวอย่างเช่นsomeButton.setOnClickListenerและในโค้ดด้านล่างจะบอกว่าต้องทำอะไรเมื่อไหร่someButtonกด

หวังว่าจะช่วยได้ :)


4

ดังที่กล่าวไว้ก่อนหน้านี้: ทั้งคู่เป็นวิธีเพิ่มตรรกะเพื่อตอบสนองต่อเหตุการณ์ในกรณีนี้คือเหตุการณ์ "คลิก"

ฉันจะแยกระหว่างตรรกะและการนำเสนอเช่นเดียวกับที่เราทำในโลก HTML / JavaScript: ปล่อย XML สำหรับการนำเสนอและเพิ่มผู้ฟังเหตุการณ์โดยใช้รหัส


1
เห็นด้วยเว้นแต่ว่าจะเป็นแอปพลิเคชันขนาดเล็กที่มีลักษณะการทำงานที่เรียบง่ายโค้ดการดำเนินการทั้งหมดของคุณควรแยกออกจากกันและมีการจัดระเบียบที่ดีควรใช้วิธีการแยกต่างหาก
OzzyTheGiant

0

หากคุณมีปุ่มหลายปุ่มโดยใช้เพียงวิธีเดียวฉันขอแนะนำให้ทำใน java แต่ถ้าคุณมีปุ่มที่มีวิธีการเฉพาะ onClick ใน XML จะดีกว่า


0

สะดวกกว่าที่จะใช้แอตทริบิวต์ android: onClick ทุกครั้งเว้นแต่คุณจะมีเหตุผลที่ดีที่จะไม่ทำเช่นหากคุณสร้างอินสแตนซ์ปุ่มขณะรันไทม์หรือคุณจำเป็นต้องประกาศพฤติกรรมการคลิกในคลาสย่อยของ Fragment


3
ฉันไม่ค่อยเห็นรหัสจากคนอื่นที่ใช้ android: onClick และเป็นสิ่งที่สับสนที่สุดเมื่อคุณดูรหัสของใครบางคน เนื่องจากไม่มีความเป็นไปได้ทั้งหมดของ setOnClickListener เกือบทุกคนใช้ setOnClickListener เท่านั้นในความคิดของฉัน
Christian

0

มีสาเหตุสองสามประการที่คุณอาจต้องการตั้งค่าOnClickListenerไฟล์. อย่างแรกคือหากคุณต้องการเปลี่ยนลักษณะการทำงานของปุ่มขณะที่แอปของคุณกำลังทำงานอยู่ คุณสามารถชี้ปุ่มของคุณไปที่วิธีอื่นโดยสิ้นเชิงหรือเพียงแค่ปิดใช้งานปุ่มโดยการตั้งค่าไฟล์OnClickListenerที่ไม่ทำอะไรเลย

เมื่อคุณกำหนด Listener โดยใช้onClickแอ็ตทริบิวต์มุมมองจะค้นหาเมธอดที่มีชื่อนั้นในกิจกรรมโฮสต์เท่านั้น การตั้งค่าโปรแกรมด้วยโปรแกรมOnClickListenerช่วยให้คุณสามารถควบคุมการทำงานของปุ่มจากที่อื่นที่ไม่ใช่กิจกรรมของโฮสต์ได้ สิ่งนี้จะมีความเกี่ยวข้องมากเมื่อเราใช้Fragmentsซึ่งโดยพื้นฐานแล้วเป็นกิจกรรมขนาดเล็กทำให้คุณสามารถสร้างคอลเลกชันมุมมองที่ใช้ซ้ำได้ด้วยวงจรชีวิตของพวกเขาเองซึ่งสามารถนำมาประกอบเป็นกิจกรรมได้ Fragments จำเป็นต้องใช้OnClickListenersเพื่อควบคุมปุ่มเสมอเนื่องจากไม่ใช่ Activities และจะไม่ถูกค้นหาสำหรับ Listener ที่กำหนดไว้ใน onClick


-2

ฉันคิดว่าความแตกต่างที่สำคัญระหว่างพวกเขาคือ:

OnClick: เมื่อคุณคลิกที่ปุ่มด้วยนิ้วของคุณ

OnClickListner: อาจเป็นทางเลือกที่กว้างกว่าที่จะใช้ในรหัสต่างๆ

ตัวอย่างเช่นเมื่อคุณพิมพ์ url "ymail.com" yahoo จะค้นหาชื่อผู้ใช้และรหัสผ่านของคุณจากเบราว์เซอร์และเปิดใช้งานปุ่มสถานะการคลิกเพื่อเปิดเมลของคุณ การดำเนินการนี้ควรใช้เฉพาะใน onClickListener

นี่คือความคิดของฉัน!


สิ่งนี้น่าสนใจ แต่มีอะไรมากกว่านั้น ของคุณควรเป็นความคิดเห็นมากกว่า
Dakatine
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.