การแทนที่ส่วนย่อยด้วยส่วนอื่นภายในกลุ่มกิจกรรม


137

ฉันมีส่วนหนึ่งในกิจกรรมกลุ่มและฉันต้องการแทนที่ด้วยส่วนอื่น:

FragmentTransaction ft = getActivity().getFragmentManager().beginTransaction();
SectionDescriptionFragment bdf = new SectionDescriptionFragment();
ft.replace(R.id.book_description_fragment, bdf);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();

มันใช้งานได้ดีเมื่อทำเป็นโครงการแยกโดยไม่ต้องใช้กลุ่มกิจกรรมทุกอย่างทำงานได้ดีใน log cat เมื่อการควบคุมเข้าไปใน getview () แต่ไม่มีมุมมองที่มองเห็นได้ไม่มีข้อยกเว้นใด ๆ เกิดขึ้นฉันต้องการให้ส่วนรายละเอียดหนังสือเป็น ถูกแทนที่ด้วยส่วนรายละเอียดส่วน

Xml ของส่วนรายละเอียดหนังสือมี id book_description_fragment และ xml สำหรับส่วนคำอธิบายส่วนมี id section_description_fragment

โค้ดด้านบนอยู่ในเมธอด onClick ของรายการฉันต้องการให้เมื่อผู้ใช้แตะที่รายการในมุมมองเลื่อนแนวนอนจากนั้นส่วนจะเปลี่ยนไป

คำตอบ:


253

ส่วนที่เป็นฮาร์ดโค้ดใน XML ไม่สามารถแทนที่ได้ หากคุณต้องการแทนที่ชิ้นส่วนด้วยชิ้นส่วนอื่นคุณควรเพิ่มแบบไดนามิกก่อนอื่น

หมายเหตุ: R.id.fragment_containerคือเค้าโครงหรือคอนเทนเนอร์ที่คุณเลือกในกิจกรรมที่คุณนำแฟรกเมนต์ไป

// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack if needed
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);

// Commit the transaction
transaction.commit();

8
R.id.fragment_container ในกรณีนี้คืออะไร
Guy

4
@Guy อาจเป็นเลย์เอาต์ใดก็ได้ที่คุณต้องการโหลดชิ้นส่วนลงใน
Subin Sebastian

1
ชื่อของ Fragment ในไฟล์ xml ควรเป็นอย่างไร ฉันต้องการเพิ่มแฟรกเมนต์แบบไดนามิกและไม่ต้องการแฟรกเมนต์แบบคงที่
Rajat Mehra

1
@RajatMehra หากคุณต้องการเพิ่มแฟรกเมนต์แบบไดนามิกคุณไม่จำเป็นต้องระบุแฟรกเมนต์ภายใน XML เลย คุณสามารถใช้มุมมองคอนเทนเนอร์ โปรดอ่านคำตอบอีกครั้ง
Subin Sebastian

4
@Ahmed เหตุผลก็คือว่าโดยสถาปัตยกรรมระบบแทนที่ <ส่วน> แท็กทุกมุมมอง (กลุ่ม) ให้โดยชิ้นส่วนที่สอดคล้องกัน onCreateView()ดังนั้นอย่างที่คุณสามารถสันนิษฐานได้ว่าการอ้างอิงถึงแฟรกเมนต์นั้นหายไปที่ระดับมุมมอง ดังนั้นโดยทั่วไปคุณไม่สามารถแทนที่ส่วนย่อยได้ แต่คุณสามารถลบมุมมองที่มีอยู่ในคอนเทนเนอร์ได้ด้วยตนเองและใส่ส่วนที่นั่นแทนหากจำเป็น
Subin Sebastian

35

โปรดดูคำถามนี้

คุณสามารถแทนที่ " ส่วนที่เพิ่มแบบไดนามิก " เท่านั้น

ดังนั้นถ้าคุณต้องการที่จะเพิ่มส่วนแบบไดนามิกให้ดูนี้ตัวอย่างเช่น


1
สวัสดี. ฉันได้ค้นพบวิธีแก้ปัญหาจริง ๆ แล้วฉันไม่ได้วางเนื้อหาของชิ้นส่วนในเค้าโครงแทนที่จะใช้ส่วนอื่นสำหรับเนื้อหาของส่วนก่อนหน้า
Lion Heart

ไม่ฉันต้องการแทนที่ส่วนทั้งหมดด้วยส่วนใหม่
Sana

1
@ Lion Heart คุณช่วยอธิบายวิธีแก้ปัญหาที่คุณพบได้ไหม?
น้ำรฐา

ลิงค์ตาย: /
Neon Warge

8

ฉันได้สร้างส่วนสำคัญด้วยวิธีการที่สมบูรณ์แบบเพื่อจัดการการเปลี่ยนชิ้นส่วน และวงจรชีวิตวงจรชีวิต

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

มันมีหลายตัวเลือกราวกับว่าคุณต้องการให้ส่วนถูกบันทึกไว้ในแบ็คสแต็ค

=> ดู Gist ที่นี่

เมื่อใช้สิ่งนี้และกิจกรรมเดียวคุณอาจต้องการเพิ่มสิ่งนี้ในกิจกรรมของคุณ:

