Android fragmentTransaction.replace()方法的奇怪行为
我刚刚创建了一个演示,以了解FragmentTransaction的替换方法,但我并没有按照得到结果 活动和片段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) {
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