【发布时间】:2017-02-08 06:12:27
【问题描述】:
我刚刚创建了一个演示来了解 FragmentTransaction 的替换方法,但我没有得到 Developer Guide 的结果。
活动和片段
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
<?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>
FragmentTransaction 替换方法: 根据 Android 文档, 替换已添加到容器中的现有片段。这本质上与为所有当前添加的片段调用 remove(Fragment) 相同,这些片段使用相同的 containerViewId 添加,然后使用此处给出的相同参数调用 add(int, Fragment, String)。
假设案例 1:使用 replace 方法将删除当前(最后一个和最新)片段并在容器视图中添加新片段。
假设案例 2:使用 replace 方法将删除添加添加到同一容器视图中的片段。
但根据上面的代码,上述情况似乎不是正确的。
让我们按照显示的代码单击按钮。 每次点击按钮直到 count == 4,Fragment 的新对象将被添加到容器中。
当我们点击按钮时,count == 5,此时使用replace方法将Fragment的新对象添加到容器中,并为第1个和第3个添加的片段调用onDestroyView方法
问题1:如果replace会删除所有添加到同一个容器中的片段,那么为什么不为第二个和第四个添加的片段调用onDestroyView?
问题 2: 如果 replace 方法删除了同一容器中最后添加的片段,那么为什么它不销毁第 4 个片段而是第 1 和第 3 个片段?
据我了解,该行为不符合Developer site 上显示的文档。
如果我错了,请纠正我。
【问题讨论】:
-
在github上分享完整的demo项目。