Durum çubuğu üzerinde Gezinme Çekmecesi yarı şeffaf çalışmıyor


86

Android projesi üzerinde çalışıyorum ve Gezinme Çekmecesini uyguluyorum. Yeni Materyal Tasarım Spesifikasyonu ve Materyal Tasarım Kontrol Listesini okuyorum .
Spesifikasyon, dışarı kayan bölmenin durum çubuğu dahil her şeyin üzerinde durması ve durum çubuğu üzerinde yarı saydam olması gerektiğini söylüyor.

Gezinme panelim durum çubuğunun üzerinde ancak şeffaflığı yok. Bu SO gönderisindeki kodu , Google geliştiricileri blog bölümünde önerilen şekilde takip ettim , yukarıdaki bağlantı DrawerLayout'u ActionBar / Araç Çubuğu üzerinde ve durum çubuğunun altında görüntülemek için nasıl kullanabilirim? .

Aşağıda XML düzenim var

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/my_drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <android.support.v7.widget.Toolbar
            android:id="@+id/my_awesome_toolbar"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:minHeight="?attr/actionBarSize"
            android:background="@color/appPrimaryColour" />
    </LinearLayout>
    <LinearLayout android:id="@+id/linearLayout"
        android:layout_width="304dp"
        android:layout_height="match_parent"
        android:layout_gravity="left|start"
        android:fitsSystemWindows="true"
        android:background="#ffffff">
        <ListView android:id="@+id/left_drawer"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:choiceMode="singleChoice"></ListView>
    </LinearLayout>
</android.support.v4.widget.DrawerLayout>

Aşağıda uygulamalar temam var

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">@color/appPrimaryColour</item>
        <item name="colorPrimaryDark">@color/appPrimaryColourDark</item>
        <item name="colorAccent">@color/appPrimaryColour</item>
        <item name="windowActionBar">false</item>
        <item name="windowActionModeOverlay">true</item>

    </style>

Aşağıda benim uygulamalarım v21 teması

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/appPrimaryColour</item>
    <item name="colorPrimaryDark">@color/appPrimaryColourDark</item>
    <item name="colorAccent">@color/appPrimaryColour</item>
    <item name="windowActionBar">false</item>
    <item name="windowActionModeOverlay">true</item>
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:statusBarColor">@android:color/transparent</item>
</style>

Aşağıda onCreate yöntemim var

protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
    setSupportActionBar(toolbar);

    mDrawerLayout = (DrawerLayout)findViewById(R.id.my_drawer_layout);
    mDrawerList = (ListView)findViewById(R.id.left_drawer);

    mDrawerLayout.setStatusBarBackgroundColor(
        getResources().getColor(R.color.appPrimaryColourDark));

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
    {
        LinearLayout linearLayout = 
            (LinearLayout)findViewById(R.id.linearLayout);
        linearLayout.setElevation(30);
    }

Aşağıda, gezinme çekmecemin üst kısmının yarı şeffaf olmadığını gösteren bir ekran görüntüsü var

Durum çubuğunun üzerinde şeffaf olmayanları gösteren ekran görüntüsü


Sonuçlarınızın ekran görüntüsünü yayınlayın.
Alok Nair

@Boardy, onu çalıştırmayı başardınız mı?
Michele La Ferla

Durum çubuğunda Şeffaf efekti ayarlanamıyor.Pl kurtulun.
Ronak Gadhia

Yanıtlar:


103

Durum çubuğu arka planınız beyazdır, çekmecenizin arka planı LinearLayout. Neden? Siz fitsSystemWindows="true"kendiniz DrawerLayoutve LinearLayoutonun için ayarısınız. Bu , durum çubuğunun (şeffaf olan) arkasınaLinearLayout genişlemenize neden olur . Böylece, durum çubuğunun çekmece kısmının arka planı beyaz olur.

