显示/隐藏系统栏上的 Android 屏幕闪烁
Posted
技术标签:
【中文标题】显示/隐藏系统栏上的 Android 屏幕闪烁【英文标题】:Android Screen Blinking on show/hide System Bars 【发布时间】:2017-12-07 04:21:28 【问题描述】:问题
我想在用户向上滚动 RecyclerView 时显示系统栏,并在用户向下滚动时隐藏系统栏。但是,使用我的方法它可以工作,但是在显示/隐藏过程中内容会奇怪地移动和闪烁。你在这里上传了一个视频:https://drive.google.com/open?id=0B_b9EpRt-zyHVW54dkQzcXdUTXM
我的方法
基本上我有这两种方法:
private void hideSystemUI()
getActivity().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 // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE);
private void showSystemUI()
getActivity().getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
我将这个 onScrollListener 设置为 RecyclerView 以根据滚动隐藏和显示状态栏:
mFragmentListBinding.fragListRvMovies.addOnScrollListener(new RecyclerView.OnScrollListener()
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy)
super.onScrolled(recyclerView, dx, dy);
if (dy > 5)
// hideSystemUI();
// SystemUIHelper.hide(getActivity());
hideSystemUI();
else if (dy < -5)
showSystemUI();
// showSystemUI();
// SystemUIHelper.show(getActivity());
if (pageToDownload < TOTAL_PAGES && layoutManager.findLastVisibleItemPosition() == adapter.movieList.size() - 1 && !isLoadingLocked && !isLoading)
downloadMoviesList();
);
这是布局:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<android.support.v4.widget.DrawerLayout
android:id="@+id/frag_drawer_layout"
android:layout_
android:layout_>
<android.support.design.widget.CoordinatorLayout
android:id="@+id/frag_drawer_coordinator"
android:layout_
android:layout_
android:fitsSystemWindows="false">
<android.support.design.widget.AppBarLayout
android:id="@+id/frag_drawer_appbar"
android:layout_
android:layout_
android:theme="@style/AppTheme.AppBarOverlay"
android:transitionGroup="false"
tools:targetApi="lollipop">
<android.support.v7.widget.Toolbar
android:id="@+id/frag_drawer_tb"
android:layout_
android:layout_
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
</android.support.design.widget.AppBarLayout>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/frag_drawer_content"
android:layout_
android:layout_
android:fitsSystemWindows="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/frag_drawer_fab_add"
android:layout_
android:layout_
android:layout_gravity="end|bottom"
android:layout_margin="@dimen/material_component_floating_action_button_margin"
android:src="@drawable/ic_add_white_24dp"
android:visibility="gone"
android:fitsSystemWindows="false"
app:backgroundTint="@color/accent"
app:elevation="@dimen/elevation_fab_resting"
app:fabSize="normal" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/frag_drawer_fab_filter"
android:layout_
android:layout_
android:layout_gravity="end|bottom"
android:layout_margin="@dimen/material_component_floating_action_button_margin"
android:fitsSystemWindows="false"
android:src="@drawable/ic_filter"
android:visibility="visible"
app:backgroundTint="@color/accent"
app:elevation="@dimen/elevation_fab_resting"
app:fabSize="normal" />
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="@+id/frag_drawer_nav"
android:layout_
android:layout_
android:layout_gravity="start"
app:elevation="@dimen/elevation_nav_drawer"
app:headerLayout="@layout/layout_nv_header"
app:itemIconTint="@color/nav_icon_tint"
app:itemTextColor="@color/nav_text"
app:menu="@menu/menu_drawer" />
</android.support.v4.widget.DrawerLayout>
</layout>
我的问题
如何更流畅地显示和隐藏状态栏和导航视图?
【问题讨论】:
android 负责管理显示和隐藏状态栏(顶部)和导航栏(底部)的动画。我们无法控制它 您是否尝试将 animateLayoutChanges="true" 添加到 RecyclerView 或其父容器? 是的,我试过了,但没有任何改变 【参考方案1】:您看到的是 Layout
调整大小。防止这种情况的唯一方法是将Layout
分层在系统视图下,因此它不受影响。
检查以下标志,这可能有助于防止调整大小:
FLAG_LAYOUT_IN_SCREEN
FLAG_LAYOUT_INSET_DECOR
但是,请记住,您的内容的顶部将位于系统 UI 之后,您需要将其抵消。
【讨论】:
这实际上让我找到了解决方案,谢谢!【参考方案2】://隐藏状态栏
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
// 显示状态栏
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
【讨论】:
【参考方案3】:您是否尝试过在 Android 的 UI 线程上运行您的方法?例如
runOnUiThread(new Runnable()
public void run()
// execute your hiding/presenting the bar here
);
有几个选项可以使用 Android UI 线程……看看this question
【讨论】:
以上是关于显示/隐藏系统栏上的 Android 屏幕闪烁的主要内容,如果未能解决你的问题,请参考以下文章
Android4.2.2 动态显示隐藏屏幕底部的导航栏(对系统源码进行修改)