ประโยชน์ของการใช้ Fragments ใน Android แทนที่จะเป็น Views คืออะไร


102

เมื่อมีการพัฒนาสำหรับAndroidคุณสามารถตั้งค่าเป้าหมายของคุณ (หรืออย่างน้อย) SDK 4 (API 1.6) และเพิ่มแพคเกจเข้ากันได้ของหุ่นยนต์ (v4) Fragmentsเพื่อเพิ่มการสนับสนุนสำหรับ เมื่อวานนี้ฉันทำสิ่งนี้และนำFragmentsไปใช้เพื่อแสดงภาพข้อมูลจากคลาสที่กำหนดเองได้สำเร็จ

คำถามของฉันคือสิ่งนี้มีประโยชน์อย่างไรในการใช้Fragmentsเมื่อเทียบกับเพียงแค่รับ View จากออบเจ็กต์ที่กำหนดเองและยังรองรับ API 1.5

ตัวอย่างเช่นฉันมีคลาส Foo.java:

public class Foo extends Fragment {

    /** Title of the Foo object*/
    private String title;
    /** A description of Foo */
    private String message;

    /** Create a new Foo
     * @param title
     * @param message */
    public Foo(String title, String message) {
        this.title = title;
        this.message = message;
    }//Foo

    /** Retrieves the View to display (supports API 1.5. To use,
     * remove 'extends Fragment' from the class statement, along with
     * the method {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}) 
     * @param context Used for retrieving the inflater */
    public View getView(Context context) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View v = inflater.inflate(R.layout.foo, null);
        TextView t = (TextView) v.findViewById(R.id.title);
        t.setText(this.title);
        TextView m = (TextView) v.findViewById(R.id.message);
        m.setText(this.message);
        return v;
    }//getView 

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if (container == null) {
            return null;
        }
        View v = inflater.inflate(R.layout.foo, null);
        TextView t = (TextView) v.findViewById(R.id.title);
        t.setText(this.title);
        TextView m = (TextView) v.findViewById(R.id.message);
        m.setText(this.message);
        return v;
    }//onCreateView

}//Foo

ทั้งสองวิธีนั้นง่ายมากในการสร้างและใช้งานกับกิจกรรมที่กล่าวว่ามีสิ่งที่List<Foo>ต้องแสดง (ตัวอย่างเช่นการเพิ่มแต่ละรายการลงใน a โดยใช้โปรแกรมScrollView) ดังนั้นFragmentsทั้งหมดนี้มีประโยชน์จริงๆหรือเป็นเพียงการทำให้เข้าใจง่ายมากเกินไปของ การดูเช่นผ่านรหัสด้านบน?


2
Fragments ไม่จำเป็นต้องมี UI แต่สามารถใช้ซ้ำได้ การดูจะซ้ำซ้อนในกรณีนั้น
Philipp Reichart

ฉันได้ตอบคำถามนี้แล้ว โปรดดูstackoverflow.com/a/14912608/909956 T; dr - ในบางครั้งแฟรกเมนต์ช่วยให้คุณสามารถสร้างคอมโพเนนต์ที่ใช้ซ้ำได้มากกว่าการใช้มุมมองแบบกำหนดเอง ดูลิงค์ว่าทำไม
numan salati

คำตอบ:


172

เหตุผลหลักในการใช้ Fragments คือคุณสมบัติแบ็คสแต็คและวงจรชีวิต มิฉะนั้นมุมมองแบบกำหนดเองจะมีน้ำหนักเบาและใช้งานง่ายกว่า

ตอนแรกฉันพยายามสร้างแอปโทรศัพท์ / แท็บเล็ตโดยใช้มุมมองที่กำหนดเอง ดูเหมือนว่าทุกอย่างจะใช้งานได้บนโทรศัพท์และแท็บเล็ตแม้กระทั่งการเปลี่ยนจากแผงเดียวเป็นแผงแยก ที่ฉันประสบปัญหาคือปุ่มย้อนกลับและวงจรชีวิต เนื่องจากฉันเพิ่งอัปเดตมุมมองด้วยตนเอง ... ไม่มีอะไรติดตามประวัติของมุมมองและสถานะของพวกเขา ดังนั้นปุ่มย้อนกลับจึงไม่ทำงานตามที่คาดไว้และเป็นการยากที่จะสร้างใหม่แม้กระทั่งสถานะล่าสุดในระหว่างเหตุการณ์วงจรชีวิตเช่นเมื่อหมุนแอป ในการแก้ไขปัญหานั้นฉันต้องรวมมุมมองที่กำหนดเองของฉันเป็นส่วนย่อยและใช้ FragmentManager เพื่อให้สถานะก่อนหน้านี้ได้รับการบันทึกและสร้างขึ้นใหม่

