为什么我的 Fragment 没有替换我的 Activity 布局?
当我从 NavigationDrawer
中选择一个项目并添加一个带有 FragmentTransaction
的新 Fragment
时,它不会替换 FragmentTransaction
的布局code>Activity 我不知道为什么!
When I pick an item from the NavigationDrawer
and add a new Fragment
with a FragmentTransaction
it doesn't replace the layout of the Activity
and I cannot figure out why!
这是我的Activity
的布局:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/content_frame"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:layout_width="match_parent"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" >
<!-- The main content view -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Location:"
android:layout_marginTop="10dp"
android:id="@+id/tv_disploc"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Temperature:"
android:id="@+id/tv_disptemp"
android:layout_below="@+id/tv_disploc"
android:layout_marginTop="44dp" />
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Search"
android:onClick="ButtonClick"
android:id="@+id/btn_search"
android:layout_below="@+id/et_inloc"
android:layout_centerHorizontal="true"
android:layout_marginTop="37dp"
android:layout_gravity="center" />
<EditText
android:layout_width="174dp"
android:layout_height="wrap_content"
android:id="@+id/et_inloc"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/tv_dispsearch"
android:layout_gravity="center" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Search:"
android:id="@+id/tv_dispsearch"
android:layout_centerVertical="true"
android:layout_gravity="left|center_vertical" />
<EditText
android:layout_width="126dp"
android:layout_height="wrap_content"
android:id="@+id/et_outtemp"
android:layout_below="@+id/et_outloc"
android:layout_toRightOf="@+id/tv_disptemp"
android:layout_marginTop="30dp"
android:layout_marginLeft="30dp"
android:clickable="false"
android:cursorVisible="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:layout_gravity="center_horizontal|top" />
<EditText
android:layout_width="135dp"
android:layout_height="wrap_content"
android:id="@+id/et_outloc"
android:layout_toRightOf="@+id/tv_disploc"
android:layout_marginLeft="30dp"
android:clickable="false"
android:cursorVisible="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:layout_gravity="center_horizontal|top" />
</FrameLayout>
<!-- The navigation drawer -->
<ListView android:id="@+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:background="#111"/>
</android.support.v4.widget.DrawerLayout>
这是我想要显示的Fragment
:
<LinearLayout
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:id="@+id/fragment_option"
android:orientation="vertical"
android:fitsSystemWindows="true"
android:minWidth="1000dp"
android:minHeight="1000dp">
android:weightSum="1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Select your Default Location"
android:layout_marginTop="100dp"
android:layout_gravity="center_horizontal"
android:id="@+id/textView" />
<Spinner
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/spinner_locations"
android:layout_gravity="center_horizontal" />
</LinearLayout>
谁能告诉我我在这里遗漏了什么?
Can anybody tell me what I am missing here?
我认为您可能对活动和片段有一些误解.一般规则是:
I think you might have a few misconceptions about Activities and Fragments. The general rule is:
在 Fragment 中构建您的用户界面(在大多数情况下,一个 Fragment
等于一个屏幕),然后使用活动来安排和显示那些片段.
Build your user interface in Fragments (In most cases one
Fragment
equals one screen) and then use Activities to arrange and display those Fragments.
带有 NavigationDrawer
的典型 Activity
布局如下所示:
A typical Activity
layout with NavigationDrawer
would look like this:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The main content view -->
<!-- This is the placeholder for your Fragments -->
<!-- You can display your Fragments here with FragmentTransactions -->
<FrameLayout
android:id="@+id/flFragmentPlaceHolder"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- The navigation drawer -->
<!-- It would even be better practice to use a Fragment here as well -->
<!-- But since the Google Tutorials just use a ListView here I will as well -->
<ListView android:id="@+id/lvDrawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:background="#111"/>
</android.support.v4.widget.DrawerLayout>
除了 Fragments 的占位符和 NavigationDrawer
的必要部分之外,没有其他东西应该在该布局中.如果您在当前状态下在 Activity
中使用该布局,除了可以从左侧拉入的 NavigationDrawer
之外,它基本上会显示一个空屏幕.您构建的任何用户界面稍后都会通过 Fragments 添加.
Nothing else besides the placeholder for the Fragments and the necessary parts of the NavigationDrawer
are supposed to be in that layout. If you would use that layout in an Activity
in its current state it would essentially display an empty screen besides the NavigationDrawer
which can be pulled in from the left. Any user interface you build will be added later on through Fragments.
要在该布局中显示 Fragment
,您必须执行 FragmentTransaction
.您可以在一个 FragmentTransaction
中添加、替换、删除、显示或隐藏多个 Fragment
.在上面的示例中,您可能希望向用户显示包含启动屏幕的 Fragment
.要做到这一点,您可以像这样执行 FragmentTransaction
:
To display a Fragment
in that layout you have to perform a FragmentTransaction
. You can add, replace, remove, show or hide multiple Fragments
in one single FragmentTransaction
. In the example above you might want to display the Fragment
which contains your startup screen to the user. To do that you would perform a FragmentTransaction
like this:
// It is best practice to use factory methods to create Fragment instances
final Fragment fragment = StartupFragment.newInstance();
// There are multiple `FragmentManagers`, be sure to always use the right one!
FragmentManager manager = getFragmentManager();
// This starts the `FragmentTransaction`.
FragmentTransaction transaction = manager.beginTransaction();
// Now you can define what happens in this transactions
// You can add/replace/remove/hide or show as many Fragments
// as you want in one `FragmentTransaction`.
// This command specifically adds the Fragment to the placeholder we defined
// in the layout of the Activity
transaction.replace(R.id.flFragmentPlaceHolder, fragment);
// This commits the `FragmentTransaction`.
// Only after you call this will any changes be made
transaction.commit();
为简洁起见,与上面相同的代码也可以写成:
For brevity the same code as above can also be written as:
final Fragment fragment = StartupFragment.newInstance();
getFragmentManager().beginTransaction()
.replace(R.id.flFragmentPlaceHolder, fragment)
.commit();
这样编写的主要改进在于,您作为开发人员可以更快地编写它很多,因为您几乎可以一直依赖代码完成.
The main improvement of writing it like this is that you as a developer can write it a lot faster since you can rely on code completion almost the whole time.
如果稍后用户从 NavigationDrawer
中选择了一个项目,那么您只需要执行一个新的 FragmentTransaction
以将 StartupFragment
替换为不一样的!
If later on the user picks an item from the NavigationDrawer
then you just have to perform a new FragmentTransaction
to replace the StartupFragment
with a different one!