ปัญหาหนึ่งของ Nested Fragment (Fragment ที่ถูกแปะบน Fragment อีกทีนึง) คือเราสามารถสั่ง startActivityForResult(...)
ได้แต่คำสั่ง onActivityResult(...)
จะไม่ถูกเรียกเนื่องจากสาเหตุเรื่องของการออกแบบ Fragment หากสนใจสามารถเข้าไปอ่านสาเหตุเต็มๆได้จาก วิธีการทำให้ onActivityResult ของ Nested Fragment ใช้งานได้ในทุกกรณี
ก่อนหน้านี้หากต้องใช้งาน onActivityResult ใน Nested Fragment เราก็ต้องหาวิธีแก้ไขกันไป แต่ล่าสุดบน Android Support Library rev 23.2 ก็มีการแก้ไขครั้งใหญ่ของปัญหาตรงนี้เรียบร้อย เมื่อตอนนี้เราสามารถใช้งาน startActivityForResult
และ onActivityResult
ได้ทันทีโดยไม่ต้องมาทำอะไรให้วุ่นวายอีกต่อไป!
การทดสอบ
ทดสอบด้วยการสร้าง Fragment ขึ้นมาสองตัว MainFragment
และ SecondFragment
โดยเอา MainFragment แปะบน Activity และเอา SecondFragment แปะลงบน MainFragment อีกทีหนึ่ง เป็นไปตามรูปด้านล่าง
โดยใน SecondFragment มีการใส่ปุ่มเข้าไปปุ่มนึงคือ btnGo
และโค้ดที่ใส่ใน SecondFragment.java
เป็นไปตามนี้
// SecondFragment.java
// Calling to SecondActivity
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
...
btnGo = (Button) rootView.findViewById(R.id.btnGo);
btnGo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getContext(), SecondActivity.class);
startActivityForResult(intent, 12345);
}
});
}
// Get Result Back
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d("onActivityResult", "requestCode = " + requestCode);
}
เมื่อมีการกดปุ่ม btnGo จะเห็นว่ามีการเรียกไปยัง SecondActivity
ที่มีการ setResult ตามโค้ดด้านล่าง
// SecondActivity.java
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Intent intent = new Intent();
setResult(RESULT_OK, intent);
finish();
}
}
ดังนั้นทันทีที SecondActivity ถูกเรียกขึ้นมามันก็จะปิดตัวเองไปพร้อมส่งผลลัพธ์ (Result) กลับทันที
ความคาดหวังคือถ้ามีการกดปุ่ม btnGo คำสั่ง onActivityResult
ของ SecondFragment
จะต้องถูกเรียก และต้องมี Log ขึ้นมา
ผลการทำงานเป็นแบบนี้
Android Support Library revision 23.1.1
com.inthecheesefactory.lab.nestedfragment I/OpenGLRenderer: Initialized EGL, version 1.4
com.inthecheesefactory.lab.nestedfragment W/EGL_emulation: eglSurfaceAttrib not implemented
com.inthecheesefactory.lab.nestedfragment W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xaf853600, error=EGL_SUCCESS
Android Support Library revision 23.2.1
com.inthecheesefactory.lab.nestedfragment I/OpenGLRenderer: Initialized EGL, version 1.4
com.inthecheesefactory.lab.nestedfragment W/EGL_emulation: eglSurfaceAttrib not implemented
com.inthecheesefactory.lab.nestedfragment W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xaf853600, error=EGL_SUCCESS
com.inthecheesefactory.lab.nestedfragment D/onActivityResult: requestCode = 12345
ก็จะเห็นว่า บน Android Support Library rev 23.1 คำสั่ง onActivityResult บน SecondFragment จะไม่ถูกเรียก ในขณะที่ใน rev 23.2 คำสั่ง onActivityResult ถูกเรียกเรียบร้อยสวยงาม
ถือเป็นการเปลี่ยนแปลงเล็กๆที่ยิ่งใหญ่ จากนี้ไม่ต้องใช้ Workaround อะไรอีกต่อไป สามารถสลับมาใช้ Android Support Library rev 23.2 เป็นต้นไปแทนได้ทันทีครับ โค้ดจะคลีนขึ้นไปอีกขั้น =)
ผู้เขียน: nuuneoi (Android GDE, CTO & CEO at The Cheese Factory) นักพัฒนาแบบ Full-Stack ที่มีประสบการณ์ในการพัฒนาแอพฯแอนดรอยด์มากว่า 6 ปีและอยู่ในวงการพัฒนาแอพฯมือถือมากว่า 12 ปี มีความสนใจทางด้าน Infrastucture, Service Side, Design, UI&UX, Hardware, Optimization, Cooking, Photographing, Blogging, Training, Public Speaking และรักที่จะแชร์เรื่องราวให้ผู้คนได้อ่านได้ฟังกันผ่าน Blog
|