görüntü açıklamasını buraya girin
Çekmecenizin durum çubuğunun arkasına uzanmasını istemiyorsanız (tüm durum çubuğu için yarı şeffaf bir arka plana sahip olmak istiyorsanız), iki şey yapabilirsiniz:

1) Herhangi bir arka plan değerini sizden kaldırabilir LinearLayoutve içindeki içeriğinizin arka planını renklendirebilirsiniz. Veya

2) fitsSystemWindows="true"sizden kaldırabilirsiniz LinearLayout. Bunun daha mantıklı ve daha temiz bir yaklaşım olduğunu düşünüyorum. Ayrıca, gezinme çekmecenizin genişlemediği durumlarda durum çubuğunun altına gölge düşmesini de önleyeceksiniz.

görüntü açıklamasını buraya girin
Çekmecenizin durum çubuğunun arkasına uzanmasını ve yarı şeffaf, durum çubuğu boyutunda bir kaplamaya sahip olmasını istiyorsanız, ScrimInsetFrameLayoutçekmece içeriğiniz için bir kap olarak kullanabilir ( ListView) ve ile durum çubuğu arka planını ayarlayabilirsiniz app:insetForeground="#4000". Elbette, istediğiniz #4000herhangi bir şeye değiştirebilirsiniz . fitsSystemWindows="true"Burada tutmayı unutma !

Veya içeriğinizi kaplamak istemiyor ve yalnızca düz bir renk görüntülemek istiyorsanız, LinearLayout istediğiniz herhangi bir şeye . Yine de içeriğinizin arka planını ayrı ayrı ayarlamayı unutmayın!

DÜZENLEME: Artık bunların hiçbiriyle uğraşmanıza gerek yok. Daha kolay Gezinme Çekmecesi / Görünüm uygulaması için lütfen Tasarım Destek Kitaplığı'na bakın .


Yardımınız için teşekkürler. Geri dönmedeki gecikme için üzgünüm, çok meşguldüm. Başlangıçta belirlediğim gibi cevabınızı ödüllendirmek için başka bir ödül ayarladım, ancak önerilerinizi uygulamak için zamanım olmadan bitti. Maalesef 23 saat beklemem gerekiyor, bu yüzden elimden geldiğince çabuk ekleyeceğim
Boardy

Dikkat! 1. veya 2. seçeneklerle, fazla para çekme işlemlerinizi izlediğinizden emin olun (bunları telefon ayarlarındaki geliştirme seçeneklerinde kontrol edebilirsiniz). Sadece içeriğin arka planını ayarladığımda çekmecenin arkasındaki her şey de çiziliyordu. Aksi takdirde harika cevap, kesinlikle bana biraz zaman kazandırdı :)
Daiwik Daarun

1
Tasarım destek kitaplığını kullanarak hangi çözümü kullanmamız gerektiğini açıklar mısınız? Chris Banes'in gönderdiği cevapla bile bazı sorunlar yaşıyorum.
mDroidd

29

Tek yapmanız gereken, durum çubuğu için bazı yarı saydam renkler kullanmaktır. Bu satırları v21 temanıza ekleyin:

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

Unutmayın, color(kaynak) her zaman biçiminde olmalıdır #AARRGGBB. Bu, rengin alfa değerini de içereceği anlamına gelir.


Adam sensin, ama ... Bunun neden sadece Çekmeceli Aktivitede işe yaradığını söyleyebilir misin? Diğerleri, olmayanlar, Durum çubuğunu gri gösterirler.
Joaquin Iurchuk

15

Neden buna benzer bir şey kullanmıyorsunuz?

<android.support.v4.widget.DrawerLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >

    <FrameLayout
            android:id="@+id/content_frame"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

    <ListView
            android:id="@+id/left_drawer"
            android:layout_width="240dp"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:choiceMode="singleChoice"
            android:divider="@android:color/transparent"
            android:dividerHeight="0dp"
            android:background="#80111111"/>
</android.support.v4.widget.DrawerLayout>