ฉันรู้หลังจากตอบว่าฉันโพสต์คำถามที่คล้ายกันเมื่อปีก่อน: https://stackoverflow.com/a/11126397/618881


14
ตอบได้ดีมาก. ฉันแค่อยากจะเพิ่มส่วนที่สามารถซ้อนกันได้ตั้งแต่ 4.2 หรือสนับสนุนไลบรารี rev 11
kar

2
ขอบคุณ @Karlo สำหรับการอัปเดต ฉันไม่คิดว่ามันจะเป็นไปได้ในแนวความคิด แต่พวกเขาแก้ไขโดยใช้ FragmentManager ส่วนตัวผ่าน getChildFragmentManager () โอ้มันคือ API 17 ไม่ใช่ 11 และพร้อมใช้งานผ่านไลบรารีการสนับสนุน
Henry

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

2
ต้องการ +1 คำตอบนี้ แต่การทำเช่นนั้นจะทำลายคะแนนปัจจุบัน นอกจากนี้ 70 ไม่ใช่ตัวเลขที่ฉันชอบ
Behnam

1
สำหรับปีที่แล้วฉันยังคิดว่า Fragments ไม่ได้มีคุณสมบัติพิเศษใด ๆ แต่ฉันพบว่าหลังจากคลิกกลับไปที่กิจกรรมฉันสูญเสียภาพทั้งหมดที่ดาวน์โหลดในนั้นดังนั้นต้องเพิ่มการใช้แคชตอนนี้ฉันกำลังคิดว่าจะใช้ เศษมันอาจจะง่ายมาก
Shirish Herwade

27

ฉันคิดว่า Fragments มีประโยชน์ในสองสถานการณ์: หากคุณแบ่งมุมมองในอุปกรณ์ / ทิศทางบางอย่างและแสดงเป็นสองกิจกรรมและแสดงเนื้อหาทั้งหมดในที่เดียวบนอุปกรณ์อื่น นั่นจะเป็นกรณีการใช้งานหากคุณใช้แท็บเล็ตหรือแม้กระทั่งในโหมดแนวนอนบนโทรศัพท์เช่นคุณแสดงรายการสิ่งของและรายละเอียดบนหน้าจอเดียว บนโทรศัพท์หรือในโหมดแนวตั้งคุณจะแสดงเพียงส่วนเดียว

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

ฉันไม่เห็นเหตุผลใด ๆ ในการใช้ Fragments สำหรับทุกๆ View และฉันเดาว่ามันน่าจะเป็นค่าใช้จ่าย ฉันใช้มันในกรณีการใช้งานครั้งแรกเท่านั้นและฉันจะบอกว่านี่เป็นการทำให้เข้าใจง่าย


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

3

Android เปิดตัวแฟรกเมนต์ใน Android 3.0 (API ระดับ 11) เพื่อรองรับการออกแบบ UI แบบไดนามิกและยืดหยุ่นมากขึ้นบนหน้าจอขนาดใหญ่เช่นแท็บเล็ต เนื่องจากหน้าจอของแท็บเล็ตมีขนาดใหญ่กว่าของโทรศัพท์มือถือมากจึงมีพื้นที่ในการรวมและเปลี่ยนองค์ประกอบ UI มากขึ้น แฟรกเมนต์อนุญาตการออกแบบดังกล่าวโดยไม่จำเป็นให้คุณจัดการการเปลี่ยนแปลงที่ซับซ้อนของลำดับชั้นมุมมอง ด้วยการแบ่งเค้าโครงของกิจกรรมออกเป็นส่วนย่อยคุณจะสามารถแก้ไขลักษณะที่ปรากฏของกิจกรรมที่รันไทม์และรักษาการเปลี่ยนแปลงเหล่านั้นไว้ในแบ็กสแต็กที่จัดการโดยกิจกรรม

ที่นี่คุณสามารถอ่านรายละเอียดเพิ่มเติม


