简体   繁体   English

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

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

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.现在我想要如果 F1 已经被点击(创建)然后再也不创建 F1,但只使用片段管理器将片段 F1 带回到前面。 Same for all other fragment所有其他片段相同

So far i tried this for every fragment in 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{

}

If part ensures me NO fragment is recreated (If its created already) again, but what should i write in else part so that already created fragment can be brought to front in View Hierarchy If部分确保我没有重新创建片段(如果它已经创建了),但是我应该在else部分写else以便已经创建的片段可以放在视图层次结构的前面

Please Help, i'm stuck at this for 2 days.请帮助,我被困在这 2 天。

I would put this code in activity class, that must have FrameLayout with 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 () .注意(@developer1011):用于在活动保存状态调用commitAllowingStateLoss () Use with care, because fragment is not restored with activity restoration.小心使用,因为片段不会随着活动恢复而恢复。

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) {
        //
    }
}

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>);

JAVA:爪哇:

If you are just trying to add a Fragment without having to worry about recreating it then I think this method I have wrote to add Fragment will 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 {
        for (Fragment frag : manager.getFragments()){
          ft.hide(frag)
        }
        ft.show ( manager.findFragmentByTag ( tag ) ).commit ();
    }
}

Kotlin:科特林:

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. 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.为您的 Fragment 使用一个简单的ArrayList<Fragment> ,并按顺序添加它们,以便您知道 get(0) 将获得 F1,get(1) 将获得 F2,等等。

  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.使用静态方法创建 Fragment 并将它们添加到 ArrayList。

  4. In each Fragment add the setRetainInstance(true);在每个 Fragment 中添加setRetainInstance(true); command to the onCreate() method.命令 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.现在,当您添加的片段与FragmentManager, onCreate()才会被调用的第一次,但onCreateView()都会被调用一次。 You want to inflate the view and wire the widgets each time, just en case your Activity got recreated because of a configuration change.您希望每次都扩展视图并连接小部件,以防万一您的 Activity 由于配置更改而重新创建。 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.因此,您将需要 Fragments 中的成员变量来跟踪它们的状态。 Override onStop() to save state, and reapply it in onCreateView() after wiring up the widgets.覆盖 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()) .

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM