【问题标题】:removed fragment still visible删除的片段仍然可见
【发布时间】:2016-01-04 09:12:46
【问题描述】:

我正在开发一个自助服务终端应用程序,以便它接管平板电脑。带有一堆不同片段的单个活动。我在活动的 oncreate 中提交了一个片段。然后,当设备连接到蓝牙时,它将通过删除旧片段并添加新片段来加载新片段(调用函数 cancelFunc())。我遇到的问题是第一个片段在移除后仍然可见。我的日志显示它实际上已被删除,而是附加了一个新片段,但我看不到新片段或稍后附加的任何其他片段。但是,当我点击屏幕时,它会显示新片段。有点奇怪,我想知道我做错了什么。它只发生在活动的 oncreate 附加的片段上。代码相当长,所以我只向您展示几个重要部分。提前感谢您的帮助。

@Override
protected void onCreate(Bundle savedInstanceState) {
    Log.d(TAG, "onCreate()");
    super.onCreate(savedInstanceState);
    setContentView(R.layout.backbone);

    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
    ft.add(R.id.fragmentContainer, new SystemDownFragment(), "SystemDownFragment");
    ft.commit();

    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

    // If the adapter is null, then Bluetooth is not supported
    if (mBluetoothAdapter == null) {
        Log.d(TAG, "adapter is null");
        Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
        finish();
    }

    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_FULLSCREEN
            | View.SYSTEM_UI_FLAG_IMMERSIVE);
}

public void cancelFunc() {
    Log.d(TAG, "cancelFunc()");

    removeFrag();

    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
    ft.add(R.id.fragmentContainer, new StartupFragment(), "StartupFragment");
    ft.commit();
    getFragmentManager().executePendingTransactions();
}

private void removeFrag(){
    Log.d(TAG, "removeFrag()" + getActiveFragments().size());
    if(getActiveFragments().size() > 0) {
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        for (int i = 0; i < getActiveFragments().size(); i++) {
            ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE);
            ft.remove(getActiveFragments().get(i));
        }
        ft.commit();
    }
}

@Override
public void onAttachFragment (Fragment fragment) {
    Log.d(TAG, "onAttachFragment");
    fragList.add(new WeakReference(fragment));
}

public List<Fragment> getActiveFragments() {
    ArrayList<Fragment> ret = new ArrayList<Fragment>();
    for(WeakReference<Fragment> ref : fragList) {
        Fragment f = ref.get();
        if(f != null) {
            if(f.isVisible()) {
                ret.add(f);
            }
        }
    }
    return ret;
}

我记录的数据显示如下:

MainActivity: onCreate()
MainActivity: onAttachFragment
MainActivity: onStart()
MainActivity: onResume()
MainActivity: Bluetooth Connected
MainActivity: cancelFunc()
MainActivity: removeFrag()1
MainActivity: onAttachFragment

【问题讨论】:

  • 你能看到新片段吗?
  • 使用 ft.replace(R.id.fragmentContainer, new StartupFragment(), "StartupFragment");而不是 ft.add();
  • 在点击屏幕之前我看不到新片段。之后,它变得可见。对于我在整个代码中添加和删除的每个其他片段,这都没有问题。但是,活动 onCreate() 中的第一个片段存在问题。而且我一直在努力避免替换,因为我通常会同时连接一两个片段,而且我更容易在必要时将它们全部删除并添加新片段。

标签: android android-fragments


【解决方案1】:

清除或移除当前fragment中的所有view,然后在Layout中替换新的fragment。

喜欢这个,试试这个

myLayout.removeAllViews();

AddNewFragment new = new AddNewFragment();

this.getFragmentManager().beginTransaction().replace(R.id.fragment_mainLayout, new, "").addToBackStack(null).commit();

【讨论】:

  • 这实际上可能是它。我今晚试试这个,然后回复你。谢谢。
  • 欢迎您。 :) 如果真的对您有帮助,请接受我的回答。
【解决方案2】:

为了移除fragment,你只需要调用activity的onBackPressed()方法,因为这个方法执行返回操作,所以它会从activity中移除你当前的fragment,然后你可以添加另一个。所以用下面的代码更新你的 removefrag() 方法。

试试这个,

void removeFrag(){
   onBackPresssed();
}

【讨论】:

  • 这并没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方留下评论。 - From Review
  • @MuhammedRefaat:他要求删除片段,我提到了执行相同操作的代码.. 答案有什么问题?
  • 没有错,但有一些不便之处,因为在 SO 中,所有没有澄清的答案都被删除,因为社区的目的是获得知识而不仅仅是解决问题,所以请解释为什么你的代码正在解决他的问题,因为这会给他带来好处,其他任何人都可以看到你的答案。
  • 感谢您提供信息。我已经更新了我的答案,现在我澄清了为什么我的代码可以工作.. 再次感谢 :)
  • 为了使后台工作正常,那么片段必须在后台堆栈上,对吧?所以我必须在提交片段之前调用 addToBackStack(null) 。到目前为止,我一直在避免向 backstack 添加任何东西,因为我的应用程序使用了一堆不同的片段,而且我更容易在 backstack 上没有任何东西,只需将它们全部删除,然后添加新的。
【解决方案3】:

它可能会解决你的问题,但它也是你想做的好习惯;在您的 FragmentTransaction 上使用 ft.replace(...) 而不是添加和删除...

【讨论】:

  • 您能解释一下为什么这是一个好的做法吗?我的应用同时显示了多个片段,我发现删除所有片段并显示新片段对我来说更容易。
【解决方案4】:

您必须在该活动中按回时替换新片段。

 public void onBackPressed() {
        ft.replace(R.id.fragment_container, new_fragment);
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        ft.commit();

}

【讨论】:

  • 这是一个自助服务终端应用程序。它完全接管了应用程序,我们隐藏了后退按钮。所以我不能依赖BackPressed()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-14
  • 1970-01-01
  • 2013-05-24
  • 1970-01-01
  • 2021-08-03
  • 1970-01-01
  • 2013-05-22
相关资源
最近更新 更多