Подтвердить что ты не робот

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

4b9b3361

Ответ 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
    }
}

Ответ 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
}