Yukarıdaki kod, alfa kaynağını kullanır. android:background , işlem çubuğu içinde şeffaflığı gösterebilmek .

Diğer yanıtların gösterdiği gibi bunu kodla yapmanın başka yolları da var. Yukarıdaki cevabım, bence kolayca düzenlenebilen xml düzen dosyasında gerekli olanı yapıyor.


4
Neden olmasın, ama neyi değiştirdiğiniz ve bunun soruyu nasıl yanıtladığı belli değil.
rds

bölücüyü şeffaf olarak ayarla ve arka plan renginde kullanılan alfa kodları
Michele La Ferla

9

Burada bahsedilen tüm cevaplar çok eski ve uzundur. En son Navigationview ile çalışan en iyi ve kısa çözüm,

@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
    super.onDrawerSlide(drawerView, slideOffset);

    try {
        //int currentapiVersion = android.os.Build.VERSION.SDK_INT;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP){
            // Do something for lollipop and above versions

        Window window = getWindow();

        // clear FLAG_TRANSLUCENT_STATUS flag:
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

        // add FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag to the window
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

        // finally change the color to any color with transparency

         window.setStatusBarColor(getResources().getColor(R.color.colorPrimaryDarktrans));}

    } catch (Exception e) {

        Crashlytics.logException(e);

    }
}

bu, çekmeceyi açtığınızda durum çubuğu renginizi şeffaf hale getirecek

Şimdi çekmeceyi kapattığınızda durum çubuğu rengini tekrar koyulaştırmanız gerekiyor, yani bu şekilde yapabilirsiniz.

@Override
public void onDrawerClosed(View drawerView) {
   super.onDrawerClosed(drawerView);
    try {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            // Do something for lollipop and above versions

            Window window = getWindow();

            // clear FLAG_TRANSLUCENT_STATUS flag:
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

            // add FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag to the window
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

            // finally change the color again to dark
            window.setStatusBarColor(getResources().getColor(R.color.colorPrimaryDark));
        }
    } catch (Exception e) {
        Crashlytics.logException(e);
    }
}

ve ardından ana düzende tek bir satır ekleyin yani

            android:fitsSystemWindows="true"

ve çekmece düzeniniz şöyle görünecek

            <android.support.v4.widget.DrawerLayout     
            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/drawer_layout"
            android:fitsSystemWindows="true"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

ve navigasyon görünümünüz şöyle görünecek

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_height="match_parent"
        android:layout_width="wrap_content"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/navigation_header"
        app:menu="@menu/drawer"
        />

Test ettim ve tamamen çalışıyor, umarım birine yardımcı olur Bu en iyi yaklaşım olmayabilir ama sorunsuz çalışıyor ve uygulaması basit. Yardımcı olacaksa işaretleyin. Mutlu kodlama :)


Teşekkürler! Bu bana çok zaman kazandırdı. En son NavigationView ile mükemmel çalışıyor. Bunun çalışmasını sağlayamayan herkes için, "colorPrimaryDarktrans" için biraz şeffaflık içeren bir renk seçtiğinizden emin olun, aksi takdirde hiçbir değişiklik göremezsiniz.
Rui

OnDrawerClosed çağrıldığında tek dezavantajı bu durum çubuğu 'yanıp sönme' dir, mükemmel çalışıyor ama # 05000000 şeffaf renk colorPrimaryDarktrans set eğer hemen hemen hiç fark var
Kirill Karmazin

8

Gezinme çekmecesi düzeninizi bir ScrimLayout.

Bir ScrimLayouttemelde gezinme çekmecesi düzeni üzerinde yarı saydam bir dikdörtgen çizer. İçerlek boyutunu almak için basitçe geçersiz fitSystemWindowsGözlerinde farklı ScrimLayout.

@Override
protected boolean fitSystemWindows(Rect insets) {
    mInsets = new Rect(insets);
    return true;
}

onDrawYarı saydam bir dikdörtgen çizmek için daha sonra geçersiz kıl.

