Android fragmentTransaction.replace()方法的奇怪行为

Android fragmentTransaction.replace()方法的奇怪行为,android,android-fragments,Android,Android Fragments,我刚刚创建了一个演示,以了解FragmentTransaction的替换方法,但我并没有按照得到结果 活动和片段 public class MainActivity extends AppCompatActivity { private int count; private Fragment prevFragment; @Override protected void onCreate(Bundle savedInstanceState) {

我刚刚创建了一个演示,以了解FragmentTransaction的替换方法,但我并没有按照得到结果

活动和片段

public class MainActivity extends AppCompatActivity {

    private int count;
    private Fragment prevFragment;


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

        final Button button = (Button) findViewById(R.id.activity_main_bv_add);


        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                count++;

                final FragmentTransaction transaction = getFragmentManager().beginTransaction();
                final TestFragment fragment = new TestFragment(count);

                if (count == 1) {
                    transaction.add(R.id.activity_main_rl_container, fragment, fragment.getClass().getSimpleName());

                } else if (count == 5) {
                    transaction.replace(R.id.activity_main_rl_container, fragment, fragment.getClass().getSimpleName());
                    transaction.addToBackStack(null);
                    if (prevFragment != null) {
                        transaction.hide(prevFragment);
                    }
                } else {
                    transaction.add(R.id.activity_main_rl_container, fragment, fragment.getClass().getSimpleName());
                    transaction.addToBackStack(null);
                    if (prevFragment != null) {
                        transaction.hide(prevFragment);
                    }
                }
                prevFragment = fragment;

                transaction.commit();


            }
        });
    }

    public class TestFragment extends Fragment {
        private final String TAG = this.getClass().getSimpleName();
        private int number;


        public TestFragment(final int number) {
            this.number = number;
        }

        public TestFragment() {
        }

        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            Log.e(TAG, "onCreateView : " + number);

            final View view = inflater.inflate(R.layout.row_button, null);

            final Button button = (Button) view.findViewById(R.id.button);
            button.setText("" + number);

            return view;
        }

        @Override
        public void onDestroyView() {
            super.onDestroyView();
            Log.e(TAG, "onDestroyView : " + number);
        }
    }
}
片段xml

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:background="@color/colorPrimary"
              android:orientation="vertical">

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:focusable="false"
        android:focusableInTouchMode="false"
        />

</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/activity_currency_select"
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:descendantFocusability="blocksDescendants"
    >

    <Button
        android:id="@+id/activity_main_bv_add"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:text="Add More"/>

    <RelativeLayout
        android:id="@+id/activity_main_rl_container"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:layout_below="@id/activity_main_bv_add"
        android:layout_marginTop="20dp"
        android:background="@color/colorAccent"></RelativeLayout>


</RelativeLayout>

活动xml

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:background="@color/colorPrimary"
              android:orientation="vertical">

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:focusable="false"
        android:focusableInTouchMode="false"
        />

</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/activity_currency_select"
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:descendantFocusability="blocksDescendants"
    >

    <Button
        android:id="@+id/activity_main_bv_add"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:text="Add More"/>

    <RelativeLayout
        android:id="@+id/activity_main_rl_container"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:layout_below="@id/activity_main_bv_add"
        android:layout_marginTop="20dp"
        android:background="@color/colorAccent"></RelativeLayout>


</RelativeLayout>

碎片事务替换方法: 根据Android文档, 替换添加到容器中的现有片段。这本质上与为所有当前添加的片段调用remove(Fragment)相同,这些片段是使用相同的containerWebID添加的,然后使用此处给出的相同参数添加(int、Fragment、String)

假设情况1:使用替换方法将删除当前(最后一个和最新的)片段,并在容器视图中添加新片段

假设情况2:使用replace方法将删除添加到同一容器视图中的片段

但根据上述准则,上述案件的非证据似乎是正确的

让我们按照显示的代码点击按钮。 在每个按钮上单击,直到count==4,片段的新对象将添加到容器中

当我们单击按钮时,对于count==5,此时将使用replace方法将Fragment的新对象添加到容器中,并为第一个和第三个添加的片段调用onDestroyView方法

