รับวัตถุชิ้นส่วนปัจจุบัน


175

ในตัวmain.xmlฉันมี

  <FrameLayout
        android:id="@+id/frameTitle"
        android:padding="5dp"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:background="@drawable/title_bg">
            <fragment
              android:name="com.fragment.TitleFragment"
              android:id="@+id/fragmentTag"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content" />

  </FrameLayout>

และฉันกำลังตั้งวัตถุชิ้นส่วนเช่นนี้

FragmentManager fragmentManager = activity.getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment newFragment = new FragmentType1();
fragmentTransaction.replace(R.id.frameTitle, casinodetailFragment, "fragmentTag");

// fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();

มันคือการตั้งค่าวัตถุชิ้นส่วนFragmentType2,FragmentType3,...แตกต่างกัน( ) ในเวลาที่แตกต่างกัน ในบางช่วงเวลาฉันต้องระบุวัตถุที่มีอยู่ในขณะนี้

ในระยะสั้นฉันต้องทำอะไรเช่นนี้

Fragment currentFragment = //what is the way to get current fragment object in FrameLayout R.id.frameTitle

ฉันพยายามต่อไปนี้

TitleFragment titleFragmentById = (TitleFragment) fragmentManager.findFragmentById(R.id.frameTitle);

และ

    TitleFragment titleFragmentByTag = (TitleFragment) fragmentManager.findFragmentByTag("fragmentTag");

แต่ทั้งวัตถุ (titleFragmentById และ titleFragmentByTag)null
ฉันคิดถึงอะไรบางอย่างเหรอ?
ฉันใช้และการพัฒนาสำหรับCompatibility Package, r3API level 7

findFragmentById()และfindFragmentByTag()จะทำงานได้ถ้าเราตั้งค่าชิ้นส่วนที่ใช้fragmentTransaction.replaceหรือfragmentTransaction.addแต่จะreturn nullถ้าเราตั้งค่าวัตถุเป็น xml (เหมือนสิ่งที่ฉันได้ทำลงไปmain.xml) ฉันคิดว่าฉันขาดอะไรบางอย่างในไฟล์ XML ของฉัน


ที่เกี่ยวข้อง - stackoverflow.com/a/21104084/80428
Jay Wick

@CommonsWare ช่วยตอบคุณหรือเปล่าเพราะฉันยังว่างอยู่?
IntoTheDeep

คำตอบ:


253

ในบางช่วงเวลาฉันต้องระบุวัตถุที่มีอยู่ในขณะนี้

โทรfindFragmentById()ในFragmentManagerและกำหนดส่วนของคุณอยู่ในR.id.frameTitleภาชนะ


1
ขอบคุณสำหรับคำตอบของคุณ มันจะทำงานได้ถ้าเราตั้งค่าส่วนโดยใช้fragmentTransaction.replace หรือfragmentTransaction.addจะไม่ได้ถ้าเราตั้งค่าไว้ที่ xml ดูการแก้ไข 2 ของฉัน
Labeeb Panampullan

9
@Labeeb P: คุณไม่สามารถแก้ไขชิ้นส่วนที่ประกาศในทรัพยากรรูปแบบ
CommonsWare

การสร้างคลาสเพื่อเก็บแท็บ / แฟรกเมนต์ที่มองเห็นได้ในปัจจุบันจะใช้งานได้เช่นกัน หวังว่าจะไม่มีความล้มเหลว
Skynet

@CommonsWare findFragmentByTagส่งคืน null ในกรณีของActionBarแท็บ ในของฉันActivityซึ่งจะขยายActionBarActivityฉันแรกเพิ่มแท็บไปActionBarแล้วค้นหา!
มูฮัมหมัดบาบา

1
@MuhammadBabar: คุณสามารถลองexecutePendingTransactions()ใช้FragmentManagerหลังจากเรียกcommit()ธุรกรรม แต่ฉันยังไม่ได้ลอง หรือคุณสามารถใช้setContentView()เพื่อใช้ไฟล์เลย์เอาต์ที่มี<fragment>แท็ก อย่างใดอย่างหนึ่งของผู้ที่เกิดขึ้นพร้อมกันและอื่น ๆ ส่วนจะอยู่ภายในonCreate()เรียกตัวเองที่คุณใช้หรือexecutePendingTransaction() setContentView()มิฉะนั้นระบบFragmentTransactionจะประมวลผลแบบอะซิงโครนัสและจะไม่เริ่มแม้กระทั่งเมื่อเวลาonCreate()สิ้นสุด
CommonsWare

110

ลองนี้

