与 DrawerLayout/NavigationView 重叠的片段
Fragments overlapping with DrawerLayout/NavigationView
使用 DrawerLayout
与 NavigationView
和 FrameLayout
我想切换 Fragment
。效果很好。
但是,如果我切换得太快,那么 Fragment
会重叠...
好像executePendingTransactions()
不行
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/toolbar" />
<FrameLayout
android:id="@+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="@+id/navigationView"
android:layout_width="@240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@color/transparent"
android:dividerHeight="0dp"
app:menu="@menu/navigationdrawer" />
</android.support.v4.widget.DrawerLayout>
如果我切换 Fragment
s(太)快(手动或通过代码在我的 Nexus 5 上延迟 750 毫秒),我会让两个 Fragment
s 重叠,第二个 Fragment
启用了触摸功能,但第一个 Fragment
在顶部...
第一个 Fragment
包含 ImageView
和 TextView
。第二个 Fragment
包含一个 TabLayout
和一个 ViewPager
(如果这对我今天的问题有帮助的话)。是的,我正在使用 AppCompat 22.2.0 和 Design 22.2.0 库。
如果我为两者设置背景颜色,那么我只能看到第一个 Fragment
,并且它永远不会改变。
我尝试了popBackStackImmediate()
、executePendingTransactions()
、remove(fragment)
、android:fitsSystemWindows="true"
、Android: fragments overlapping issue、延迟和其他方法,但都没有成功。
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ...
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(final MenuItem menuItem) {
navigationDrawer(menuItem.getItemId());
return true;
}
});
if (savedInstanceState == null) {
final MenuItem menuItem = mNavigationView.getMenu().getItem(0);
if (menuItem != null) {
navigationDrawer(menuItem.getItemId());
}
}
}
private void navigationDrawer(final int itemId) {
final Fragment fragment = getFragment(itemId);
getSupportFragmentManager().beginTrasaction()
.replace(R.id.frameLayout, fragment)
.addToBackStack(null)
.commit();
mNavigationView.getMenu().findItem(itemId).setChecked(true);
mDrawerLayout.closeDrawer(mNavigationView);
supportInvalidateOptionsMenu();
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_first:
case R.id.menu_second:
case R.id.menu_third:
navigationDrawer(item.getItemId());
return true;
}
return super.onOptionsItemSelected(item);
}
编辑
在我的 onCreate()
中,我是这样做的:
if (savedInstanceState == null) {
final MenuItem menuItem = mNavigationView.getMenu().getItem(0);
if (menuItem != null) {
navigationDrawer(menuItem.getItemId());
}
}
事实证明打电话太快了。删除此代码解决了我的问题(暂时,见下文)。
我仍然不知道为什么executePendingTransactions()
没有阻止这种奇怪的问题...
编辑 2
我考虑保留一个 boolean
(init 为 false)以跟踪 Fragment
交易何时发生。我在 navigationDrawer()
中将其设置为 true
,在 Fragment.onResume()
中将其设置为 false
。还是不行...
所以:我的 MainFragment
仍然有问题,它使用 Picasso
加载图像并太快(800 毫秒)切换到另一个 Fragment
:它们仍然重叠...
你可以试试这个...
它会延迟您的频繁点击 ...
private final Handler mDrawerActionHandler = new Handler();
private static final long DRAWER_CLOSE_DELAY_MS = 250;
mDrawerActionHandler.postDelayed(new Runnable() {
@Override
public void run() {
// your navigation code goes here
}
}, DRAWER_CLOSE_DELAY_MS);
在我的 onCreate()
中,我是这样做的:
if (savedInstanceState == null) {
final MenuItem menuItem = mNavigationView.getMenu().getItem(0);
if (menuItem != null) {
navigationDrawer(menuItem.getItemId());
}
}
事实证明打电话太快了。 删除此代码解决了我的问题。
我还是不知道:
why executePendingTransactions()
did not prevent such weird issue...
编辑
我的 MainFragment
仍然有问题,它使用 Picasso
加载图像并且切换到另一个图像的速度太快(800 毫秒):它们仍然重叠...
编辑 2
所以我现在使用一个布尔值来标记我的 Activity
是否正在转换 Fragment
或没有,切换之间的最小计时器为 1 秒。
在我的 Fragment
中 onViewCreated()
:
if (view != null) {
view.post(new Runnable() {
@Override
public void run() {
// Activity might be null
getActivity().setTransitioning(false);
}
});
}
在我的 navigationDrawer()
中:
if (isTransitioning()) {
// Switching Fragments too fast
return false;
}
使用 DrawerLayout
与 NavigationView
和 FrameLayout
我想切换 Fragment
。效果很好。
但是,如果我切换得太快,那么 Fragment
会重叠...
好像executePendingTransactions()
不行
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/toolbar" />
<FrameLayout
android:id="@+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="@+id/navigationView"
android:layout_width="@240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@color/transparent"
android:dividerHeight="0dp"
app:menu="@menu/navigationdrawer" />
</android.support.v4.widget.DrawerLayout>
如果我切换 Fragment
s(太)快(手动或通过代码在我的 Nexus 5 上延迟 750 毫秒),我会让两个 Fragment
s 重叠,第二个 Fragment
启用了触摸功能,但第一个 Fragment
在顶部...
第一个 Fragment
包含 ImageView
和 TextView
。第二个 Fragment
包含一个 TabLayout
和一个 ViewPager
(如果这对我今天的问题有帮助的话)。是的,我正在使用 AppCompat 22.2.0 和 Design 22.2.0 库。
如果我为两者设置背景颜色,那么我只能看到第一个 Fragment
,并且它永远不会改变。
我尝试了popBackStackImmediate()
、executePendingTransactions()
、remove(fragment)
、android:fitsSystemWindows="true"
、Android: fragments overlapping issue、延迟和其他方法,但都没有成功。
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ...
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(final MenuItem menuItem) {
navigationDrawer(menuItem.getItemId());
return true;
}
});
if (savedInstanceState == null) {
final MenuItem menuItem = mNavigationView.getMenu().getItem(0);
if (menuItem != null) {
navigationDrawer(menuItem.getItemId());
}
}
}
private void navigationDrawer(final int itemId) {
final Fragment fragment = getFragment(itemId);
getSupportFragmentManager().beginTrasaction()
.replace(R.id.frameLayout, fragment)
.addToBackStack(null)
.commit();
mNavigationView.getMenu().findItem(itemId).setChecked(true);
mDrawerLayout.closeDrawer(mNavigationView);
supportInvalidateOptionsMenu();
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_first:
case R.id.menu_second:
case R.id.menu_third:
navigationDrawer(item.getItemId());
return true;
}
return super.onOptionsItemSelected(item);
}
编辑
在我的 onCreate()
中,我是这样做的:
if (savedInstanceState == null) {
final MenuItem menuItem = mNavigationView.getMenu().getItem(0);
if (menuItem != null) {
navigationDrawer(menuItem.getItemId());
}
}
事实证明打电话太快了。删除此代码解决了我的问题(暂时,见下文)。
我仍然不知道为什么executePendingTransactions()
没有阻止这种奇怪的问题...
编辑 2
我考虑保留一个 boolean
(init 为 false)以跟踪 Fragment
交易何时发生。我在 navigationDrawer()
中将其设置为 true
,在 Fragment.onResume()
中将其设置为 false
。还是不行...
所以:我的 MainFragment
仍然有问题,它使用 Picasso
加载图像并太快(800 毫秒)切换到另一个 Fragment
:它们仍然重叠...
你可以试试这个... 它会延迟您的频繁点击 ...
private final Handler mDrawerActionHandler = new Handler();
private static final long DRAWER_CLOSE_DELAY_MS = 250;
mDrawerActionHandler.postDelayed(new Runnable() {
@Override
public void run() {
// your navigation code goes here
}
}, DRAWER_CLOSE_DELAY_MS);
在我的 onCreate()
中,我是这样做的:
if (savedInstanceState == null) {
final MenuItem menuItem = mNavigationView.getMenu().getItem(0);
if (menuItem != null) {
navigationDrawer(menuItem.getItemId());
}
}
事实证明打电话太快了。 删除此代码解决了我的问题。
我还是不知道:
why
executePendingTransactions()
did not prevent such weird issue...
编辑
我的 MainFragment
仍然有问题,它使用 Picasso
加载图像并且切换到另一个图像的速度太快(800 毫秒):它们仍然重叠...
编辑 2
所以我现在使用一个布尔值来标记我的 Activity
是否正在转换 Fragment
或没有,切换之间的最小计时器为 1 秒。
在我的 Fragment
中 onViewCreated()
:
if (view != null) {
view.post(new Runnable() {
@Override
public void run() {
// Activity might be null
getActivity().setTransitioning(false);
}
});
}
在我的 navigationDrawer()
中:
if (isTransitioning()) {
// Switching Fragments too fast
return false;
}