【安卓】Fragment的切换导致重叠

刚接触fragment,之前在书上看的时候,由于它当时是加上了背景颜色,所以在切换的时候我没有去注意到重叠的问题。然后最近在做一个项目的时候用到fragment,才发现了这个问题。

我用RadioGroup里的RadioButton来做切换

package com.moke.activity;

public class CJD_CardPackageActivity extends Activity implements OnCheckedChangeListener {

private RadioGroup radipGroup;

@Override

protected void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_NO_TITLE);

setContentView(R.layout.cjd_cardpackageactivity);

init();

}

private void init() {

radipGroup = (RadioGroup)findViewById(R.id.cjd_CardPackageActivity_rgp);

bindClick();

}

private void bindClick(){

radipGroup.setOnCheckedChangeListener(this);

}

@Override

public void onCheckedChanged(RadioGroup group, int checkedId) {

// TODO Auto-generated method stub

CJD_Fragment_CardPackageUnused unusedFragment = new CJD_Fragment_CardPackageUnused();

CJD_Fragment_CardPackageUsed usedFragment = new CJD_Fragment_CardPackageUsed();

FragmentManager fragmentManager = getFragmentManager();

FragmentTransaction transaction = fragmentManager.beginTransaction();

switch (checkedId) {

//切换到未使用页面

case R.id.cjd_CardPackageActivity_rbtn_unused:

transaction.replace(R.id.cjd_CardPackageActivity_fl_switch, unusedFragment);

transaction.commit();

break;

//切换到使用页面

case R.id.cjd_CardPackageActivity_rbtn_used:

transaction.replace(R.id.cjd_CardPackageActivity_fl_switch, usedFragment);

transaction.commit();

break;

default:

break;

}

}

}

布局文件的代码cjd_cardpackageactivity.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:orientation="vertical" >

<RadioGroup

android:id="@+id/cjd_CardPackageActivity_rgp"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="horizontal">

<RadioButton

android:id="@+id/cjd_CardPackageActivity_rbtn_unused"

style="@style/radioButtonInTop"

android:text="@string/unused"

android:checked="true"/>

<RadioButton

android:id="@+id/cjd_CardPackageActivity_rbtn_used"

style="@style/radioButtonInTop"

android:text="@string/used"/>

</RadioGroup>

<FrameLayout

android:id="@+id/cjd_CardPackageActivity_fl_switch"

android:layout_width="match_parent"

android:layout_height="match_parent">

<fragment

android:layout_width="match_parent"

android:layout_height="match_parent"

android:name="com.moke.fragment.CJD_Fragment_CardPackageUnused"/>

</FrameLayout>

</LinearLayout>

一开始“未使用”的界面:
【安卓】Fragment的切换导致重叠

切换到“已使用”界面
【安卓】Fragment的切换导致重叠

切换回“未使用”界面并向下活动:
【安卓】Fragment的切换导致重叠

这样就发现新的重叠在了原来的Fragment上,当然原来的Fragment是固定不动的,还保留着当时的位置。

这是修改后的代码,目前从效果上看已经没有了重叠的现象了,非常感谢“li21”!!

public class CJD_CardPackageActivity extends Activity implements OnCheckedChangeListener {

private RadioGroup radipGroup;

private FragmentTransaction transaction;

private CJD_Fragment_CardPackageUnused unusedFragment;

private CJD_Fragment_CardPackageUsed usedFragment;

private FragmentManager fragmentManager;

@Override

protected void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_NO_TITLE);

setContentView(R.layout.cjd_cardpackageactivity);

init();

}

private void init() {

radipGroup = (RadioGroup)findViewById(R.id.cjd_CardPackageActivity_rgp);

unusedFragment = new CJD_Fragment_CardPackageUnused();

usedFragment = new CJD_Fragment_CardPackageUsed();

fragmentManager = getFragmentManager();

// unusedFragment = (CJD_Fragment_CardPackageUnused) getFragmentManager().findFragmentByTag("unused");

// usedFragment = (CJD_Fragment_CardPackageUsed) getFragmentManager().findFragmentByTag("used");

transaction = fragmentManager.beginTransaction();

transaction.add(R.id.cjd_CardPackageActivity_fl_switch, unusedFragment).commit();

bindClick();

}

private void bindClick(){

radipGroup.setOnCheckedChangeListener(this);

}

@Override

public void onCheckedChanged(RadioGroup group, int checkedId) {

// TODO Auto-generated method stub

switch (checkedId) {

//切换到未使用页面

case R.id.cjd_CardPackageActivity_rbtn_unused:

transaction = fragmentManager.beginTransaction();

transaction.replace(R.id.cjd_CardPackageActivity_fl_switch, unusedFragment);

transaction.commit();

break;

//切换到使用页面

case R.id.cjd_CardPackageActivity_rbtn_used:

transaction = fragmentManager.beginTransaction();

transaction.replace(R.id.cjd_CardPackageActivity_fl_switch, usedFragment);

transaction.commit();

break;

default:

break;

}

}

}

我把布局里的fragment删掉了,然后在一开始的时候把unusedFragment add上去。接下来的工作应该是我要去试一下fragment的切换过程中会不会重新加载这样的问题,找到了一些有关hide()和show()的东西。

回答

只从你贴出来的这段代码看,并不会造成重叠。所以我猜是你的其它代码造成的问题,根据我的测试情况,有两种可能:

可能1. 在你的布局文件内,存在一个组件,和你的R.id.cjd_CardPackageActivity_fl_switch 占据同样的位置。并且有代码向其中添加了usedFragment:ft.add或者replace(R.id.*, usedFragment);
因为资源ID会告诉FragmentManager fragment视图应该出现在activity视图的哪个位置。所以,如果先向其中一个ID添加了Fragment,然后又向另一个ID添加了Fragment,就会导致重叠。

可能2. 如果你贴出来的代码是位于Fragment中的代码(也就是说你是通过Fragment管理的这两个Fragment),在onCheckedChanged()方法以外,是不是也添加过Fragment?比如在onCreateView()中,先add了一个usedFragment,并且是通过getChildFragmentManager()获取的FragmentManager。
而你后面又是通过getFragmentManager()管理的Fragment,此时replace无法替换掉之前add的fragment,就导致了重叠。

我目前就测试到这两种情况会导致重叠。

如果上述列举的两种都不是造成你问题的原因,那么临时的解决办法是,加背景色;或者,参考这个答案的办法 http://segmentfault.com/q/1010000003731705/a-1020000003738254
在replace之前,先remove所有的子Fragment:

    if (fm.getFragments() != null && fm.getFragments().size() > 0) {

for (Fragment cf : fm.getFragments()) {

ft.remove(cf);

}

}

Update1

添加fragment到activity布局中,就等同于将fragment及其视图与activity的视图绑定在一起,且在activity的生命周期过程中,无法切换fragment视图。 《Android权威编程指南 the big nerd ranch guide 7.4.2》

所以把Layout中的fragment去掉就可以了,问题的原因在『可能1』 中给出了解释。

  <fragment 

android:layout_width="match_parent"

android:layout_height="match_parent"

android:name="com.moke.fragment.CJD_Fragment_CardPackageUnused"/>

Update2 开始就没有默认显示“未使用”界面,而是要进行切换操作后才显示,要怎么处理?

在初始化的地方,add一个fragment以填充视图。

以上是 【安卓】Fragment的切换导致重叠 的全部内容, 来源链接: utcz.com/a/97976.html

回到顶部