Fragment currentFragment = getActivity().getFragmentManager().findFragmentById(R.id.fragment_container);

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

    if (currentFragment instanceof NameOfYourFragmentClass) {
     Log.v(TAG, "find the current fragment");
  }

จะใส่สายนี้ที่ไหน
Anand Savjani

9
บางครั้งคุณต้องใช้getSupportFragmentManager()แทนและจะได้รับ null โดยไม่มีsupportส่วน
Muz

ลบเครื่องหมายคำพูดจาก "NAME OF FRAGMENT CLASS"
อลันเนลสัน

37

ฉันคิดว่าคุณสามารถใช้onAttachFragment event ได้อาจเป็นประโยชน์ในการตรวจสอบว่าแฟรกเมนต์ใดทำงานอยู่

@Override
public void onAttachFragment(Fragment fragment) {
    // TODO Auto-generated method stub
    super.onAttachFragment(fragment);

    Toast.makeText(getApplicationContext(), String.valueOf(fragment.getId()), Toast.LENGTH_SHORT).show();

}

3
ฉันสามารถรับส่วนที่ฉันแนบ ความคิดของฉันคือเมื่อฉันเปลี่ยนทิศทางแล้วฉันต้องแสดงมุมมองเดียวกันไม่ใช่มุมมองอื่นดังนั้นวิธีการทำเช่นนี้
นักพัฒนา Androi

7
สิ่งนี้ไม่ทำงานเนื่องจากไม่ได้อัปเดตชิ้นส่วนที่ใช้งานอยู่เมื่อคุณย้อนกลับไป
Justin

1
@Justin ดังนั้นเราแค่ต้องใช้ onDetach ด้วยรายการการ
อ้างอิงอ่อน

12

ฉันคิดว่าคุณควรทำ:

Fragment currentFragment = fragmentManager.findFragmentByTag("fragmentTag");

เหตุผลเนื่องจากคุณตั้งค่าแท็ก "fragmentTag" เป็นแฟรกเมนต์สุดท้ายที่คุณเพิ่ม (เมื่อคุณเรียกแทนที่)


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

ขอบคุณมาก! แก้ไขปัญหาของฉัน!
Jonas Gröger

2
วิธีแก้ปัญหานี้ไม่ได้หมายความว่าคุณต้องใส่แท็กเดียวกันสำหรับหลายชิ้น มิฉะนั้นคุณจะรู้ได้อย่างไรว่าfragmentTagเป็นแท็กสำหรับแฟรกเมนต์ปัจจุบัน
Thupten

12

คุณสามารถรับรายชื่อของชิ้นส่วนและดูล่าสุด

    FragmentManager fm = getSupportFragmentManager();
    List<Fragment> fragments = fm.getFragments();
    Fragment lastFragment = fragments.get(fragments.size() - 1);

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

    FragmentManager fm = getSupportFragmentManager();
    if (fm != null) {
        List<Fragment> fragments = fm.getFragments();
        if (fragments != null) {
            for(int i = fragments.size() - 1; i >= 0; i--){
                Fragment fragment = fragments.get(i);
                if(fragment != null) {
                    // found the current fragment

                    // if you want to check for specific fragment class
                    if(fragment instanceof YourFragmentClass) {
                        // do something
                    }
                    break;
                }
            }
        }
    }

3
อย่าใช้getFragments()วิธีการ มันถูกทำเครื่องหมายด้วย@hideและไม่ควรถูกรวมไว้กับ jar ไลบรารีสนับสนุน ไม่ควรพิจารณาว่าเป็นส่วนหนึ่งของ API ที่ส่งออก
James Wald

พวกเขาควรจะสร้างวิธีการที่ช่วยให้คุณทำสิ่งที่getFragments()ทำเพราะคุณต้องการมันค่อนข้างบ่อย ฉันคิดว่าตอนนี้มีให้บริการแบบสาธารณะแล้วเช่นกัน
EpicPandaForce

10

นี่คือทางออกที่ง่ายที่สุดและใช้ได้สำหรับฉัน

1. ) คุณเพิ่มส่วนของคุณ

ft.replace(R.id.container_layout, fragment_name, "fragment_tag").commit();

2. )

FragmentManager fragmentManager = getSupportFragmentManager();

Fragment currentFragment = fragmentManager.findFragmentById(R.id.container_layout);

if(currentFragment.getTag().equals("fragment_tag"))

{

 //Do something

}

else

{

//Do something

}

9

มันอาจจะสาย แต่ฉันหวังว่ามันจะช่วยคนอื่นได้เช่นกัน @CommonsWare ได้โพสต์คำตอบที่ถูกต้องแล้ว