ฉันได้อ่านเอกสารทั้งหมดแล้ว แต่ฉันกำลังมองหาสิ่งที่อธิบายประโยชน์ของพวกเขาได้ดีกว่าเช่นแท็บเล็ตหรือแบ็คสแต็ค
ฟิล

3
  1. หน้าจอแยกกิจกรรมสถานการณ์ - เรามีหนึ่งเลย์เอาต์และหนึ่งกิจกรรมที่จัดการส่วนหน้าจอซ้ายขวา
  2. Scenario FragmentActivity เรามีหนึ่งเลย์เอาต์สำหรับหน้าจอหลักหนึ่งสำหรับซ้ายหนึ่งสำหรับขวา

สถานการณ์ที่ดีถ้าคุณมีแอปพลิเคชันง่ายๆ

สถานการณ์ที่สองเป็นสิ่งที่ดีหากคุณต้องการมีหลายชิ้นส่วนและหลาย FragmentActivities และคุณสามารถรวมแต่ละส่วนได้ นอกจากนี้คุณสามารถสร้างปฏิสัมพันธ์ระหว่างชิ้นส่วน

ฉันมี Fragmentactivity แบบแยกหน้าจอฉันสามารถเรียกมันด้วย 'Intent Extras' และบอกกับ fragmentActivity ว่าจะโหลดแฟรกเมนต์ไหน Fragment เป็นสิ่งที่ดีเนื่องจากไม่ได้อยู่ในรายการเพื่อให้คุณสามารถสร้างชิ้นส่วนที่ใช้ซ้ำได้และ FragmentActvity

แต่ทำให้โครงการของคุณมีขนาดใหญ่ขึ้น แต่ถ้าคุณสร้างโครงการขนาดใหญ่คุณสามารถประหยัดได้มากมาย เนื่องจากคุณสามารถใช้ Fragment เดียวกันหรือกิจกรรม Fragment เดียวกันได้

และฉันคิดว่าชิ้นส่วนนี้มาช้าไปหน่อยดังนั้นคุณต้องพยายามคิดในรูปแบบใหม่ อาจจะลองแปลงกิจกรรมของคุณเป็น FragmentActivity ต่อมาลองค้นหาโค้ดที่ใช้ซ้ำได้และสร้าง Fragment จากมัน

มันมีประโยชน์ แต่ฉันไม่รู้ว่าตอนนี้เป็นอย่างไร แต่ฉันมีความคิดบางอย่าง

นี่เป็นปัญหาเสมอ ทีมแอนดรอยด์สร้างความคิดและไม่มีใครรู้ว่าอะไรดี เพราะเราแทบจะไม่ได้เรียนรู้เหมือนเดิมและสิ่งใหม่ ๆ ก็มาถึงที่นี่

ในความคิดของฉันมันดี แต่ไม่ใช่เหตุผลที่ google บอกเรา


0

เพิ่มหนึ่งกรณีเมื่อใช้ Fragment หรือ Activity บน CustomView:

เมื่อคุณใช้ CursorLoader เพื่อสังเกตมุมมอง ListView หรือ TextView บางอย่างและต้องการอัปเดตค่าการแสดงผลเมื่อใดก็ตามที่ข้อมูลของ ContentProvider ของคุณอัปเดตที่ส่วนหลัง (กรณีทั่วไปส่วนใหญ่คุณมีบริการที่อัปเดตฐานข้อมูลในเครื่องของคุณโดยการสำรวจข้อมูลจากฐานข้อมูลระยะไกล / คลาวด์เป็นระยะ )


-2

สิ่งสำคัญอย่างหนึ่งที่ความคิดเห็นข้างต้นไม่ได้กล่าวถึงคือชิ้นส่วนยังคงอยู่ในหน่วยความจำแม้ว่า Android จะฆ่ากิจกรรมและรีสตาร์ทเมื่อคุณทำบางอย่างเช่นเปลี่ยนทิศทางของอุปกรณ์ของคุณ สิ่งนี้ทำด้วยเหตุผลด้านประสิทธิภาพ แต่ยังสามารถนำไปสู่ผลลัพธ์ที่ไม่คาดคิดหากคุณคาดหวังว่าชิ้นส่วนจะถูกทำลายเพียงเพื่อที่จะพบว่าพวกมันถูกสร้างขึ้นใหม่โดยไม่มีที่ไหนเลย

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