问题1:如果replace将删除在同一容器中添加的所有片段,那么为什么不为第二个和第四个添加的片段调用onDestroyView

问题2:如果replace方法删除了同一容器中最后添加的片段,那么为什么它不销毁第4个片段,而是销毁第1个和第3个片段

据我所知,该行为不符合上所示的文件

如果我错了,请纠正我

for (int i=0; i<mManager.mAdded.size(); i++) {    
    Fragment old = mManager.mAdded.get(i);
    if (f ==null ||old.mContainerId == f.mContainerId) {
        mManager.removeFragment(old,mTransition, mTransitionStyle);
    }
}
这意味着在使用for循环遍历ArrayList列表时使用remove


这意味着在使用for循环遍历ArrayList列表时使用remove,这似乎是
replace
方法的一个缺陷。 请注意,
FragmentManager
的支持版本不会出现这种情况

我将参考和

第一个标记为已过时,第二个标记为已分配,但两者似乎非常相关

在这两种情况下,突出显示了在
for
循环中删除片段(从ArrayList中),然后片段的ArrayList在
for
循环中更改其大小,这会导致跳过某些索引,然后删除一些(不是全部)片段

以下是链接中引用的for循环:

for (int i = 0; i < mManager.mAdded.size(); i++) {
    Fragment old = mManager.mAdded.get(i);
    // ... 
    if (f == null || old.mContainerId == f.mContainerId) {
        if (old == f) {
            op.fragment = f = null;
        } else {
            if (op.removed == null) {
                op.removed = new ArrayList<Fragment>();
            }
            op.removed.add(old);
            old.mNextAnim = op.exitAnim;
            if (mAddToBackStack) {
                old.mBackStackNesting += 1;
                if (FragmentManagerImpl.DEBUG) {
                    Log.v(TAG, "Bump nesting of "
                            + old + " to " + old.mBackStackNesting);
                }
            }
            mManager.removeFragment(old, mTransition, mTransitionStyle);
        }
    }
}
for(int i=0;i
在您的特定情况下,您将添加片段1、2、3、4。之后,当您想用第五个片段替换所有这四个片段时,将执行上面的for循环。因此,删除第一个(对应于for循环中的i=0),片段的arraylist变为2,3,4。然后在for循环中选择下一个索引(i=1),但同时arraylist发生了变化,因此获取片段3(对应于i=1)并删除它。最后,此arraylist变为2,4,i=2,并且没有与索引2对应的片段


我希望我已经帮助您理解了,即使我没有接受50分:)

这似乎是
替换方法的一个缺陷。
请注意,
FragmentManager
的支持版本不会出现这种情况

我将参考和

第一个标记为已过时,第二个标记为已分配,但两者似乎非常相关

在这两种情况下,突出显示了在
for
循环中删除片段(从ArrayList中),然后片段的ArrayList在
for
循环中更改其大小,这会导致跳过某些索引,然后删除一些(不是全部)片段

以下是链接中引用的for循环:

for (int i = 0; i < mManager.mAdded.size(); i++) {
    Fragment old = mManager.mAdded.get(i);
    // ... 
    if (f == null || old.mContainerId == f.mContainerId) {
        if (old == f) {
            op.fragment = f = null;
        } else {
            if (op.removed == null) {
                op.removed = new ArrayList<Fragment>();
            }
            op.removed.add(old);
            old.mNextAnim = op.exitAnim;
            if (mAddToBackStack) {
                old.mBackStackNesting += 1;
                if (FragmentManagerImpl.DEBUG) {
                    Log.v(TAG, "Bump nesting of "
                            + old + " to " + old.mBackStackNesting);
                }
            }
            mManager.removeFragment(old, mTransition, mTransitionStyle);
        }
    }
}
for(int i=0;i
在您的特定情况下,您将添加片段1、2、3、4。之后,当您想用第五个片段替换所有这四个片段时,将执行上面的for循环。因此,删除第一个(对应于for循环中的i=0),片段的arraylist变为2,3,4。然后在for循环中选择下一个索引(i=1),但同时arraylist发生了变化,因此获取片段3(对应于i=1)并删除它。最后,此arraylist变为2,4