Android Полностью прозрачная панель состояния?
Я искал документацию, но нашел только это: Ссылка. Что используется, чтобы сделать бар прозрачным? Я пытаюсь сделать строку состояния полностью прозрачной (как показано на рисунке ниже) и сделать ее обратно совместимой для APK <19: ![enter image description here]()
Мой styles.xml:
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="AppTheme" parent="Theme.AppCompat.Light">
<item name="android:actionBarStyle">@style/ThemeActionBar</item>
<item name="android:windowActionBarOverlay">true</item>
<!-- Support library compatibility -->
<item name="actionBarStyle">@style/ThemeActionBar</item>
<item name="windowActionBarOverlay">true</item>
</style>
<style name="ThemeActionBar" parent="Widget.AppCompat.Light.ActionBar.Solid">
<item name="android:background"> @null </item>
<!-- Support library compatibility -->
<item name="background">@null</item>
<item name="android:displayOptions"> showHome | useLogo</item>
<item name="displayOptions">showHome|useLogo</item>
</style>
</resources>
Что я смог сделать:
![enter image description here]()
Ответы
Ответ 1
Все, что вам нужно сделать, это установить эти свойства в вашей теме:
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
Для вашей деятельности/макета контейнера, для которого вы хотите иметь прозрачную строку состояния, необходимо установить следующее свойство:
android:fitsSystemWindows="true"
Как правило, это невозможно выполнить на pre-kitkat, похоже, что вы можете это сделать, но какой-то странный код делает это так.
РЕДАКТИРОВАТЬ: Я бы порекомендовал эту библиотеку: https://github.com/jgilfelt/SystemBarTint для многих элементов управления цветом строки состояния перед леденцом на палочке.
После долгих размышлений я узнал, что ответом на полное отключение полупрозрачности или любого цвета, помещенного в строку состояния и панель навигации для леденца на палочке, является установка этого флага в окне:
// In Activity onCreate() for instance
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window w = getWindow();
w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
Никакая другая тема не нужна, она производит что-то вроде этого:
![enter image description here]()
Ответ 2
Просто добавьте эту строку кода в ваш основной файл Java:
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
);
Ответ 3
Вы можете использовать внешнюю библиотеку StatusBarUtil:
Добавьте к своему модулю уровень build.gradle
:
compile 'com.jaeger.statusbarutil:library:1.4.0'
Затем вы можете использовать следующую утилиту для действия, чтобы сделать строку состояния прозрачной:
StatusBarUtil.setTransparent(Activity activity)
Пример:
![transparent status bar on Lollipop and KitKat]()
Ответ 4
Работает для Android KitKat и выше (для тех, кто хочет прозрачно отображать строку состояния и не манипулирует навигационной панелью, потому что все эти ответы также будут прозрачной навигационной панелью!)
Самый простой способ добиться этого:
Поместите эти 3 строки кода в styles.xml(v19)
→ если вы не знаете, как это сделать (v19), просто напишите их в styles.xml
умолчанию и затем используйте alt + enter для автоматически создать его:
<item name="android:windowFullscreen">false</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:fitsSystemWindows">false</item>
А теперь перейдите к вашему классу MainActivity
и поместите этот метод из onCreate в класс:
public static void setWindowFlag(Activity activity, final int bits, boolean on) {
Window win = activity.getWindow();
WindowManager.LayoutParams winParams = win.getAttributes();
if (on) {
winParams.flags |= bits;
} else {
winParams.flags &= ~bits;
}
win.setAttributes(winParams);
}
Затем поместите этот код в метод onCreate
в Activity:
if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, true);
}
if (Build.VERSION.SDK_INT >= 19) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
//make fully Android Transparent Status bar
if (Build.VERSION.SDK_INT >= 21) {
setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false);
getWindow().setStatusBarColor(Color.TRANSPARENT);
}
Это!
Ответ 5
Чтобы нарисовать макет под строкой состояния:
Значения /styles.xml
<item name="android:windowTranslucentStatus">true</item>
Значения-V21/styles.xml
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@color/colorPrimaryDark</item>
Используйте CoordinatorLayout/DrawerLayout, который уже позаботится о параметре fitsSystemWindows, или создайте свой собственный макет так:
public class FitsSystemWindowConstraintLayout extends ConstraintLayout {
private Drawable mStatusBarBackground;
private boolean mDrawStatusBarBackground;
private WindowInsetsCompat mLastInsets;
private Map<View, int[]> childsMargins = new HashMap<>();
public FitsSystemWindowConstraintLayout(Context context) {
this(context, null);
}
public FitsSystemWindowConstraintLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public FitsSystemWindowConstraintLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
if (ViewCompat.getFitsSystemWindows(this)) {
ViewCompat.setOnApplyWindowInsetsListener(this, new android.support.v4.view.OnApplyWindowInsetsListener() {
@Override
public WindowInsetsCompat onApplyWindowInsets(View view, WindowInsetsCompat insets) {
FitsSystemWindowConstraintLayout layout = (FitsSystemWindowConstraintLayout) view;
layout.setChildInsets(insets, insets.getSystemWindowInsetTop() > 0);
return insets.consumeSystemWindowInsets();
}
});
setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
TypedArray typedArray = context.obtainStyledAttributes(new int[]{android.R.attr.colorPrimaryDark});
try {
mStatusBarBackground = typedArray.getDrawable(0);
} finally {
typedArray.recycle();
}
} else {
mStatusBarBackground = null;
}
}
public void setChildInsets(WindowInsetsCompat insets, boolean draw) {
mLastInsets = insets;
mDrawStatusBarBackground = draw;
setWillNotDraw(!draw && getBackground() == null);
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child.getVisibility() != GONE) {
if (ViewCompat.getFitsSystemWindows(this)) {
ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) child.getLayoutParams();
if (ViewCompat.getFitsSystemWindows(child)) {
ViewCompat.dispatchApplyWindowInsets(child, insets);
} else {
int[] childMargins = childsMargins.get(child);
if (childMargins == null) {
childMargins = new int[]{layoutParams.leftMargin, layoutParams.topMargin, layoutParams.rightMargin, layoutParams.bottomMargin};
childsMargins.put(child, childMargins);
}
if (layoutParams.leftToLeft == LayoutParams.PARENT_ID) {
layoutParams.leftMargin = childMargins[0] + insets.getSystemWindowInsetLeft();
}
if (layoutParams.topToTop == LayoutParams.PARENT_ID) {
layoutParams.topMargin = childMargins[1] + insets.getSystemWindowInsetTop();
}
if (layoutParams.rightToRight == LayoutParams.PARENT_ID) {
layoutParams.rightMargin = childMargins[2] + insets.getSystemWindowInsetRight();
}
if (layoutParams.bottomToBottom == LayoutParams.PARENT_ID) {
layoutParams.bottomMargin = childMargins[3] + insets.getSystemWindowInsetBottom();
}
}
}
}
}
requestLayout();
}
public void setStatusBarBackground(Drawable bg) {
mStatusBarBackground = bg;
invalidate();
}
public Drawable getStatusBarBackgroundDrawable() {
return mStatusBarBackground;
}
public void setStatusBarBackground(int resId) {
mStatusBarBackground = resId != 0 ? ContextCompat.getDrawable(getContext(), resId) : null;
invalidate();
}
public void setStatusBarBackgroundColor(@ColorInt int color) {
mStatusBarBackground = new ColorDrawable(color);
invalidate();
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mDrawStatusBarBackground && mStatusBarBackground != null) {
int inset = mLastInsets != null ? mLastInsets.getSystemWindowInsetTop() : 0;
if (inset > 0) {
mStatusBarBackground.setBounds(0, 0, getWidth(), inset);
mStatusBarBackground.draw(canvas);
}
}
}
}
main_activity.xml
<FitsSystemWindowConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
android:src="@drawable/toolbar_background"
app:layout_constraintBottom_toBottomOf="@id/toolbar"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="0dp"
android:layout_height="?attr/actionBarSize"
android:background="@android:color/transparent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Content"
android:textSize="48sp" />
</LinearLayout>
</FitsSystemWindowConstraintLayout>
Результат:
Скриншот:
![Screenshot]()
Ответ 6
Полностью прозрачная панель состояния и панель навигации
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
transparentStatusAndNavigation();
}
private void transparentStatusAndNavigation() {
//make full transparent statusBar
if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
setWindowFlag(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, true);
}
if (Build.VERSION.SDK_INT >= 19) {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
);
}
if (Build.VERSION.SDK_INT >= 21) {
setWindowFlag(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, false);
getWindow().setStatusBarColor(Color.TRANSPARENT);
getWindow().setNavigationBarColor(Color.TRANSPARENT);
}
}
private void setWindowFlag(final int bits, boolean on) {
Window win = getWindow();
WindowManager.LayoutParams winParams = win.getAttributes();
if (on) {
winParams.flags |= bits;
} else {
winParams.flags &= ~bits;
}
win.setAttributes(winParams);
}
Ответ 7
Используйте android:fitsSystemWindows="false"
в вашем топ-макете
Ответ 8
Вот расширение в kotlin, которое делает свое дело:
fun Activity.setTransparentStatusBar() {
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.statusBarColor = Color.TRANSPARENT
}
}
Ответ 9
Ничего, я нашел ответ здесь:
полностью прозрачная строка состояния и панель навигации на леденец
Надеюсь, это поможет кому-то:).
Теперь мне нужно только сделать его обратно совместимым.
Ответ 10
Используя этот код в своем XML, вы сможете увидеть временную шкалу в вашей активности:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
Ответ 11
Вы также можете просмотреть мой пример с анимированным аватаром и анимированным текстом.
CollapsingAvatarToolbarSample
Читайте мой пост на Medium
![]()
Итак, позвольте мне объяснить, как это работает. Я создал собственный вид, реализованный AppBarLayout.OnOffsetChangedListener. Внутри HeadCollapsing Custom View я основал текст и изображение в AppBarLayout.
class HeadCollapsing(context: Context, attrs: AttributeSet?) :
FrameLayout(context, attrs), AppBarLayout.OnOffsetChangedListener {
private fun findViews() {
appBarLayout = findParentAppBarLayout()
avatarContainerView = findViewById(R.id.imgb_avatar_wrap)
titleToolbarText = findViewById<AppCompatTextView>(id)
}
private fun findParentAppBarLayout(): AppBarLayout {
val parent = this.parent
return parent as? AppBarLayout ?: if (parent.parent is AppBarLayout) {
parent.parent as AppBarLayout
} else {
throw IllegalStateException("Must be inside an AppBarLayout")
}
}
...
override fun onOffsetChanged(appBarLayout: AppBarLayout, offset:Int) {
...
//Calculate expanded percentage
val expandedPercentage = 1 - -offset / maxOffset
updateViews(expandedPercentage)
}
}
Затем измените просмотры через рассчитанный процент. Например, как изменяется вид текста:
when {
inversePercentage < ABROAD -> {
titleToolbarText?.visibility = View.VISIBLE
titleTolbarTextSingle?.visibility = View.INVISIBLE
}
inversePercentage > ABROAD -> {
titleToolbarText?.visibility = View.INVISIBLE
titleTolbarTextSingle?.visibility = View.VISIBLE
titleTolbarTextSingle?.let {
animateShowText(it)
}
}
}
Чтобы определить, когда нужно свернуть изображение, анимируйте созданный объект Pair
private var cashCollapseState: kotlin.Pair<Int, Int>? = null
с состояниями: TO_EXPANDED_STATE, TO_COLLAPSED_STATE, WAIT_FOR_SWITCH, SWITCHED
companion object {
const val ABROAD = 0.95f
const val TO_EXPANDED_STATE = 0
const val TO_COLLAPSED_STATE = 1
const val WAIT_FOR_SWITCH = 0
const val SWITCHED = 1
}
затем создана анимация для аватара с состоянием:
when {
cashCollapseState != null && cashCollapseState != state -> {
when (state.first) {
TO_EXPANDED_STATE -> {
// do calculates
}
TO_COLLAPSED_STATE -> {
ValueAnimator.ofFloat(avatarContainerView.translationX, translationX).apply {
addUpdateListener {
avatarContainerView.translationX = it.animatedValue as Float
}
duration = 350
(state.first == TO_COLLAPSED_STATE).apply {
if (this) interpolator = LinearInterpolator()
}
start()
}
//SWITCH STATE CASE
cashCollapseState = kotlin.Pair(state.first, SWITCHED)
}
else -> {
cashCollapseState = kotlin.Pair(state.first, WAIT_FOR_SWITCH)
}
Ответ 12
android:fitsSystemWindows="true"
работает только с v21. Мы можем установить его в теме xml или в родительском макете типа LinearLayout
или в CoordinateLayout
.
Для ниже v21 мы не смогли добавить этот флаг.
Пожалуйста, создайте папку с различными значениями с различным style.xml
файлом в соответствии с вашими потребностями.
Ответ 13
Вы можете попробовать это.
private static void setStatusBarTransparent(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
} else {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
Ответ 14
добавьте эти строки в свою активность перед setContentView()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window w = getWindow();
w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
добавьте эти 2 строки в ваш AppTheme
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
и последнее, что ваш minSdkVersion должен б 19
minSdkVersion 19
Ответ 15
Это сработало для меня:
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">false</item>
<item name="android:windowTranslucentNavigation">false</item>
Ответ 16
Все, что нужно, это зайти в MainActivity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Window g = getWindow();
g.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
setContentView(R.layout.activity_main);
}
Ответ 17
Есть три шага:
1) Просто используйте этот сегмент кода в свой метод @OnCreate
@OnCreate{
// FullScreen
getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
если вы работаете с Fragment, вам следует поместить этот сегмент кода в метод деятельности @OnCreate.
2) Обязательно установите прозрачность в /res/values-v21/styles.xml:
<item name="android:statusBarColor">@android:color/transparent</item>
Или вы можете установить прозрачность программно:
getWindow().setStatusBarColor(Color.TRANSPARENT);
3) В любом случае вы должны добавить сегмент кода в styles.xml
<item name="android:windowTranslucentStatus">true</item>
ПРИМЕЧАНИЕ. Этот метод работает только с API 21 и выше.
Ответ 18
<item name="android:statusBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
<!--<item name="android:windowLightStatusBar" tools:targetApi="m">true</item>-->
Не используйте windowLightStatusBar
используйте вместо него statusBarColor = @android:color/transparent
Ответ 19
Это только для уровня API> = 21. Это работает для меня. Вот мой код (Kotlin)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<View>(android.R.id.content).systemUiVisibility =
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
}