มีกิจกรรม vs เศษกี่ชิ้น


185

บทนำ:

รูปแบบ "การสอน Fragments" พื้นฐานมีลักษณะดังนี้:

  1. บนแท็บเล็ตมีรายการทางด้านซ้ายรายละเอียดด้านขวา
  2. ทั้งสอง และอาศัยทั้งในแบบเดียวกันFragmentsActivity
  3. บนโทรศัพท์มือถือที่มีรายชื่อในหนึ่งFragmentActivity
  4. เปิดตัวใหม่มีรายละเอียดActivityFragment

(เช่นAndroid 3.0 Fragments API โดย Dianne Hackbornและคู่มือFragments API )

Fragmentsในอุปกรณ์ทั้งสองทำงานอยู่ใน (แบบง่าย)

บนแท็บเล็ตแอปทั้งหมดเป็น1Activityในโทรศัพท์มีจำนวนมากActivities


คำถาม:

  • มีเหตุผลที่จะแยกแอพโทรศัพท์ออกเป็นจำนวนมากActivitiesหรือไม่?

หนึ่งปัญหาด้วยวิธีนี้คือการที่คุณซ้ำกันจำนวนมากของลอจิกในแท็บเล็ตหลักและในโทรศัพท์ที่แยกต่างหากActivityActivities

  • จะง่ายกว่าไหมถ้าจะคงรูปแบบ 1 กิจกรรมไว้ในทั้งสองกรณีโดยใช้ตรรกะเดียวกันในการสลับFragmentsเข้าและออก (ใช้รูปแบบที่แตกต่างกัน)

วิธีนี้ตรรกะส่วนใหญ่อยู่ในFragmentsตัวของมันเองและมีการActivityทำสำเนารหัสเพียงครั้งเดียวน้อยลง

สิ่งที่ฉันได้อ่านเกี่ยวกับสิ่งActionBarSherlockที่ดูเหมือนว่าจะทำงานได้ดีที่สุดด้วยFragmentsแทนที่จะเป็นActivities(แต่ฉันยังไม่ได้ทำงานด้วย)

แบบฝึกหัดเกินความจริงหรือฉันพลาดสิ่งสำคัญในแนวทางนี้หรือไม่?


เราได้ลองทั้งสองวิธีในสำนักงานเรียบร้อยแล้ว - แต่ฉันกำลังจะเริ่มโครงการที่ใหญ่กว่าและต้องการทำสิ่งต่าง ๆ ให้ง่ายที่สุดสำหรับตัวเอง

ลิงก์ไปยังคำถามที่เกี่ยวข้อง:


อัพเดท

เริ่มจ่ายเงินตามคำถาม - ยังไม่มั่นใจว่าทำไมฉันต้องทำซ้ำตรรกะแอพของฉันในกิจกรรมแท็บเล็ตของฉันและในแต่ละกิจกรรมโทรศัพท์

พบบทความที่น่าสนใจโดยผู้ชายที่ Square ซึ่งน่าอ่านดี:


38
+1 สำหรับคำถามที่ยอดเยี่ยมและเขียนได้ดี
Siddharth Lele

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

1
ฉันไม่ได้หมายถึงความผิดโดยสุจริต แต่ฉันคิดว่าคุณแค่ยอมรับสิ่งที่คุณต้องการจะได้ยินมากกว่าคำตอบ Google ไม่แนะนำคำตอบของ Scuba และโพสต์บล็อกที่ฉันชอบเพื่ออธิบายว่าทำไม
pjco

1
@pjco โดยเฉพาะฉันไม่เห็นด้วยกับการมีonItemSelected()วิธีการในกิจกรรม ในแอป "ของจริง" ของฉันฉันมีรายการ & รายการย่อยมากมาย รูปแบบนี้แสดงให้เห็นว่ากิจกรรมแท็บของฉันต้องมีonItemSelected()วิธีจัดการแต่ละรายการ นอกจากนี้กิจกรรมทางโทรศัพท์แต่ละคนจะต้องมีตรรกะเดียวกันที่ซ้ำกันภายในแต่ละกิจกรรม IMHO เป็นการดีกว่ามากที่จะใส่ตรรกะการเลือกรายการลงในแต่ละส่วน - ไม่มีการทำซ้ำและฉันชอบวิธีการสร้างรหัสนั้น ฉันหวังว่านี่จะช่วยได้
Richard Le Mesurier

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

คำตอบ:


41

ฉันเห็นด้วยว่าบทเรียนนั้นง่ายมาก พวกเขาเพิ่งแนะนำFragmentsแต่ฉันไม่เห็นด้วยกับรูปแบบที่แนะนำ

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


ฉันชอบรูปแบบที่ใช้โดยActionBarSherlockแอพ Fragments Demo ( ดาวน์โหลดที่นี่และซอร์สโค้ดที่นี่ ) ตัวอย่างที่ตรงกับบทช่วยสอนที่กล่าวถึงในคำถามมากที่สุดคือตัวอย่างที่เรียกว่า "เลย์เอาต์" ในแอพ หรือFragmentLayoutSupportในซอร์สโค้ด