Bir örnek uygulama, Google IO App kaynağında bulunabilir. Burada xml düzeninde nasıl kullanıldığını görebilirsiniz.


5

Gezinme panelinin durum çubuğunun üzerinde olmasını ve durum çubuğunun üzerinde yarı şeffaf olmasını istiyorsanız. Google I / O Android Uygulama Kaynağı iyi bir çözüm sunar ( APK Play Store'da son sürüme güncellenmez)

Önce bir ScrimInsetFrameLayout'a ihtiyacınız var

/*
* Copyright 2014 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* A layout that draws something in the insets passed to {@link #fitSystemWindows(Rect)}, i.e. the area above UI chrome
* (status and navigation bars, overlay action bars).
*/
public class ScrimInsetsFrameLayout extends FrameLayout {
    private Drawable mInsetForeground;

    private Rect mInsets;
    private Rect mTempRect = new Rect();
    private OnInsetsCallback mOnInsetsCallback;

    public ScrimInsetsFrameLayout(Context context) {
        super(context);
        init(context, null, 0);
    }

    public ScrimInsetsFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public ScrimInsetsFrameLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    private void init(Context context, AttributeSet attrs, int defStyle) {
        final TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.ScrimInsetsView, defStyle, 0);
        if (a == null) {
            return;
        }
        mInsetForeground = a.getDrawable(R.styleable.ScrimInsetsView_insetForeground);
        a.recycle();

        setWillNotDraw(true);
    }

    @Override
    protected boolean fitSystemWindows(Rect insets) {
        mInsets = new Rect(insets);
        setWillNotDraw(mInsetForeground == null);
        ViewCompat.postInvalidateOnAnimation(this);
        if (mOnInsetsCallback != null) {
            mOnInsetsCallback.onInsetsChanged(insets);
        }
        return true; // consume insets
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);

        int width = getWidth();
        int height = getHeight();
        if (mInsets != null && mInsetForeground != null) {
            int sc = canvas.save();
            canvas.translate(getScrollX(), getScrollY());

            // Top
            mTempRect.set(0, 0, width, mInsets.top);
            mInsetForeground.setBounds(mTempRect);
            mInsetForeground.draw(canvas);

            // Bottom
            mTempRect.set(0, height - mInsets.bottom, width, height);
            mInsetForeground.setBounds(mTempRect);
            mInsetForeground.draw(canvas);

            // Left
            mTempRect.set(0, mInsets.top, mInsets.left, height - mInsets.bottom);
            mInsetForeground.setBounds(mTempRect);
            mInsetForeground.draw(canvas);

            // Right
            mTempRect.set(width - mInsets.right, mInsets.top, width, height - mInsets.bottom);
            mInsetForeground.setBounds(mTempRect);
            mInsetForeground.draw(canvas);

            canvas.restoreToCount(sc);
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (mInsetForeground != null) {
            mInsetForeground.setCallback(this);
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (mInsetForeground != null) {
            mInsetForeground.setCallback(null);
        }
    }

    /**
     * Allows the calling container to specify a callback for custom processing when insets change (i.e. when
     * {@link #fitSystemWindows(Rect)} is called. This is useful for setting padding on UI elements based on
     * UI chrome insets (e.g. a Google Map or a ListView). When using with ListView or GridView, remember to set
     * clipToPadding to false.
     */
    public void setOnInsetsCallback(OnInsetsCallback onInsetsCallback) {
        mOnInsetsCallback = onInsetsCallback;
    }

    public static interface OnInsetsCallback {
        public void onInsetsChanged(Rect insets);
    }
}

Ardından, XML düzeninizde bu bölümü değiştirin

<LinearLayout android:id="@+id/linearLayout"
    android:layout_width="304dp"
    android:layout_height="match_parent"
    android:layout_gravity="left|start"
    android:fitsSystemWindows="true"
    android:background="#ffffff">
    <ListView android:id="@+id/left_drawer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:choiceMode="singleChoice"></ListView>
</LinearLayout>

LinearLayout'u ScrimInsetFrameLayout'unuza bu şekilde değiştirin

<com.boardy.util.ScrimInsetFrameLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/linearLayout"
    android:layout_width="304dp"
    android:layout_height="match_parent"
    android:layout_gravity="left|start"
    android:fitsSystemWindows="true"
    app:insetForeground="#4000">
    <ListView android:id="@+id/left_drawer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:choiceMode="singleChoice"></ListView>
</com.boardy.util.ScrimInsetFrameLayout>

Merhaba, cevabınız için teşekkürler .. OnInsetsCallback'i aldığımız yerden bulamıyorum ... Şimdiden teşekkürler.
Ashokchakravarthi Nagarajan

özelliği koyabilir misin ScrimInsetsView_insetForeground?
reegan29

1
android.support.design.internal.ScrimInsetsFrameLayoutDestek kitaplığından kullanın
Roman

3

Projemde uygulamak için benzer bir özellik vardı. Çekmecemi şeffaf yapmak için sadece şeffaflığı altıgen renkler için kullanıyorum . 6 onaltılık basamak kullanarak, sırasıyla kırmızı, yeşil ve mavinin her bir değeri için 2 onaltılık basamağa sahip olursunuz. ancak iki ek basamak (8 onaltılık basamak) koyarsanız, ARGB'niz olur (alfa değeri için iki basamak) ( Buraya bakın ).

İşte Hex Opaklık Değerleri: 2 ek basamak için

100% — FF
95% — F2
90% — E6
85% — D9
80% — CC
75% — BF
70% — B3
65% — A6
60% — 99
55% — 8C
50% — 80
45% — 73
40% — 66
35% — 59
30% — 4D
25% — 40
20% — 33
15% — 26
10% — 1A
5% — 0D
0% — 00

Örneğin, onaltılık renk (# 111111) varsa, şeffaflık elde etmek için opaklık değerlerinden birini girin. bunun gibi: (# 11111100)

Çekmecem eylem çubuğunu kapatmıyor (sizinki gibi) ancak şeffaflık bu durumlarda da uygulanabilir. İşte kodum:

     <ListView
          android:id="@+id/left_drawer"
          android:layout_width="240dp"
          android:layout_height="match_parent"
          android:layout_gravity="start"
          android:background="#11111100"
          android:choiceMode="singleChoice"
          android:divider="@android:color/transparent"
          android:dividerHeight="0dp" />
</android.support.v4.widget.DrawerLayout>

Ve işte alfa kodlarını onaltılık renklerde anlamanıza yardımcı olabilecek başka bir makale .


1

Mevcut çözümler oldukça eskidir. İşte AndroidX veya Material kitaplıklarında mükemmel çalışması gereken en son çözüm.

  • Ekle android:fitsSystemWindows="true" dava için DrawerLayout olur düzeninizi, kök Görünüm.

    Bu, View'e tüm ekranı ölçü ve düzen için durum çubuğuyla örtüşerek kullanmasını söyler.

  • Aşağıdakileri XML stilinize ekleyin

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

    windowTranslucentStatusdurum çubuğunu şeffaf hale getirecek, durum çubuğuna
    windowDrawsSystemBarBackgroundssiyah boşluk olmak yerine altına herhangi bir şey çizmesini söyler.

  • Arayın DrawerLayout.setStatusBarBackground()veya DrawerLayout.setStatusBarBackgroundColor()ana Aktivitenizde

    Bu, DrawerLayout'a durum çubuğu alanını renklendirmesini söyler.


0

Buradaki tüm cevaplar çok karmaşık, size basit bir kod vereyim. AppTheme stilinizin altına bu kod satırını ekleyin ve çekmeceyi açtığınızda gri renkli yarı şeffaf bir durum çubuğu göreceksiniz.

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

bu onu çalıştıracak.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.