programing

Android 완전히 투명한 상태 표시줄?

minimums 2023. 10. 25. 23:13
반응형

Android 완전히 투명한 상태 표시줄?

설명서를 찾아봤지만 링크라는 것만 발견되었습니다.막대를 반투명하게 만드는 데 사용되는 것은?제가 하려는 일은 상태 표시줄을 완전히 투명하게 만들고(아래 이미지에 표시된 것처럼) APK<19:enter image description here

My style.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

테마에 다음 속성만 설정하면 됩니다.

<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>

투명 상태 표시줄을 사용하려는 활동/컨테이너 레이아웃에는 다음 속성 집합이 필요합니다.

android:fitsSystemWindows="true"

일반적으로 프리킷캣에서 이것을 확실히 수행하는 것은 불가능합니다. 당신이 할 수 있는 것처럼 보이지만 어떤 이상한 코드가 그렇게 만듭니다.

편집: 많은 사전 막대 막대 막대 색 제어를 위해 이 lib: https://github.com/jgilfelt/SystemBarTint 을 추천합니다.

고민 끝에 저는 투명도를 완전히 비활성화하거나 막대 모양의 상태 표시줄과 탐색 막대에 배치된 색상을 막대에 완전히 비활성화하는 것에 대한 답이 창에 이 플래그를 설정하는 것임을 알게 되었습니다.

// In Activity's 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

이 코드 줄을 메인 자바 파일에 추가하기만 하면 됩니다.

getWindow().setFlags(
    WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
    WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
);

아래 코드를 사용하여 상태 표시줄을 투명하게 만들 수 있습니다. 아래 코드의 사용을 식별하는 데 도움이 되는 빨간색 강조 표시가 있는 이미지를 참조하십시오.

1]

안드로이드 앱을 위한 코틀린 코드 스니펫

단계:1 On create method에 코드 쓰기

if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
    setWindowFlag(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, true)
}
if (Build.VERSION.SDK_INT >= 19) {
    window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
}
if (Build.VERSION.SDK_INT >= 21) {
    setWindowFlag(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false)
    window.statusBarColor = Color.TRANSPARENT
}

2단계: 아래 코드에서 설명하는 윈도우 플래그 설정 방법이 필요합니다.

private fun setWindowFlag(bits: Int, on: Boolean) {
    val win = window
    val winParams = win.attributes
    if (on) {
        winParams.flags = winParams.flags or bits
    } else {
        winParams.flags = winParams.flags and bits.inv()
    }
    win.attributes = winParams
}

Android 앱용 Java 코드 스니펫:

1단계: 주 활동 코드

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);
}

if (Build.VERSION.SDK_INT >= 21) {
    setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false);
    getWindow().setStatusBarColor(Color.TRANSPARENT);
}

2단계: 윈도우 플래그 설정 방법

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);
}

Android KitKat 이상에서 작동합니다. (상태 표시줄을 투명하게 하고 네비게이션 바를 조작하지 않으려는 사용자의 경우, 이 모든 답변이 네비게이션 바도 투명하게 표시됩니다!)

가장 쉬운 방법은 다음과 같습니다.

이 세 줄의 코드를 집어넣습니다.styles.xml (v19)-> 이것(v19)을 어떻게 갖는지 모르면 그냥 기본값으로 써주세요styles.xml그런 다음 +enter를 사용하여 자동으로 만듭니다.

<item name="android:windowFullscreen">false</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:fitsSystemWindows">false</item>

그리고 이제, 당신의 것으로 가세요.MainActivity클래스를 지정하고 이 메서드를 삭제합니다.클래스에서 만들기:

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활동 방법:

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);
    }

그거에요!

완전 투명 상태 표시줄 및 탐색 표시줄

@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);
}

방금 여기서 찾았어요.

이미 6년이 지났고 기본 minSDKAPI는 21(롤리팝) *CMIIW이기 때문입니다.탐색 버튼과 겹치지 않고 투명 상태 표시줄을 마무리하는 방법은 다음과 같습니다.

