Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/221.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android “的具体原因”;片段重叠;?_Android_Android Fragments - Fatal编程技术网

Android “的具体原因”;片段重叠;?

Android “的具体原因”;片段重叠;?,android,android-fragments,Android,Android Fragments,我还没有找到一个问题的答案,详细说明了为什么在Android运行时出现这个问题。有人能解释一下吗?我对缓解此问题的方法不感兴趣(例如设置fragment的根视图背景色),但希望得到发生原因的具体解释 (我正在使用v4支持FragmentManager、FragmentTransaction和FragmentAPI) 我有一个由FrameLayout(R.id.fragment_容器)和BottomNavigationView组成的活动 最初在活动中,我向FrameLayout添加了一个片段实例:

我还没有找到一个问题的答案,详细说明了为什么在Android运行时出现这个问题。有人能解释一下吗?我对缓解此问题的方法不感兴趣(例如设置fragment的根视图背景色),但希望得到发生原因的具体解释

(我正在使用v4支持FragmentManager、FragmentTransaction和FragmentAPI)

我有一个由FrameLayout(R.id.fragment_容器)和BottomNavigationView组成的活动

最初在活动中,我向FrameLayout添加了一个片段实例:

FragmentTransaction transaction = 
getSupportFragmentManager().beginTransaction();
transaction.add(R.id.fragment_container, donsListFragment);
transaction.commit();
donsListFragment(my
DonationsListFragment.class
的一个实例)显示一条消息(“当前没有捐赠”)和一个刷新指示器(使用SwipeRefreshLayout)(参见第一个屏幕截图),直到它从web服务检索到数据为止(参见第二个屏幕截图)。我使用
DonationsListFragment.class
中的实例成员保存从web服务检索的数据,并通过数据绑定框架控制消息和RecyclerView(用于显示列表)的可见性

如果用户点击BottomNavigationView(“Schedule”,例如)中的项目,则以下代码将FrameLayout中的片段替换为与用户选择相对应的片段(
frag
):

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.fragment_container, frag);
        transaction.commit();
有时,在这种情况下,会出现“片段重叠”(我自己的术语:)),请参见下面的第三个屏幕截图(“目前没有捐赠”。
donsListFragment
的消息仍然可见(在屏幕截图中加下划线)即使之前的代码应该已经用计划片段完全替换了
donsListFragment
):

这里到底发生了什么事

我在活动中覆盖
onNavigationItemSelected(MenuItem)
时处理用户点击BottomNavigationView(它实现了BottomNavigationView.OnNavigationItemSelectedListener):

我的
displayFragment(Fragment)
方法定义如下:

    private void displayFragment(Fragment frag) {
            // update title in app bar accordingly
            appBarTitleTV.setText(fragTitles.get(frag.getClass()));

            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            transaction.replace(R.id.fragment_container, frag);
transaction.commit();
        }
您将从前面的
switch
语句中看到,我使用刷新事件对象的粘性post在
DonationsListFragment
onResume()中触发刷新。以下是捐赠的片段
onResume()

我的
refresh()
方法在包装片段布局的SwipeRefreshLayout上调用
setRefresh(true)
之前启动一个异步web服务调用(使用基于web客户端)。底层web客户端回调处理代码通过GreenRobot事件总线将从服务器检索到的捐赠发送回
DonationsListFragment

public void refreshDonations() {
        apiClient.donationCurrentDonations();
        refreshLayout.setRefreshing(true);
    }

使用
transaction.replace(R.id.fragment\u容器,donsListFragment)
而不是
transaction.add(R.id.fragment\u容器,donsListFragment)

使用
事务。替换(R.id.fragment\u容器,donsListFragment)
而不是
transaction.add(R.id.fragment\u容器,donsListFragment)

原因

这里的问题是
.replace()
的行为与您预期的不一样

在这个场景中,您从名为
fragment\u容器的
FrameLayout
开始

调用
transaction.add(R.id.fragment\u容器,donsListFragment)时向“活动状态”添加新视图

i、 e.您现在有2个视图(
R.id.fragment\u容器
donsListFragment
的视图),而之前只有1个视图(仅
R.id.fragment\u容器

但是,当您在容器视图上调用
.replace()
时,
R.id.fragment\u container
,它不会删除先前添加的视图

i、 e.您仍将有2个视图(
donsListFragment
的视图和
frag
的视图)。这会导致重叠

解决方案

有两种可能的解决方案:


  • 使用
    transaction.replace()
    donsListFragment
    插入(大概)初始
    FragmentTransaction

  • 当导航到不同的
    片段时,调用
    .remove()
    for
    donsFragment
    作为
    片段事务的一部分

  • 原因

    这里的问题是
    .replace()
    的行为与您预期的不一样

    在这个场景中,您从名为
    fragment\u容器的
    FrameLayout
    开始

    调用
    transaction.add(R.id.fragment\u容器,donsListFragment)时向“活动状态”添加新视图

    i、 e.您现在有2个视图(
    R.id.fragment\u容器
    donsListFragment
    的视图),而之前只有1个视图(仅
    R.id.fragment\u容器

    但是,当您在容器视图上调用
    .replace()
    时,
    R.id.fragment\u container
    ,它不会删除先前添加的视图

    i、 e.您仍将有2个视图(
    donsListFragment
    的视图和
    frag
    的视图)。这会导致重叠

    解决方案

    有两种可能的解决方案:


  • 使用
    transaction.replace()
    donsListFragment
    插入(大概)初始
    FragmentTransaction

  • 当导航到不同的
    片段时,调用
    .remove()
    for
    donsFragment
    作为
    片段事务的一部分


  • 我发现,从片段的各自布局中删除
    SwipeRefreshLayout
    s,而是将SwipeRefreshLayout(围绕片段的swap-in-out-FrameLayout)添加到包含活动的布局中,从而阻止了“重叠”的发生

    public void onResume() {
        EventBus.getDefault().register(this);
        OneSignal.setInFocusDisplaying(OneSignal.OSInFocusDisplayOption.None);
    
        if (EventBus.getDefault().removeStickyEvent(RefreshDonationsEvent.class) != null) {
            refreshDonations();
        }
    
        super.onResume();
    }
    
    public void refreshDonations() {
            apiClient.donationCurrentDonations();
            refreshLayout.setRefreshing(true);
        }