ในการสาธิตนี้ตรรกะที่ได้รับการย้ายออกจากและเข้าไปในActivity จริงมีตรรกะสำหรับการเปลี่ยนชิ้นส่วน ด้วยวิธีนี้แต่ละกิจกรรมนั้นง่ายมาก ในการทำซ้ำกิจกรรมที่ง่ายมาก ๆ โดยที่ไม่มีตรรกะใด ๆ อยู่ภายในกิจกรรมทำให้มันง่ายมากFragmentTitlesFragment

โดยการวางตรรกะเป็นเศษที่มีไม่จำเป็นต้องเขียนโค้ดมากกว่าหนึ่งครั้ง ; มันสามารถใช้ได้ไม่ว่าจะวางกิจกรรมใดใน Fragment สิ่งนี้ทำให้มันมีรูปแบบที่ทรงพลังมากกว่าที่แนะนำโดยการสอนพื้นฐาน

    /**
    * Helper function to show the details of a selected item, either by
    * displaying a fragment in-place in the current UI, or starting a
    * whole new activity in which it is displayed.
    */
    void showDetails(int index)
    {
        mCurCheckPosition = index;

        if (mDualPane)
        {
            // We can display everything in-place with fragments, so update
            // the list to highlight the selected item and show the data.
            getListView().setItemChecked(index, true);

            // Check what fragment is currently shown, replace if needed.
            DetailsFragment details = (DetailsFragment) getFragmentManager()
                .findFragmentById(R.id.details);
            if (details == null || details.getShownIndex() != index)
            {
                // Make new fragment to show this selection.
                details = DetailsFragment.newInstance(index);

                // Execute a transaction, replacing any existing fragment
                // with this one inside the frame.
                FragmentTransaction ft = getFragmentManager()
                    .beginTransaction();
                ft.replace(R.id.details, details);
                ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
                ft.commit();
            }

        }
        else
        {
            // Otherwise we need to launch a new activity to display
            // the dialog fragment with selected text.
            Intent intent = new Intent();
            intent.setClass(getActivity(), DetailsActivity.class);
            intent.putExtra("index", index);
            startActivity(intent);
        }
    }

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

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


ขอบคุณสำหรับคำตอบที่ครอบคลุม - ฉันได้ดูการสาธิต ABS และฉันคิดว่ามีรหัสที่ดีมากมาย ฉันจะพยายามย้ายตรรกะส่วนใหญ่ของฉันไปไว้ใน Fragments แทน
Richard Le Mesurier

แอปพลิเคชันตัวอย่างย้ายมาที่นี่: play.google.com/store/apps/…
Philippe E.

ฉันคิดว่ารูปแบบที่คุณอธิบายนั้นมาจากรหัสตัวอย่าง Google ดั้งเดิม: android-developers.blogspot.com/2011/02/… ฉันคิดว่า ActionBarSherlock เพิ่งจะส่งรหัสตัวอย่างของ Google เพื่อใช้คลาส ABS
Dan J

17

ฉันคิดว่าคุณกำลังถูกทาง (และใช่บทเรียนนั้นง่ายเกินไป)

ในเค้าโครงแท็บเล็ตคุณสามารถใช้กิจกรรมเดียวและสลับส่วนเข้าและออก (ใน 'บานหน้าต่าง' หลายรายการ) ในขณะที่อยู่ในเค้าโครงโทรศัพท์คุณสามารถใช้กิจกรรมใหม่สำหรับแต่ละส่วน

ชอบมาก

ป้อนคำอธิบายรูปภาพที่นี่

ดูเหมือนว่าจะมีงานพิเศษมากมาย แต่ด้วยการใช้กิจกรรมหลายอย่างสำหรับโทรศัพท์คุณจะสามารถเปิดใช้งานวงจรชีวิตขั้นพื้นฐานและการผ่านเจตนาได้ สิ่งนี้ยังอนุญาตให้เฟรมเวิร์กจัดการกับอนิเมชั่นและ back-stack ทั้งหมด

เพื่อช่วยลดรหัสคุณสามารถใช้BaseActivityและขยายจากนั้น

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

หากผู้ใช้มีโทรศัพท์คุณสามารถใช้กิจกรรมปกติที่มีรหัสน้อยมากและขยายMyBaseSingleFragActivityหรือคล้ายกัน กิจกรรมเหล่านี้อาจง่ายมากรหัส 5-10 บรรทัด (อาจจะน้อยกว่า)

ส่วนที่ยุ่งยากคือการกำหนดเส้นทางเจตนาและอะไร * (แก้ไข: ดูเพิ่มเติมด้านล่าง)