fun setStatusBarTransparent(activity: Activity, view: View) {
    activity.apply {
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
        window.statusBarColor = ContextCompat.getColor(this, R.color.transparent)
        WindowCompat.setDecorFitsSystemWindows(window, false)
        ViewCompat.setOnApplyWindowInsetsListener(view) { root, windowInset ->
            val inset = windowInset.getInsets(WindowInsetsCompat.Type.systemBars())
            root.updateLayoutParams<ViewGroup.MarginLayoutParams> {
                leftMargin = inset.left
                bottomMargin = inset.bottom
                rightMargin = inset.right
                topMargin = 0
            }
            WindowInsetsCompat.CONSUMED
        }
    }
}

상태 표시줄을 다시 표시하려면 몇 가지 변경 사항이 필요합니다.

fun setStatusBarShown(activity: Activity, view: View) {
    activity.apply {
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
        window.statusBarColor = ContextCompat.getColor(this, R.color.transparent)
        WindowCompat.setDecorFitsSystemWindows(window, false)
        ViewCompat.setOnApplyWindowInsetsListener(view) { root, windowInset ->
            val inset = windowInset.getInsets(WindowInsetsCompat.Type.systemBars())
            val inset1 = windowInset.getInsets(WindowInsetsCompat.Type.statusBars())
            root.updateLayoutParams<ViewGroup.MarginLayoutParams> {
                leftMargin = inset.left
                bottomMargin = inset.bottom
                topMargin = inset1.top
                rightMargin = inset.right
            }
            WindowInsetsCompat.CONSUMED
        }
    }
}

그 기능을 안에 넣었습니다.Object부름반UiUtils활동에서 해당 기능을 호출할 때(View Binding도 사용).다음과 같습니다.

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    ...
    UiUtils.setStatusBarTransparent(this, bind.root)
    ...
}

제 대답이 도움이 될 수 있기를 바랍니다 :)

상태 표시줄 아래에 레이아웃을 그리려면:

values/styles.xml

<item name="android:windowTranslucentStatus">true</item>

values-v21/styles.xml

<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@color/colorPrimaryDark</item>

이미 적합한 시스템 Windows 매개변수를 처리한 CoordinatorLayout/DrawerLayout을 사용하거나 다음과 같이 자신만의 레이아웃을 만듭니다.

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

단순하고 간결하며 거의 모든 사용 사례(API 레벨 16 이상의 경우)와 함께 작동합니다.

  1. 앱 테마에서 다음 태그를 사용하여 상태 표시줄을 투명하게 만듭니다.

    <item name="android:statusBarColor">@android:color/transparent</item>

  2. 그런 다음 활동의 생성 방법에서 이 코드를 사용합니다.

    View decorView = getWindow().getDecorView();
    decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
    

그거면 돼요 ;)

개발자 설명서를 통해 더 많은 정보를 얻을 수 있습니다.저도 이 블로그 글을 읽는 것을 추천합니다.

KOTLIN 코드:

    val decorView = window.decorView
    decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)

여기서 나의 다른 답변을 확인합니다.

다음은 코틀린의 확장자로 요령을 부리는 것입니다.

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
    }
}

주/야간 지원이 가능한 API > 23의 경우 아래 확장자를 이용하실 수 있습니다.이해해야 할 중요한 부분은android:fitsSystemWindows="true"도구 모음에서와 같이 패딩을 사용하여 삽입체 내에서 이동합니다.따라서 루트 레이아웃(Drower Layout, Coordinator Layout, ...이들은 자체 구현을 사용합니다)에 배치하는 것은 타당하지 않습니다.

enter image description here

<style name="Theme.YourApp.DayNight" parent="Theme.MaterialComponents.DayNight.NoActionBar">
    ...
    <item name="android:windowLightStatusBar">@bool/isDayMode</item>
    <item name="android:statusBarColor">@android:color/transparent</item>
</style>
<androidx.constraintlayout.widget.ConstraintLayout
    ...>

    <com.google.android.material.appbar.MaterialToolbar
        ...
        android:fitsSystemWindows="true">

</androidx.constraintlayout.widget.ConstraintLayout
fun Activity.transparentStatusBar() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
        window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
    } else {
        window.setDecorFitsSystemWindows(false)
    }
}

그럼 이렇게 부르세요.

class YourActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        transparentStatusBar()
    }
}

Chris Banes의 슬라이드를 확인해 보십시오. 에 잘 맞는 사람이 되기

편집: 탐색 모음 뒤에 콘텐츠가 떠 있는 데 문제가 있으면 다음을 사용합니다.

// using Insetter
binding.yourViewHere.applySystemWindowInsetsToPadding(bottom = true)

사용하다android:fitsSystemWindows="false"당신의 맨 위 배치로

styles.xml과 액티비티를 다루는 것이 너무 번거롭다는 것을 알았기 때문에 아래 옵션이 설정된 일반적인 유틸리티 방법을 만들었습니다.

자바

Window window = getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
window.setStatusBarColor(Color.TRANSPARENT);

코틀린 DSL

activity.window.apply {
    clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
    addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
    decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
    statusBarColor = Color.TRANSPARENT
}

그리고 투명한 상태 표시줄을 달성하는 데 필요한 것은 그것뿐입니다.도움이 되길 바랍니다.

세 가지 단계가 있습니다.

1)이 코드 세그먼트를 OnCreate 메서드에 사용합니다.

  // FullScreen
  getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, 
  WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

프래그먼트 작업을 하는 경우 이 코드 세그먼트를 활동의 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 이상에서만 작동합니다.

이것은 제가 많은 검색 끝에 찾은 간단한 방법입니다.

1단계

당신의 테마에 이 아이템을 넣습니다.

        <item name="android:statusBarColor" tools:targetApi="lollipop">@android:color/transparent</item>

2단계

주 활동

WindowCompat.setDecorFitsSystemWindows(window, false)

하단 탐색 막대를 사용한 경우 매우 중요합니다.

일부 장치에서는 API 30+ u를 사용하면 시스템 탐색바가 아래쪽 탐색바와 겹치는 것을 찾을 수 있습니다.

이것이 이 문제를 해결하는 것입니다.

  if (Build.VERSION.SDK_INT >= 30) {
        // Root ViewGroup of my activity
        val root = findViewById<ConstraintLayout>(R.id.root)

        ViewCompat.setOnApplyWindowInsetsListener(root) { view, windowInsets ->

            val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())

            // Apply the insets as a margin to the view. Here the system is setting
            // only the bottom, left, and right dimensions, but apply whichever insets are
            // appropriate to your layout. You can also update the view padding
            // if that's more appropriate.

            view.layoutParams =  (view.layoutParams as FrameLayout.LayoutParams).apply {
                leftMargin = insets.left
                bottomMargin = insets.bottom
                rightMargin = insets.right
            }

            // Return CONSUMED if you don't want want the window insets to keep being
            // passed down to descendant views.
            WindowInsetsCompat.CONSUMED
        }

    }
<style name="Theme.Transparent" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowTranslucentStatus">true</item>
    <item name="android:windowTranslucentNavigation">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
</style>

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">

효과가 있었습니다.

<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>

다음 코드를 시도해 봅니다.

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);
    }
}

statusBar 색상만 제거됩니다!

window?.decorView?.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
window?.statusBarColor = Color.TRANSPARENT

enter image description here

나한테 효과가 있었어요, 당신에게도 효과가 있기를 바랍니다.

필요한 것은 단지 안으로 들어가는 것입니다.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);

    }

제 경우에는 "onCreate"(반응 네이티브 앱이며 반응 네이티브 상태바 구성 요소를 사용하여 수정할 수도 있음)를 전혀 호출하지 않습니다.

override fun onStart() {
        super.onStart()
        window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
        window.statusBarColor = Color.TRANSPARENT
}

위의 모든 답이 동일한 기본 아이디어를 중심으로 순환하고 위의 예시 중 하나를 사용하여 간단한 레이아웃으로 작동시킬 수 있습니다.다만 슬라이딩 '전체화면'(탭바 옆) 조각 내비게이션을 사용하면서 배경색을 바꾸고 내비게이션, 탭, 액션바 등을 규칙적으로 유지하고 싶었습니다.

안톤 하두츠키의 기사를 주의 깊게 읽은 후에 저는 무슨 일이 일어나고 있는지 더 잘 이해하게 되었습니다.

있습니다DrawerLayout와 함께ConstraintLayout(즉, 컨테이너)를 포함하는Toolbar, 주절편에 대하여 포함하고.BottomNavigationView.

세팅DrawerLayout하고 있다fitsSystemWindows진실로는 충분하지 않아요, 당신은 두 가지 모두를 설정해야 합니다.DrawerLayout그리고.ConstraintLayout. 투명 상태 표시줄을 가정하면 상태 표시줄 색상은 이제 배경 색상과 동일합니다.ConstraintLayout.

그러나 포함된 프래그먼트는 여전히 상태 표시줄이 설정되어 있으므로 다른 '전체 화면' 프래그먼트를 위에 올려도 상태 표시줄의 색이 변경되지 않습니다.

참조된 기사에서 약간의 코드가 다음으로.ActivityonCreate:

ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.container)) { view, insets ->
        insets.replaceSystemWindowInsets(
                insets.systemWindowInsetLeft,
                0,
                insets.systemWindowInsetRight,
                insets.systemWindowInsetBottom
        )
    }

그리고 지금을 제외하고는 모든게 좋아요.Toolbar상태 표시줄 높이는 다루지 않습니다.기사를 좀 더 참고하면 완벽하게 작동하는 솔루션이 있습니다.

val toolbar = findViewById<Toolbar>(R.id.my_toolbar)
    ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.container)) { view, insets ->
        val params = toolbar.layoutParams as ViewGroup.MarginLayoutParams
        params.topMargin = insets.systemWindowInsetTop
        toolbar.layoutParams = params
        insets.replaceSystemWindowInsets(
                insets.systemWindowInsetLeft,
                0,
                insets.systemWindowInsetRight,
                insets.systemWindowInsetBottom
        )
    }

main_activity.xml (marginTopin에 유의하십시오.Toolbar는 미리보기 목적이며 코드로 대체됩니다.

<?xml version="1.0" encoding="utf-8"?>
    <androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        >

    <androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/green"
        android:fitsSystemWindows="true"
        tools:context=".MainActivity">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/my_toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_constraintTop_toTopOf="@id/container"
            android:layout_marginTop="26dp" 
            android:background="@android:color/transparent"
            ...>
            ...
        </androidx.appcompat.widget.Toolbar>

        <include layout="@layout/content_main" />
        ...
    </androidx.constraintlayout.widget.ConstraintLayout>
    ...
</androidx.drawerlayout.widget.DrawerLayout>

다음은 코틀린 확장입니다.

fun Activity.transparentStatusBar() {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
        window.statusBarColor = Color.TRANSPARENT

    } else
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)

}

이 솔루션은 완전히 투명한 상태 표시줄을 사용하고 탐색 표시줄에 영향을 주지 않으려는 사용자를 위한 것입니다.믿을 수 없을 정도로 간단해서 저를 포함한 한 명 이상이 머리를 아프게 했습니다.

이것이 제가 말하는 최종 결과입니다.

결과

우리 활동의 OnCreate에서 호출할 것을 권장하는 두 가지 기능만 필요합니다. 첫 번째 기능은 setStatusBar()로 동일한 기능에 대한 투명화를 담당합니다.

private fun setStatusBar() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    window.apply {
        clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
        addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            decorView.systemUiVisibility =
                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
        } else {
            decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        }
        statusBarColor = Color.TRANSPARENT
    }
}

두 번째 보기인 setMargins()는 상단으로 제한된 보기에 해당하는 여백 설정을 담당합니다. 그렇지 않으면 상태 표시줄 아래에 이러한 보기가 표시되기 때문입니다.

private fun setMargins() {
    ViewCompat.setOnApplyWindowInsetsListener(
        findViewById(R.id.your_parent_view)
    ) { _, insets ->
        val view = findViewById<FrameLayout>(R.id.your_child_view)
        val params = view.layoutParams as ViewGroup.MarginLayoutParams
        params.setMargins(
            0,
            insets.systemWindowInsetTop,
            0,
            0
        )
        view.layoutParams = params
        insets.consumeSystemWindowInsets()
    }
}

최종 코드는 다음과 같습니다.

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.your_layout))
        setStatusBar()
        setMargins()
}

private fun setStatusBar() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    window.apply {
        clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
        addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            decorView.systemUiVisibility =
                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
        } else {
            decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        }
        statusBarColor = Color.TRANSPARENT
    }
}

private fun setMargins() {
    ViewCompat.setOnApplyWindowInsetsListener(
        findViewById(R.id.your_parent_view)
    ) { _, insets ->
        val view = findViewById<FrameLayout>(R.id.your_child_view)
        val params = view.layoutParams as ViewGroup.MarginLayoutParams
        params.setMargins(
            0,
            insets.systemWindowInsetTop,
            0,
            0
        )
        view.layoutParams = params
        insets.consumeSystemWindowInsets()
    }
}

이 모든 것에 대한 더 자세한 설명은 다음 포스트에서 찾을 수 있습니다.

저는 또한 이러한 개념들이 작동하는 테스트 프로젝트를 남깁니다.

이 기능을 뉴/올드 안드로이드 api에서 작동합니다.

private fun changeScreenSystemUiController(isFullScreen: Boolean) {
    window?.also {
        WindowCompat.setDecorFitsSystemWindows(it, !isFullScreen)
        WindowCompat.getInsetsController(it, it.decorView).apply {
            systemBarsBehavior =
                if (isFullScreen)
                    WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
                else
                    WindowInsetsControllerCompat.BEHAVIOR_SHOW_BARS_BY_TOUCH
            if (isFullScreen)
                hide(WindowInsetsCompat.Type.systemBars())
            else
                show(WindowInsetsCompat.Type.systemBars())
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            it.attributes.layoutInDisplayCutoutMode =
                if (isFullScreen)
                    WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
                else
                    WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
        }
    }
}

완전히 투명한 상태 표시줄을 사용하려면:먼저 테마.xml에서 사용자 지정 테마를 다음과 같이 만듭니다.

<style name="Theme.QuiloThemeLight" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowTranslucentNavigation">true</item>
</style>

Java:

    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
    getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
    getWindow().setStatusBarColor(Color.TRANSPARENT);

코틀린:

activity.window.apply {
        clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
        addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
        decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        statusBarColor = Color.TRANSPARENT
    }

android:fitsSystemWindows="true"v21에서만 작동합니다.테마 xml이나 부모 레이아웃에서 설정할 수 있습니다.LinearLayout아니면CoordinateLayout 이 할 수 v21 아래의 경우 이 플래그를 추가할 수 없습니다.다른 값 폴더를 다른 값으로 만들어 주십시오.style.xml필요에 따라 파일을 작성합니다.

 <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

하단 도구 모음이 있는 경우 이전 솔루션을 테스트할 때 문제가 있었습니다. Android 시스템 버튼은 하단 메뉴로 덮여 있습니다. 활동 내에 추가하는 솔루션은 다음과 같습니다.

Create(Bundle savedInstanceState) { super.onCreate(savedInstanceState)에서 보호된 void;

    // force full screen mode
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);


    setContentView(R.layout.main_activity_container);

아래 코드를 이용하시면 됩니다.

getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); 
getWindow().setStatusBarColor(Color.TRANSPARENT);

이 레이아웃을 기본 레이아웃에 포함합니다.

toolbar.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/toolbarNav"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        app:contentInsetEnd="0dp"
        app:contentInsetLeft="0dp"
        app:contentInsetRight="0dp"
        app:contentInsetStart="0dp">

        <RelativeLayout
            android:id="@+id/rlBackImageLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/main_background2">  //add your color here

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="@dimen/_40sdp"
                android:layout_marginTop="@dimen/_16sdp"
                android:orientation="horizontal">

                <ImageView
                    android:id="@+id/toolbarIcon"
                    android:layout_width="@dimen/_30sdp"
                    android:layout_height="@dimen/_30sdp"
                    android:layout_gravity="center"
                    android:layout_marginStart="@dimen/_10sdp"
                    android:padding="@dimen/_5sdp"
                    android:src="@drawable/nav_icon" />

                <TextView
                    android:id="@+id/txtTitle"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_gravity="center"
                    android:layout_marginEnd="@dimen/_30sdp"
                    android:fontFamily="@font/muli_semibold"
                    android:gravity="center"
                    android:textColor="#fff"
                    android:textSize="@dimen/_14ssp"
                    android:textStyle="bold"
                    tools:text="test Data" />

            </LinearLayout>

        </RelativeLayout>

    </androidx.appcompat.widget.Toolbar>

참고: SDP와 SSP를 각각 dp와 sp로 대체할 수 있습니다.

언급URL : https://stackoverflow.com/questions/29311078/android-completely-transparent-status-bar

반응형