Android 在单个 Activity 中的 Fragment 之间切换
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11217551/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Switching between Fragments in a single Activity
提问by nhaarman
I want to create an Activity
which shows a sort of menu a user can go through. By clicking an item, a new screen is shown, allowing the user more options (wizard-like).
我想创建一个Activity
显示用户可以浏览的菜单。通过单击一个项目,会显示一个新屏幕,为用户提供更多选项(类似向导)。
I wanted to implement this using Fragment
s, but it's not working for me.
Right now I have:
我想使用Fragment
s来实现它,但它对我不起作用。
现在我有:
main.xml
:
main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:id="@+id/main_fragmentcontainer" >
<fragment
android:id="@+id/mainmenufragment"
android:name="com.myapp.MainMenuFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<fragment
android:id="@+id/secondmenufragment"
android:name="com.myapp.SecondMenuFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
MainMenuFragment
with an OnClickListener
:
MainMenuFragment
与OnClickListener
:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.mainmenu, container, false);
setupButton(view);
return view;
}
/* Button setup code omitted */
@Override
public void onClick(View v) {
SherlockFragment secondRunMenuFragment = (SherlockFragment) getSherlockActivity().getSupportFragmentManager().findFragmentById(R.id.secondmenufragment);
FragmentTransaction transaction = getSherlockActivity().getSupportFragmentManager().beginTransaction();
transaction.replace(android.R.id.content, secondMenuFragment); //also crashes with R.id.main_fragmentcontainer
transaction.addToBackStack(null);
transaction.commit();
}
Now when I press the button, the application crashes with this logcat:
现在,当我按下按钮时,应用程序会因为这个 logcat 崩溃:
06-27 01:45:26.309: E/AndroidRuntime(8747): java.lang.IllegalStateException: Can't change container ID of fragment SecondMenuFragment{405e2a70 #1 id=0x7f060029}: was 2131099689 now 2131099687
06-27 01:45:26.309: E/AndroidRuntime(8747): at android.support.v4.app.BackStackRecord.doAddOp(Unknown Source)
06-27 01:45:26.309: E/AndroidRuntime(8747): at android.support.v4.app.BackStackRecord.replace(Unknown Source)
06-27 01:45:26.309: E/AndroidRuntime(8747): at android.support.v4.app.BackStackRecord.replace(Unknown Source)
06-27 01:45:26.309: E/AndroidRuntime(8747): at com.myapp.MainMenuFragment$MyButtonOnClickListener.onClick(MainMenuFragment.java:52)
06-27 01:45:26.309:E / AndroidRuntime(8747):java.lang.IllegalStateException:不能改变片段SecondMenuFragment {405e2a70#1的id = 0x7f060029}的容器ID:为2131099689现在2131099687
06-27 1时45分:26.309: E/AndroidRuntime(8747): at android.support.v4.app.BackStackRecord.doAddOp(Unknown Source)
06-27 01:45:26.309: E/AndroidRuntime(8747): at android.support.v4.app .BackStackRecord.replace(Unknown Source)
06-27 01:45:26.309: E/AndroidRuntime(8747): at android.support.v4.app.BackStackRecord.replace(Unknown Source)
06-27 01:45:26.309: E /AndroidRuntime(8747): 在 com.myapp.MainMenuFragment$MyButtonOnClickListener.onClick(MainMenuFragment.java:52)
What am I doing wrong?
我究竟做错了什么?
回答by Josep Escobar
I create this main layout:
我创建了这个主要布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context="com.example.fragmentsexample.MainActivity" >
<FrameLayout
android:id="@+id/contentFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" />
</LinearLayout>
And i replenished in the FrameActivity with:
我在 FrameActivity 中补充了:
@Override
public void onCreate(Bundle savedInstanceState) {
...
Fragment fragment = new Dashboard();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.replace(R.id.contentFragment, fragment);
transaction.commit();
...
}
And I repleace on onClick Method with the same code, cahnging Fragment (Dashboard for Events):
我用相同的代码替换 onClick 方法,更改片段(事件仪表板):
@Override
public void onClick.... {
...
Fragment fragment = new Events();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.replace(R.id.contentFragment, fragment); //Container -> R.id.contentFragment
transaction.commit();
...
}
回答by CommonsWare
Personally, I would not have any <fragment>
elements.
就个人而言,我不会有任何<fragment>
元素。
Step #1: Populate your activity layout with a <FrameLayout>
for the variable piece of the wizard, plus your various buttons.
第 1 步:使用<FrameLayout>
向导的可变部分以及各种按钮填充您的活动布局。
Step #2: In onCreate()
of the activity, run a FragmentTransaction
to load the first wizard page into the FrameLayout
.
第 2 步:在onCreate()
活动中,运行 aFragmentTransaction
将第一个向导页面加载到FrameLayout
.
Step #3: On the "next" click, run a FragmentTransaction
to replace the contents of the FrameLayout
with the next page of the wizard.
第 3 步:在“下一步”单击时,运行 aFragmentTransaction
以将 的内容替换FrameLayout
为向导的下一页。
Step #4: Add in the appropriate smarts for disabling the buttons when they are unusable (e.g., back on the first wizard page).
第 4 步:添加适当的智能以在按钮不可用时禁用它们(例如,回到第一个向导页面)。
Also, you will want to think about how the BACK button should work in conjunction with any on-screen "back" button in the wizard. If you want them to both behave identically, you will need to add each transaction to the back stack and pop stuff off the back stack when you handle the "back" button.
此外,您还需要考虑后退按钮如何与向导中的任何屏幕上的“后退”按钮一起工作。如果您希望它们的行为相同,则需要将每个事务添加到后退堆栈,并在您处理“后退”按钮时从后退堆栈中弹出内容。
Someday, if nobody beats me to it, I'll try to create a wizard-by-way-of-fragments example, or perhaps a reusable component.
总有一天,如果没有人打败我,我会尝试创建一个向导式片段示例,或者一个可重用的组件。
回答by LordRaydenMK
Another option is to use the Android-WizardPagerby Roman Nurik.
另一种选择是使用Roman Nurik的Android-WizardPager。
Key features:
主要特点:
- Branching, or the ability for wizard steps to influence the availability of later steps
- Allowing the user to review before committing
- Allowing the user freeform navigation between wizard steps
- Support for required and optional steps
- Support for step classes (technically, each step is an instance of a Java class, so you can have multiple instances within the wizard)
- 分支,或向导步骤影响后续步骤可用性的能力
- 允许用户在提交前查看
- 允许用户在向导步骤之间自由导航
- 支持必需和可选步骤
- 支持步骤类(从技术上讲,每个步骤都是 Java 类的一个实例,因此您可以在向导中拥有多个实例)
More info here.
更多信息在这里。