在 FragmentManager 中更改片段
Posted
技术标签:
【中文标题】在 FragmentManager 中更改片段【英文标题】:Issue changing fragment in FragmentManager 【发布时间】:2016-04-04 08:50:24 【问题描述】:New Layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/RelativeLayout1"
android:layout_
android:layout_ >
<FrameLayout
android:layout_
android:layout_
android:layout_above="@+id/L1" >
<fragment
android:id="@+id/fragment_place"
android:name="com.javacodegeeks.android.fragmentstest.HomeFrag"
android:layout_
android:layout_ />
</FrameLayout>
<RelativeLayout
android:id="@+id/L1"
android:layout_
android:layout_
android:layout_alignParentBottom="true" >
<ImageView
android:id="@+id/button1"
android:layout_
android:layout_
android:src="@drawable/home"
android:onClick="selectFrag"
android:layout_alignParentLeft="true"/>
<ImageView
android:id="@+id/button2"
android:layout_
android:layout_
android:src="@drawable/search"
android:onClick="selectFrag"
android:layout_toRightOf="@+id/button1"/>
<ImageView
android:id="@+id/button3"
android:layout_
android:layout_
android:src="@drawable/map"
android:onClick="selectFrag"
android:layout_toRightOf="@+id/button2"/>
</RelativeLayout>
</RelativeLayout>
我正在学习使用 FragmentManager 在 ImageView 单击上更改片段。当我单击第一个 imageView 时,带有文本“home”的主要片段布局显示良好。但是当点击其他ImageViews改变fragment页面时,它会更改为新的fragment页面,但不会删除之前的页面。结果,上一页与新页混在一起。 It look like this. 截图显示主页,文本为“home”,即上一页,新页面,文本为“search”。点击新的ImageView时如何删除上一页?
MainActivity
public class MainActivity extends Activity
private static final int RESULT_SETTINGS = 1;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.demo);
public void selectFrag(View view)
Fragment fr = null;
if(view == findViewById(R.id.button1))
fr = new HomeFrag();
else if(view == findViewById(R.id.button2))
fr = new SearchFrag();
else if(view == findViewById(R.id.button3))
fr = new MapFrag();
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.fragment_place, fr);
fragmentTransaction.commit();
【问题讨论】:
在框架布局中使用片段阅读此answer 【参考方案1】:作为Android guide on starting fragments says 当您希望片段更改时,您不要在布局文件中使用fragment
元素。你应该使用一些布局,例如FrameLayout
如果您计划在活动的生命周期内更改片段,这是必要的。
我认为这是导致您的问题的原因。
您的新 XML 布局很接近,但我的意思是完全不使用 <fragment>
。
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_place"
android:layout_
android:layout_>
</FrameLayout>
然后代码本身还有更多工作要做,因为您需要在首次创建 UI 时创建/附加“home”片段。
在你的public void onCreate(Bundle savedInstanceState)
中
添加它以创建/附加第一个“home”片段。
if (findViewById(R.id.fragment_place) != null)
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
if (savedInstanceState != null)
return;
// Create a new Fragment to be placed in the activity layout
HomeFrag firstFragment = new HomeFrag();
// In case this activity was started with special instructions from an
// Intent, pass the Intent's extras to the fragment as arguments
// firstFragment.setArguments(getIntent().getExtras());
// I commented this out since you don't appear to need it right now.
// Add the fragment to the 'fragment_container' FrameLayout
getFragmentManager().beginTransaction()
.add(R.id.fragment_container, firstFragment).commit();
【讨论】:
***.com/a/17495250/2801237 这里很好地解释了为什么你应该使用 framelayout。 我添加了 FrameLayout 并在其中插入了片段,但问题仍然存在。我在帖子中编辑了布局代码。 @mawalker 非常感谢。它工作得很好。 @mawalker。【参考方案2】:用框架布局包装。试试这个xml
说明here
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/RelativeLayout1"
android:layout_
android:layout_ >
<Framelayout
android:layout_
android:layout_>
<fragment
android:id="@+id/fragment_place"
android:name="com.javacodegeeks.android.fragmentstest.HomeFrag"
android:layout_
android:layout_
android:layout_above="@+id/L1" />
</framelayout>
<RelativeLayout
android:id="@+id/L1"
android:layout_
android:layout_
android:layout_alignParentBottom="true" >
<ImageView
android:id="@+id/button1"
android:layout_
android:layout_
android:src="@drawable/home"
android:onClick="selectFrag"
android:layout_alignParentLeft="true"/>
<ImageView
android:id="@+id/button2"
android:layout_
android:layout_
android:src="@drawable/search"
android:onClick="selectFrag"
android:layout_toRightOf="@+id/button1"/>
<ImageView
android:id="@+id/button3"
android:layout_
android:layout_
android:src="@drawable/map"
android:onClick="selectFrag"
android:layout_toRightOf="@+id/button2"/>
</RelativeLayout>
【讨论】:
我将根布局更改为框架布局,但仍然不好。 @Zeeshan【参考方案3】:试试这个代码 sn-p 会起作用
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_place);
if(currentFragment!=null)
fragmentTransaction.remove()
else
fragmentTransaction.add(R.id.fragment_place, fr);
`enter code here`
fragmentTransaction.commit();
【讨论】:
以上是关于在 FragmentManager 中更改片段的主要内容,如果未能解决你的问题,请参考以下文章
FragmentManager popBackStack 不删除片段
Android - 通过 FragmentManager 替换片段后,片段返回到它们的第一个状态
在 FragmentManager 中管理 BackStackEntries
使用 (Child)FragmentManager 正确使用子子片段