H5W3
当前位置:H5W3 > Andriod > 正文

【安卓】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以填充视图。

本文地址:H5W3 » 【安卓】Fragment的切换导致重叠

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址