@Override
public void onBackPressed() {
    int fragments = getSupportFragmentManager().getBackStackEntryCount();
    if (fragments == 1) {
            finish();
            return;
    }

    super.onBackPressed();
}

1
@ RémiPลิงก์ทำงานตามที่คาดไว้ คุณสามารถตรวจสอบสิ่งนี้ที่อาจดีกว่า IMO github.com/HugoGresse/Anecdote/blob/master/app/src/main/java/io/…
Hugo Gresse

7

ใช้รหัสด้านล่างใน android.support.v4

FragmentTransaction ft1 = getFragmentManager().beginTransaction();
WebViewFragment w1 = new WebViewFragment();
w1.init(linkData.getLink());
ft1.addToBackStack(linkData.getName());
ft1.replace(R.id.listFragment, w1);
ft1.commit();

4

ใช้รหัสนี้โดยใช้ v4

 ExampleFragment newFragment = new ExampleFragment();     
 FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();  
 // Replace whatever is in the fragment_container view with this fragment,  
 // and add the transaction to the back stack so the user can navigate back   
 transaction.replace(R.id.container, newFragment);
 transaction.addToBackStack(null);  
 // Commit the transaction   
 transaction.commit();

3

ใช้ ViewPager มันทำงานสำหรับฉัน

final ViewPager viewPager = (ViewPager) getActivity().findViewById(R.id.vp_pager); 
button = (Button)result.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        viewPager.setCurrentItem(1);
    }
});

2

หวังว่าคุณจะทำได้ดีเมื่อฉันเริ่มทำงานด้วยAndroid Fragmentsตอนนั้นฉันก็มีปัญหาเดียวกันจากนั้นฉันก็อ่านเกี่ยวกับ 1- วิธีการสลับส่วนกับอื่น ๆ 2- วิธีเพิ่มส่วนหากFragment containerไม่มีส่วนใด ๆ

หลังจากการวิจัยและพัฒนาบางอย่างฉันได้สร้างฟังก์ชันที่ช่วยฉันในหลาย ๆ โปรเจ็กต์จนถึงตอนนี้และฉันก็ยังใช้ฟังก์ชันง่ายๆนี้อยู่

public void switchFragment(BaseFragment baseFragment) {
    try {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
        if (getSupportFragmentManager().findFragmentById(R.id.home_frame) == null) {
            ft.add(R.id.home_frame, baseFragment);
        } else {
            ft.replace(R.id.home_frame, baseFragment);
        }
        ft.addToBackStack(null);
        ft.commit();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

สนุกกับรหัสของคุณ :)


ทำไมคุณต้องรวมรหัสธุรกรรมส่วนของคุณไว้ใน try catch โดยมีข้อยกเว้นทั่วไป
Banana droid

1

คุณสามารถใช้รหัสนี้

((AppCompatActivity) getActivity()).getSupportFragmentManager().beginTransaction().replace(R.id.YourFrameLayout, new YourFragment()).commit();

หรือคุณสามารถใช้รหัสนี้

YourFragment fragments=(YourFragment) getSupportFragmentManager().findFragmentById(R.id.FrameLayout);

        if (fragments==null) {
            getSupportFragmentManager().beginTransaction().replace(R.id.FrameLayout, new Fragment_News()).commit();
        }

0

ใน Kotlin คุณสามารถทำได้:

// instantiate the new fragment
val fragment: Fragment = ExampleFragment()

val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.book_description_fragment, fragment)
transaction.addToBackStack("transaction_name")
// Commit the transaction
transaction.commit()

0

คุณสามารถใช้รหัสง่ายๆในการทำธุรกรรม

Fragment newFragment = new MainCategoryFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame_NavButtom, newFragment);
ft.commit(); 

0

ฉันเปลี่ยนส่วนแบบไดนามิกในโค้ดบรรทัดเดียว
มันใช้งานได้ในเวอร์ชัน SDK ใด ๆ และ androidx
ฉันใช้การนำทางเป็นBottomNavigationView

    BottomNavigationView btn_nav;
    FragmentFirst fragmentFirst;
    FragmentSecond fragmentSecond;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);
        fragmentFirst = new FragmentFirst();
        fragmentSecond = new FragmentSecond ();
        changeFragment(fragmentFirst); // at first time load the fragmentFirst
        btn_nav = findViewById(R.id.bottomNav);
        btn_nav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
                switch(menuItem.getItemId()){
                    case R.id.menu_first_frag:
                        changeFragment(fragmentFirst); // change fragmentFirst
                        break;
                    case R.id.menu_second_frag:
                        changeFragment(fragmentSecond); // change fragmentSecond
                        break;
                        default:
                            Toast.makeText(SearchActivity.this, "Click on wrong bottom SORRY!", Toast.LENGTH_SHORT).show();
                }
                return true;
            }
        });
    }
public void changeFragment(Fragment fragment) {
        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout_changer, fragment).commit();
    }

0

วิธีนี้จะได้ผลหากคุณพยายามเปลี่ยนชิ้นส่วนจากส่วนอื่น

Objects.requireNonNull(getActivity()).getSupportFragmentManager()
.beginTransaction()
.replace(R.id.home_fragment_container,new NewFragment())

หมายเหตุตามที่ระบุไว้ในคำตอบข้างต้นคุณต้องมีชิ้นส่วนไดนามิก

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