ฉันคิดว่าเหตุผลนี้เป็นวิธีที่แนะนำคือการบันทึกความทรงจำและลดความซับซ้อนและการมีเพศสัมพันธ์ หากคุณทำการแลกเปลี่ยนแฟรกเมนต์การFragmentManagerอ้างอิงจะอ้างอิงไปยังแฟรกเมนต์นั้นสำหรับแบ็คสแต็ก นอกจากนี้ยังลดความซับซ้อนของสิ่งที่ควรเรียกใช้สำหรับผู้ใช้ การตั้งค่านี้ยังแยกมุมมองและเค้าโครงและตรรกะใน Fragment จาก Activity Life-Cycle วิธีนี้แฟรกเมนต์สามารถมีอยู่ในกิจกรรมเดี่ยวข้างแฟรกเมนต์อื่น (สองบานหน้าต่าง) หรือในกิจกรรมสามบานเป็นต้น

* ข้อดีอย่างหนึ่งของการมีการกำหนดเส้นทางเจตนาปกติคือคุณสามารถเปิดใช้งานกิจกรรมได้อย่างชัดเจนจากทุกที่ในแบ็คสแต็ค ตัวอย่างหนึ่งอาจอยู่ในกรณีของผลการค้นหา (MySearchResults.class)

อ่านเพิ่มเติมได้ที่นี่:

http://android-developers.blogspot.com/2011/09/preparing-for-handsets.html

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


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

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

ทำไมการสลับแฟรกเมนต์เมื่อมีจำนวนมาก แต่ถ้ามีเพียง 1 แฟรกเมนต์เท่านั้นที่มองเห็นได้ฉันต้องไม่เปลี่ยนเป็นแฟรกเมนต์อื่น?
Richard Le Mesurier

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

ยินดีต้อนรับคุณ :) โปรด upvote หรือยอมรับถ้าคุณรู้สึกว่าคำตอบจะเป็นประโยชน์
pjco

6

นี่คือคำตอบ Reto Meier เรื่องเดียวกันที่นำมาจากวิดีโอนี้ของUdacity ของหลักสูตรความรู้พื้นฐานของ

มีสาเหตุหลายประการที่คุณควรแยกแอพของคุณออกเป็นกิจกรรมต่างๆ

  • การมีกิจกรรมแบบเสาหินเดียวจะเพิ่มความซับซ้อนของรหัสทำให้ยากต่อการอ่านทดสอบและบำรุงรักษา
  • ทำให้การสร้างและการจัดการตัวกรองเจตนายากขึ้น
  • เพิ่มความเสี่ยงของการมีเพศสัมพันธ์อย่างอิสระส่วนประกอบ
  • ทำให้มีโอกาสมากขึ้นที่จะแนะนำความเสี่ยงด้านความปลอดภัยหากกิจกรรมเดียวมีทั้งข้อมูลที่ละเอียดอ่อนและข้อมูลที่ปลอดภัยที่จะแบ่งปัน

กฎง่ายๆคือการสร้างกิจกรรมใหม่เมื่อใดก็ตามที่บริบทเปลี่ยนไป ตัวอย่างเช่นการแสดงข้อมูลประเภทอื่นและในขณะที่สลับจากการดูเป็นการป้อนข้อมูล


น่าสนใจชื่อของวิดีโอคือ "ทำไมเราไม่เพียง แต่ใช้เศษ"
Richard Le Mesurier

มันเป็นวิธีการที่ดีกำลังเผชิญกับปัญหามากมายกับกิจกรรมเดี่ยวหลายชิ้น ... ประสบการณ์จริงอาจเป็นไปได้
GvSharma

4

ปัญหาหนึ่งของวิธีนี้คือคุณทำซ้ำตรรกะจำนวนมากในกิจกรรมแท็บเล็ตหลักและในกิจกรรมโทรศัพท์แยกต่างหาก

ในรูปแบบรายละเอียดหลักมีสองกิจกรรม หนึ่งแสดงทั้งชิ้นส่วนบนหน้าจอขนาดใหญ่และเฉพาะส่วน "ต้นแบบ" บนหน้าจอขนาดเล็ก ส่วนอื่น ๆ จะแสดงส่วน "รายละเอียด" บนหน้าจอขนาดเล็ก

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

สิ่งที่ฉันได้อ่านเกี่ยวกับ ActionBarSherlock ก็คือดูเหมือนว่าจะทำงานได้ดีที่สุดกับ Fragments แทนที่จะเป็นกิจกรรม (แต่ฉันยังไม่ได้ทำงานด้วย)

ActionBarSherlock ไม่ได้เกี่ยวข้องกับแฟรกเมนต์มากกว่าเนเชอร์บาร์อีกต่อไปเนื่องจาก ActionBarSherlock เป็นแบ็คพอร์ทของเนชั่นเนชั่นบาร์โดยแท้


คุณคิดอย่างไรกับแนวคิดของกิจกรรมเดี่ยว
theblang

@attblang: ตราบใดที่คุณได้รับการนำทางที่ถูกต้องก็ไม่มีปัญหา
CommonsWare

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

0

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


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