Android 将 Fragment 放在前面(无 Fragment 娱乐)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20737550/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 03:22:41  来源:igfitidea点击:

Bring Fragment to Front (No fragment recreation)

androidandroid-fragmentsandroid-fragmentactivity

提问by Nitin Misra

I have three fragments F1 F2 F3 F4 all are accessible from sidebar.

我有三个片段 F1 F2 F3 F4 都可以从侧边栏访问。

all four can be called at any time and in any order,

所有四个都可以随时以任何顺序调用,

Now I want if, F1 is already clicked(created) then never again create F1, but only bring back fragment F1 to front using fragment manager. Same for all other fragment

现在我想要如果 F1 已经被点击(创建)然后再也不创建 F1,但只使用片段管理器将片段 F1 带回到前面。所有其他片段相同

So far i tried this for every fragmentin my container (FRAGMENT ACTIVITY)

到目前为止,我对容器中的每个片段都尝试了这个(片段活动)

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{

}

Ifpart ensures me NO fragment is recreated (If its created already) again, but what should i write in elsepart so that already created fragment can be brought to front in View Hierarchy

If部分确保我没有重新创建片段(如果它已经创建了),但是我应该写什么else部分以便已经创建的片段可以放在视图层次结构中

Please Help, i'm stuck at this for 2 days.

请帮助,我被困在这 2 天。

回答by Solata

I would put this code in activity class, that must have FrameLayoutwith id R.id.fragment_container.

我会把这段代码放在活动类中,它必须有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();

}

And add this for button click:

并添加此按钮单击:

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();
    }
    //...
}

On button click(s) you can show, that fragment that you want and hide others.

单击按钮时,您可以显示您想要的片段并隐藏其他片段。

NOTE (@developer1011):For use after activity save state call commitAllowingStateLoss (). Use with care, because fragment is not restored with activity restoration.

注意(@developer1011):用于在活动保存状态调用之后使用commitAllowingStateLoss ()。小心使用,因为片段不会随着活动恢复而恢复。

NOTE:MainActivity should implement OnFragmentInteractionListener for each Fragment.

注意:MainActivity 应该为每个 Fragment 实现 OnFragmentInteractionListener。

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

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

回答by nikvs

Get the fragment by tag and replace it in the container,

通过标签获取片段并在容器中替换它,

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

UPDATE: you can use hide and show fragment to avoid recreation.instead of using "transaction.replace()"

更新:您可以使用隐藏和显示片段来避免重新创建。而不是使用“transaction.replace()”

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

回答by erluxman

If you are just trying to add a Fragmentwithout having to worry about recreating it then I think this method I have wrote to add Fragmentwill do you job.

如果你只是想添加一个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 {
        ft.show ( manager.findFragmentByTag ( tag ) ).commit ();
    }
}

回答by Rick Falck

  1. Use a simple ArrayList<Fragment>for your Fragments, and add them in order, so that you know get(0) will get F1, get(1) gets F2, etc.

  2. Create the Fragments as singletons. In each fragment add a static field and method:

     private static Fragment mMyInstance = null;
    
     public static Fragment newInstance() {
         if (mMyInstance == null) {
             mMyInstance = new F1();
         }
         return mMyInstance;
     }
    
  3. Create the Fragments with the static method and add them to the ArrayList.

  4. In each Fragment add the setRetainInstance(true);command to the onCreate() method.

  1. 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() 方法。

Now when you add the Fragment with the FragmentManager, onCreate()will only be called the first time, but onCreateView()will be called every time. You want to inflate the view and wire the widgets each time, just en case your Activity got recreated because of a configuration change. But you can check something you add to see if it's the first time or not, and reset the widgets to their previous state if not. So, you will need member variables in your Fragments to keep track of their state. Override onStop() to save state, and reapply it in onCreateView() after wiring up the widgets.

现在当你用 FragmentManager 添加 Fragment 时,onCreate()只会在第一次onCreateView()被调用,但每次都会被调用。您希望每次都扩展视图并连接小部件,以防万一您的 Activity 由于配置更改而重新创建。但是您可以检查您添加的内容以查看它是否是第一次,如果不是,则将小部件重置为之前的状态。因此,您将需要 Fragments 中的成员变量来跟踪它们的状态。覆盖 onStop() 以保存状态,并在连接小部件后在 onCreateView() 中重新应用它。

Then when the sidebar button is pressed, you get the Fragment that corresponds to that button, remove the previous Fragment, and add the current one with the FragmentManager (or just use the replace() command instead of remov()/add()).

然后当侧边栏按钮被按下时,你会得到对应于那个按钮的 Fragment,移除之前的 Fragment,并用 FragmentManager 添加当前的 Fragment(或者只是使用 replace() 命令而不是 remov()/add()) .

回答by JDenais

If you are using the Support Fragment, then this static method does the job.

如果您使用的是 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;
}