Android 将碎片带到前面(无碎片)

Android 将碎片带到前面(无碎片),android,android-fragments,android-fragmentactivity,Android,Android Fragments,Android Fragmentactivity,我有三个片段F1 F2 F3 F4都可以从侧边栏访问 所有四个都可以在任何时间以任何顺序调用 现在我想知道,如果已单击(创建)F1,则不再创建F1,而只使用片段管理器将片段F1带回到前面。所有其他片段均相同 到目前为止,我对容器中的每个片段都尝试了这个(片段活动) Ifpart确保不再重新创建片段(如果已经创建了片段),但我应该在中写些什么,以便已经创建的片段可以在视图层次结构中放在前面 请帮帮我,我已经被困在这里两天了。用标签把碎片拿出来,放在容器里 else{ Fragment existi

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

所有四个都可以在任何时间以任何顺序调用

现在我想知道,如果已单击(创建)F1,则不再创建F1,而只使用片段管理器将片段F1带回到前面。所有其他片段均相同

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

If
part确保不再重新创建片段(如果已经创建了片段),但我应该在
中写些什么,以便已经创建的片段可以在视图层次结构中放在前面


请帮帮我,我已经被困在这里两天了。

用标签把碎片拿出来,放在容器里

else{
Fragment existingFragment = (CategoriesFragment)fragmentManager.findFragmentByTag("apps");
transaction.replace(R.id.content_frame,existingFragment, "apps");
transaction.addToBackStack("apps");
transaction.commit();
}
更新: 您可以使用隐藏和显示片段来避免重新创建。而不是使用“transaction.replace()

fragmentTransaction.hide();
fragmentTransaction.show();
  • 对片段使用一个简单的
    ArrayList
    ,并按顺序添加它们,这样您就知道get(0)将得到F1,get(1)将得到F2,等等

  • 将片段创建为单例。在每个片段中添加一个静态字段和方法:

     private static Fragment mMyInstance = null;
    
     public static Fragment newInstance() {
         if (mMyInstance == null) {
             mMyInstance = new F1();
         }
         return mMyInstance;
     }
    
  • 使用静态方法创建片段并将其添加到ArrayList

  • 在每个片段中添加
    setRetainInstance(true)命令

  • 现在,当您使用FragmentManager添加片段时,
    onCreate()
    只会在第一次调用,但每次都会调用
    onCreateView()
    。您希望每次都膨胀视图并连接小部件,以防由于配置更改而重新创建活动。但是你可以检查你添加的东西,看它是否是第一次,如果不是,你可以将小部件重置为以前的状态。因此,您将需要片段中的成员变量来跟踪它们的状态。重写onStop()以保存状态,并在连接小部件后在onCreateView()中重新应用它


    然后,当按下边栏按钮时,您将获得与该按钮对应的片段,删除前面的片段,并使用FragmentManager添加当前片段(或者只使用replace()命令而不是remov()/add())。

    我将此代码放在activity类中,必须具有id为R.id.fragment\u容器的FrameLayout

    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应该为每个片段实现OnFragmentInteractionListener

    public class MainActivity extends FragmentActivity implements Fragment1.OnFragmentInteractionListener, Fragment2.OnFragmentInteractionListener, Fragment3.OnFragmentInteractionListener, Fragment4.OnFragmentInteractionListener {//..
    
        @Override
        public void onFragmentInteraction(Uri uri) {
            //
        }
    }
    

    如果您使用的是支持片段,那么这个静态方法将完成这项工作

        /**
     * 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;
    }
    
    /**
    *获取一个片段标记,并尝试在管理器中查找该片段(如果存在),然后将其放到前面。
    *如果没有,将返回false;
    *@param管理器
    *@param标签
    */
    公共静态布尔resurfaceFragment(FragmentManager,字符串标记){
    Fragment Fragment=manager.findFragmentByTag(标记);
    FragmentTransaction=manager.beginTransaction();
    if(片段!=null){
    对于(int i=0;i
    JAVA:

    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()
        }
    }
    
    如果您只是尝试添加一个
    片段
    ,而不必担心重新创建它,那么我认为我编写的添加
    片段
    的方法可以完成这项工作

    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()
        }
    }
    

    你有多少类型的片段?@Rajesh CP所有片段都是从片段类扩展而来的只有其他类型的片段ID我的答案帮助?我检查了你提供的代码,但它在视图层次结构的顶部重新创建了片段,没有带回以前创建的片段,它仍然没有用,因为当我尝试显示以前创建的线程时,代码没有效果,我做了
    Fragment existingFragment=(CategoriesFragment)fragmentManager.findffragmentbytag(“apps”);transaction.show(existingFragment)保留自己的片段数组列表被认为是一种不好的做法。为什么?考虑用户改变方向,UI将被破坏等等。你仍然会引用不存在的片段,这会导致讨厌的内存泄漏,并且在某些情况下会导致崩溃。PS:如果您使用的是supportFragmentManager,您可以使用supportFragmentManager..getFragments()轻松访问它们,并找出您想要的片段是否已经存在,或者您必须创建一个新的片段。您还可以避免内存泄漏。我建议使用设计用于片段操作的东西;)您不应该在包含UI的片段上调用` setRetainInstance(true)')。调用commit会导致java.lang.IllegalStateException:commit已被调用:(
    来自开发人员文档:-事务只能在其包含活动保存其状态之前使用此方法提交。如果在该点之后尝试提交,将引发异常。
    @developer1011:question未声明是否应在活动还原时还原状态。来自文档:commitAllowingStateLoss()类似于commit(),但允许在保存活动状态后执行提交。注意:请小心使用!fragmentManager.getFragments()发出警告,它只能从同一库组中调用,还需要隐藏其他片段,否则show看起来无法工作
    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()
        }
    }