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