FragmentManager fm = getSupportFragmentManager();
Fragment fragment_byID = fm.findFragmentById(R.id.fragment_id);
//OR
Fragment fragment_byTag = fm.findFragmentByTag("fragment_tag");

9
สิ่งนี้ไม่อนุญาตให้คุณรับแฟรกเมนต์ที่ใช้งานอยู่เนื่องจากคุณไม่จำเป็นต้องรู้ id หรือแท็ก
Justin

7

บางทีวิธีที่ง่ายที่สุดคือ:

public MyFragment getVisibleFragment(){
    FragmentManager fragmentManager = MainActivity.this.getSupportFragmentManager();
    List<Fragment> fragments = fragmentManager.getFragments();
    for(Fragment fragment : fragments){
        if(fragment != null && fragment.getUserVisibleHint())
            return (MyFragment)fragment;
    }
    return null;
}

มันใช้งานได้สำหรับฉัน


6

คุณสามารถสร้างฟิลด์ในคลาสกิจกรรมหลัก:

public class MainActivity extends AppCompatActivity {

    public Fragment fr;

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

}

จากนั้นภายในแต่ละชั้นแฟรกเมนต์:

public class SomeFragment extends Fragment {

@Override
    public View onCreateView(LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {

        ((MainActivity) getActivity()).fr = this;
}

ฟิลด์ 'fr' ของคุณเป็นวัตถุชิ้นส่วนปัจจุบัน

มันยังทำงานกับ popBackStack ()


4

ฉันรู้ว่าไม่นานมานี้ แต่ฉันจะใช้ที่นี่เพื่อช่วยคนอื่น

คำตอบที่เหมาะสมโดยไกล (และหนึ่งที่เลือก) จาก CommonsWare ฉันมีปัญหาเช่นเดียวกับที่โพสต์ต่อไปนี้

MyFragmentClass fragmentList = 
            (MyFragmentClass) getSupportFragmentManager().findFragmentById(R.id.fragementID);

เก็บไว้ในการกลับมาเป็นโมฆะ ความผิดพลาดของฉันโง่มากในไฟล์ xml ของฉัน:

<fragment
    android:tag="@+id/fragementID"
    android:name="com.sf.lidgit_android.content.MyFragmentClass"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
/>

ความผิดพลาดคือการที่ฉันมีหุ่นยนต์: แท็กแทนของหุ่นยนต์: ID


2

@ การตอบสนองของแฮมเมอร์ใช้ได้ผลกับฉันฉันใช้เพื่อควบคุมปุ่มการกระทำแบบลอยตัว

final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(final View view) {
            android.app.Fragment currentFragment = getFragmentManager().findFragmentById(R.id.content_frame);
            Log.d("VIE",String.valueOf(currentFragment));
            if (currentFragment instanceof PerfilFragment) {
                PerfilEdit(view, fab);
            }
        }
});

2

หากคุณกำลังขยายจาก AbstractActivity คุณสามารถใช้วิธี getFragments ():

for (Fragment f : getFragments()) {
    if (f instanceof YourClass) {
        // do stuff here
    }
}

1

หากคุณกำลังกำหนดส่วนในกิจกรรมของ layour XML แล้วในActivityให้แน่ใจว่าคุณโทรหาก่อนที่จะเรียกsetContentView()findFragmentById()


1

หากคุณใช้ BackStack ... และเฉพาะในกรณีที่คุณใช้แบ็คสแต็คให้ลองทำดังนี้:

rivate Fragment returnToPreviousFragment() {

    FragmentManager fm = getSupportFragmentManager();

    Fragment topFrag = null;

    int idx = fm.getBackStackEntryCount();
    if (idx > 1) {
        BackStackEntry entry = fm.getBackStackEntryAt(idx - 2);
        topFrag = fm.findFragmentByTag(entry.getName());
    }

    fm.popBackStack();

    return topFrag;
}

0

นี่จะให้ชื่อคลาสแฟรกเมนต์ปัจจุบัน ->

String fr_name = getSupportFragmentManager().findFragmentById(R.id.fragment_container).getClass().getSimpleName();

0
  1. ทำการตรวจสอบ (ซึ่งส่วนในภาชนะกิจกรรม) ในวิธีการ onStart;

    @Override
    protected void onStart() {
    super.onStart();
    Fragment fragmentCurrent = getSupportFragmentManager.findFragmentById(R.id.constraintLayout___activity_main___container);
    }
  2. ตรวจสอบบางส่วน:

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