簡體   English   中英

將 Fragment 放在前面(無 Fragment 娛樂)

[英]Bring Fragment to Front (No fragment recreation)

我有三個片段 F1 F2 F3 F4 都可以從側邊欄訪問。

所有四個都可以隨時以任何順序調用,

現在我想要如果 F1 已經被點擊(創建)然后再也不創建 F1,但只使用片段管理器將片段 F1 帶回到前面。 所有其他片段相同

到目前為止,我對容器中的每個片段都嘗試了這個(片段活動)

if (fragmentManager.findFragmentByTag("apps")==null) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);

Fragment newFragment = new CategoriesFragment();
transaction.replace(R.id.content_frame, newFragment, "apps");
transaction.addToBackStack("apps");
transaction.commit();   
} else{

}

If部分確保我沒有重新創建片段(如果它已經創建了),但是我應該在else部分寫else以便已經創建的片段可以放在視圖層次結構的前面

請幫助,我被困在這 2 天。

我會把這段代碼放在活動類中,它必須有FrameLayout和 ID R.id.fragment_container

private Fragment1 F1;
private Fragment2 F2;
private Fragment3 F3;
private Fragment4 F4;       

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    F1 = new Fragment1();
    getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, F1).commit();
    F2 = new Fragment2();
    getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, F2).commit();
    F3 = new Fragment3();
    getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, F3).commit();
    F4 = new Fragment4();
    getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, F4).commit();

    //if needed show F1
    getSupportFragmentManager().beginTransaction().show(F1).commit();

}

並添加此按鈕單擊:

public void onBtnClick(View view){
    if(mShowF1){
        getSupportFragmentManager().beginTransaction().show(F1).commit();
        getSupportFragmentManager().beginTransaction().hide(F2).commit();
        getSupportFragmentManager().beginTransaction().hide(F3).commit();
        getSupportFragmentManager().beginTransaction().hide(F4).commit();
    }
    //...
}

單擊按鈕時,您可以顯示您想要的片段並隱藏其他片段。

注意(@developer1011):用於在活動保存狀態調用commitAllowingStateLoss () 小心使用,因為片段不會隨着活動恢復而恢復。

注意: MainActivity 應該為每個 Fragment 實現 OnFragmentInteractionListener。

public class MainActivity extends FragmentActivity implements Fragment1.OnFragmentInteractionListener, Fragment2.OnFragmentInteractionListener, Fragment3.OnFragmentInteractionListener, Fragment4.OnFragmentInteractionListener {//..

    @Override
    public void onFragmentInteraction(Uri uri) {
        //
    }
}

通過標簽獲取片段並在容器中替換它,

else{
Fragment existingFragment = (CategoriesFragment)fragmentManager.findFragmentByTag("apps");
transaction.replace(R.id.content_frame,existingFragment, "apps");
transaction.addToBackStack("apps");
transaction.commit();
}

更新:您可以使用隱藏和顯示片段來避免重新創建。而不是使用“transaction.replace()”

fragmentTransaction.hide(<oldFragment>);
fragmentTransaction.show(<newFragment>);

爪哇:

如果您只是想添加Fragment而不必擔心重新創建它,那么我認為我編寫的這種添加Fragment可以完成您的工作。

public static void attachFragment ( int fragmentHolderLayoutId, Fragment fragment, Context context, String tag ) {


    FragmentManager manager = ( (AppCompatActivity) context ).getSupportFragmentManager ();
    manager.findFragmentByTag ( tag );
    FragmentTransaction ft = manager.beginTransaction ();

    if (manager.findFragmentByTag ( tag ) == null) { // No fragment in backStack with same tag..
        ft.add ( fragmentHolderLayoutId, fragment, tag );
        ft.addToBackStack ( tag );
        ft.commit ();
    }
    else {
        for (Fragment frag : manager.getFragments()){
          ft.hide(frag)
        }
        ft.show ( manager.findFragmentByTag ( tag ) ).commit ();
    }
}

科特林:

fun attachFragment(fragmentHolderLayoutId: Int, fragment: Fragment?, tag: String?) {
    val manager: FragmentManager = supportFragmentManager
    val ft: FragmentTransaction = manager.beginTransaction()
    if (manager.findFragmentByTag(tag) == null) { // No fragment in backStack with same tag..
        ft.add(fragmentHolderLayoutId, fragment!!, tag)
        ft.addToBackStack(tag)
        ft.commit()
    } else {
        //Hide other fragments
        for (frag in manager.fragments){
            ft.hide(frag)
        }
        //Shows the selected fragment.
        ft.show(manager.findFragmentByTag(tag)!!).commit()
    }
}
  1. 為您的 Fragment 使用一個簡單的ArrayList<Fragment> ,並按順序添加它們,以便您知道 get(0) 將獲得 F1,get(1) 將獲得 F2,等等。

  2. 將片段創建為單例。 在每個片段中添加一個靜態字段和方法:

     private static Fragment mMyInstance = null; public static Fragment newInstance() { if (mMyInstance == null) { mMyInstance = new F1(); } return mMyInstance; }
  3. 使用靜態方法創建 Fragment 並將它們添加到 ArrayList。

  4. 在每個 Fragment 中添加setRetainInstance(true); 命令 onCreate() 方法。

現在,當您添加的片段與FragmentManager, onCreate()才會被調用的第一次,但onCreateView()都會被調用一次。 您希望每次都擴展視圖並連接小部件,以防萬一您的 Activity 由於配置更改而重新創建。 但是您可以檢查您添加的內容以查看它是否是第一次,如果不是,則將小部件重置為之前的狀態。 因此,您將需要 Fragments 中的成員變量來跟蹤它們的狀態。 覆蓋 onStop() 以保存狀態,並在連接小部件后在 onCreateView() 中重新應用它。

然后當側邊欄按鈕被按下時,你會得到對應於那個按鈕的 Fragment,移除之前的 Fragment,並用 FragmentManager 添加當前的 Fragment(或者只是使用 replace() 命令而不是 remov()/add()) .

如果您使用的是 Support Fragment,那么這個靜態方法就可以完成這項工作。

    /**
 * Takes a Fragment TAG and tries to find the fragment in the manager if it exists and bring it to front.
 * if not, will return false;
 * @param manager
 * @param tag
 */
public static boolean resurfaceFragment(FragmentManager manager, String tag ){
    Fragment fragment = manager.findFragmentByTag(tag);
    FragmentTransaction transaction = manager.beginTransaction();
    if (fragment!=null){
        for (int i = 0; i < manager.getFragments().size(); i++) {
            Fragment f =  manager.getFragments().get(i);
            transaction.hide(f);

        }
        transaction.show(fragment).commit();
        return true;
    }

    return false;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM