แถบสถานะโปร่งใสอย่างสมบูรณ์?


184

ฉันได้สืบค้นเอกสารแต่เพียงพบนี้: การเชื่อมโยง สิ่งที่ใช้ในการทำแถบโปร่งแสง ? สิ่งที่ฉันพยายามทำคือการทำให้แถบสถานะโปร่งใสอย่างสมบูรณ์ (ดังที่แสดงในภาพด้านล่าง) และทำให้ย้อนกลับเข้ากันได้กับ APK <19: ป้อนคำอธิบายรูปภาพที่นี่

สไตล์ของฉัน 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>

สิ่งที่ฉันสามารถทำได้:

ป้อนคำอธิบายรูปภาพที่นี่

คำตอบ:


369

สิ่งที่คุณต้องทำคือตั้งค่าคุณสมบัติเหล่านี้ในธีมของคุณ:

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

โครงร่างกิจกรรม / คอนเทนเนอร์ของคุณที่คุณต้องการให้มีแถบสถานะโปร่งใสต้องการชุดคุณสมบัตินี้:

android:fitsSystemWindows="true"

โดยทั่วไปแล้วไม่สามารถดำเนินการนี้ได้อย่างแน่นอนใน pre-kitkat ดูเหมือนว่าคุณสามารถทำได้แต่มีรหัสแปลก ๆ ที่ทำให้มันเป็นเช่นนั้น

แก้ไข: ฉันจะแนะนำ lib นี้: https://github.com/jgilfelt/SystemBarTintสำหรับการควบคุมสีแถบสถานะล่วงหน้า lollipop จำนวนมาก

หลังจากใคร่ครวญมากฉันได้เรียนรู้ว่าคำตอบสำหรับการปิดการใช้งาน translucency หรือสีใด ๆ ที่วางอยู่บนแถบสถานะและแถบนำทางสำหรับอมยิ้มคือการตั้งค่าสถานะนี้บนหน้าต่าง:

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

ไม่จำเป็นต้องใช้ชุดรูปแบบอื่นมันสร้างสิ่งนี้:

ป้อนคำอธิบายรูปภาพที่นี่


21
ฉันใช้รหัสแล้วเพิ่มรูปภาพเป็นพื้นหลังแล้วเพิ่มลงandroid:fitsSystemWindows="true"ใน activity_main.xml ของฉัน แถบระบบโปร่งแสงและไม่โปร่งใส
มูฮัมหมัดอาลีมี. ค.

9
ดีผมเชื่อว่าทุกสิ่งที่คุณต้องการในกรณีที่ว่านั้นก็คือการเพิ่ม<item name="android:statusBarColor">@android:color/transparent</item>รูปแบบของคุณ :)
แดเนียลวิลสัน

7
ใช่เราขอขอบคุณสำหรับความอดทนของคุณฉันเกือบจะเอียงเนื่องจากฉันพยายามทำสิ่งนี้ในสองสามชั่วโมงที่ผ่านมา xD รหัสด้านบนไม่ทำงาน แต่ฉันตั้งค่าเป็นandroid:windowTranslucentStatusเท็จและทำให้แถบสถานะโปร่งใส ตอนนี้ฉันทำสิ่งเดียวกันกับแถบนำทางและเพิ่ม<item name="android:navigationBarColor">@android:color/transparent</item>แต่มันทำให้แถบทั้งสองเป็นสีเทา ฮึ!
มูฮัมหมัดอาลี

4
เพื่อให้การใช้งาน "adjustPan" ใช้ w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);แทน
Arda Kara

4
หมายเหตุ: การใช้การตั้งค่าสถานะ FLAG_LAYOUT_NO_LIMITS จะทำให้เค้าโครงของคุณอยู่ใต้แถบนำทางเสมือนที่ด้านล่าง โดยทั่วไปคุณไม่ต้องการทำสิ่งนี้ ... ดังนั้นสิ่งที่คนอื่น ๆ พูด :-(
kenyee

23

เพียงเพิ่มรหัสบรรทัดนี้ลงในไฟล์ java หลักของคุณ:

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

45
สิ่งนี้มีผลต่อแถบนำทางด้วยเช่นกัน
นักพัฒนา android

16

คุณสามารถใช้ห้องสมุดภายนอกStatusBarUtil :

เพิ่มในระดับโมดูลของคุณbuild.gradle:

compile 'com.jaeger.statusbarutil:library:1.4.0'

จากนั้นคุณสามารถใช้ประโยชน์ต่อไปนี้สำหรับกิจกรรมเพื่อทำให้แถบสถานะโปร่งใส:

StatusBarUtil.setTransparent(Activity activity)

ตัวอย่าง:

แถบสถานะโปร่งใสบน Lollipop และ KitKat


วิธีการทำเช่นนี้สำหรับการนำทางลิ้นชัก?
Reejesh PK

24
lib เพียงเพื่อแก้ปัญหานี้มันเหมือนแสงเทียนกับเครื่องพ่นไฟ
Felipe Castilhos

@FelipeCastilhos ใช่ แต่ถ้าคุณทำสิ่งต่าง ๆ มากมายด้วยแถบสถานะและคุณไม่ต้องการจัดการกับ API ที่ไม่ดีของ Google ที่มีให้คุณ
David Rawson

@DavidRawson ที่เป็นสถานการณ์ที่แตกต่าง ที่นี่เรากำลังพูดถึงเพิ่มความโปร่งใสเท่านั้น ทำไมต้องเพิ่มรหัสบุคคลที่สามมากขึ้นใน codebase ของคุณเพื่อจัดการกับมัน
Felipe Castilhos

14

ใช้งานได้กับ Android KitKat ขึ้นไป (สำหรับผู้ที่ต้องการทำให้แถบสถานะโปร่งใสและไม่ใช้ NavigationBar เพราะคำตอบเหล่านี้ทั้งหมดจะทำให้ NavigationBar โปร่งใสเช่นกัน!)

วิธีที่ง่ายที่สุดในการบรรลุเป้าหมาย:

ใส่รหัส 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วิธีการของกิจกรรม:

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

แค่นั้นแหละ!


1
เนื่องจากประสบการณ์ของฉันในการตอบโต้ดั้งเดิม ... รหัสด้านบนมีข้อขัดแย้งกับการแสดงแป้นพิมพ์ (adjustResize) ดังนั้นฉันเพิ่งเปลี่ยนแปลงเล็กน้อย: `` `if (Build.VERSION.SDK_INT> = 19) {getWindow (). getDecorView (). setSystemUiVisibility (View.SYSTEM_UI_FLAG_LAYOUT_STABLE); } `` `และในส่วนประกอบ` `` <StatusBar translucent = {true} backgroundColor = "transparent" /> `` `และใน AppManisfes - MainActivity` `` android: windowSoftInputMode = "adjustResize" " เหมือนกัน. fyi: `` `" react-native ":" 0.61.5 ",` `` ขอบคุณ @parsa dadras
Rudi Wijaya

12

แถบสถานะโปร่งใสและแถบนำทางอย่างสมบูรณ์

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

ทางออกเดียวที่ใช้งานได้จริงสำหรับฉันพร้อมกับโหมดคีออสก์ (การปักหน้าจอ)
Brontes

11

ในการวาดเค้าโครงของคุณใต้แถบสถานะ:

ค่า / 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>

ผลลัพธ์:

ภาพหน้าจอ:
ภาพหน้าจอ


10

คุณสามารถใช้รหัสด้านล่างเพื่อทำให้แถบสถานะโปร่งใส ดูภาพด้วยไฮไลท์สีแดงซึ่งช่วยให้คุณระบุการใช้งานของรหัสด้านล่าง

1]

ตัวอย่างโค้ด Kotlin สำหรับแอพ Android ของคุณ

ขั้นตอนที่: 1จดรหัสในการสร้างวิธี

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:คุณต้องใช้วิธี SetWindowFlag ซึ่งอธิบายไว้ในโค้ดด้านล่าง

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
}

ตัวอย่างโค้ด Java สำหรับแอป Android ของคุณ:

ขั้นที่ 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:วิธี SetWindowFlag

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

1
ฉันแค่แบ่งปันรหัสของฉันกับชุมชนนักพัฒนาของเราเพื่อช่วย 😊
CodeInsideCofee


5

นี่คือส่วนขยายใน 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
    }
}

4

เมื่อใช้รหัสนี้ใน 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">

3

มีสามขั้นตอนดังนี้

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 ขึ้นไป


2

นอกจากนี้คุณยังสามารถดูตัวอย่างของฉันด้วย avatar เคลื่อนไหวและข้อความเคลื่อนไหว

CollapsingAvatarToolbarSample

อ่านโพสต์ของฉันในสื่อ

ดังนั้นให้ฉันอธิบายวิธีการทำงาน ฉันสร้างที่กำหนดเอง view ดำเนิน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)
                    }
                }
            }

ในการตรวจจับเมื่อต้องการให้ภาพอนิเมชั่นล่มสร้างวัตถุคู่

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

2

คุณอาจลองสิ่งนั้น

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

1

ในขณะที่คำตอบทั้งหมดข้างต้นหมุนเวียนไปรอบ ๆ แนวคิดพื้นฐานเดียวกันและคุณสามารถทำให้มันทำงานกับเลย์เอาต์ที่เรียบง่ายโดยใช้หนึ่งในตัวอย่างข้างต้น อย่างไรก็ตามฉันต้องการเปลี่ยนสีของพื้นหลังในขณะที่ใช้แถบเลื่อน 'เต็มหน้าจอ' (แถบแท็บกัน) เลื่อนส่วนและรักษาการนำทางปกติแท็บและแถบการกระทำ

หลังจากอ่านบทความอย่างหนึ่งโดย Anton Hadutskiฉันก็เข้าใจดีขึ้นว่าเกิดอะไรขึ้น

ฉันมีDrawerLayoutกับConstraintLayout(เช่นคอนเทนเนอร์) ซึ่งมีToolbarรวมถึงชิ้นส่วนหลักและBottomNavigationViewรวมสำหรับชิ้นส่วนหลักและ

การตั้งค่าDrawerLayoutมีfitsSystemWindowsจริงไม่เพียงพอคุณจะต้องตั้งทั้งในและDrawerLayout ConstraintLayoutสมมติว่าแถบสถานะโปร่งใสสีของแถบสถานะจะเหมือนกับสีพื้นหลังของConstraintLayoutสมมติแถบสถานะโปร่งใสสีแถบสถานะตอนนี้เป็นเช่นเดียวกับสีพื้นหลังของ

อย่างไรก็ตามส่วนที่รวมอยู่นั้นยังคงมีแถบสถานะแทรกดังนั้นการแยกส่วนของ 'เต็มหน้าจอ' อีกอันที่ด้านบนของด้วยจะไม่เปลี่ยนสีของแถบสถานะ

เล็กน้อยรหัสจากบทความที่อ้างถึงเป็นActivityของonCreate:

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 (โปรดทราบว่า marginTop 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>

1

ฉันพบว่าการเล่นซอกับสไตล์.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);

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

และนั่นคือทั้งหมดที่ใช้เพื่อให้ได้แถบสถานะโปร่งใส หวังว่านี่จะช่วยได้


0

android:fitsSystemWindows="true"ใช้งานได้กับ v21 เท่านั้น เราสามารถตั้งค่าในรูปแบบ XML รูปแบบหรือในรูปแบบที่พ่อแม่ชอบหรือLinearLayout CoordinateLayoutต่ำกว่า v21 เราไม่สามารถเพิ่มธงนี้ โปรดสร้างโฟลเดอร์ค่าที่แตกต่างกันพร้อมstyle.xmlไฟล์ต่าง ๆ ตามที่คุณต้องการ


0

สิ่งนี้ใช้ได้กับฉัน:

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

0

สิ่งที่ทุกคนต้องการคือเข้าไป 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);

    }

อย่างไรก็ตามฉันจะได้รับข้อบกพร่องที่น่ากลัวเมื่อฉันเริ่มเลื่อนลง

0

ในกรณีของฉันเนื่องจากฉันเป็นแถบเครื่องมือด้านล่างฉันมีปัญหาเมื่อทดสอบวิธีแก้ไขปัญหาก่อนหน้านี้ปุ่มระบบ android ถูกปกคลุมด้วยเมนูด้านล่างของฉันโซลูชันของฉันคือการเพิ่มในกิจกรรม:

โมฆะป้องกัน onCreate (บันเดิลที่บันทึกไว้InstanceState) {super.onCreate (บันทึกไว้InstanceState);

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

0

คุณสามารถใช้รหัสด้านล่างนี้

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 ตามลำดับ


0

ในกรณีของฉันฉันไม่เรียกเลยว่า "onCreate" (มันเป็นแอพเนทีฟที่ตอบสนองและสิ่งนี้สามารถแก้ไขได้ด้วยการใช้คอมโพเนนต์ StatusBar แบบตอบสนองดั้งเดิม) คุณสามารถใช้สิ่งนี้:

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
}

0

สิ่งนี้น่าจะใช้ได้

// ใน Activity ของ onCreate ()

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

0

ฉันพบคำตอบขณะตรวจสอบห้องสมุดนี้: https://github.com/laobie/StatusBarUtil

ดังนั้นคุณต้องเพิ่มรหัสต่อไปนี้ในกิจกรรมของคุณ

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

0

เพิ่มบรรทัดเหล่านี้ในกิจกรรมของคุณก่อน 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

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


-1

นี่เป็นเพียงระดับ 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
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.