ActionBar / Araç Çubuğu ve durum çubuğunun altında görüntülemek için DrawerLayout'u nasıl kullanabilirim?


394

Yeni malzeme tasarımında Side Nav spec'te çekmeceyi eylem çubuğunun üzerinde ve durum çubuğunun arkasında görüntüleyebileceğinizi gördüm . Bunu nasıl uygulayabilirim?


4
Bugün bile geriye dönük uyumlulukla çalışan açık bir cevap yoktur. Bu tür konular gerçekten herhangi bir programcıyı kızdırır. Zaten "N" API ve Android sisteminde geliştirmek için birçok temel yönleri teşvik.
Val Martinez

Yanıtlar:


528

Çerçeve ve destek kütüphanelerindeki yeni işlevler tam olarak buna izin verir. Üç 'bulmacanın parçaları' vardır:

  1. Eylem çubuğunuzu görünüm hiyerarşinize yerleştirebilmeniz için Araç Çubuğu'nu kullanma .
  2. DrawerLayout'u fitsSystemWindows sistem çubuklarının arkasına yerleştirilecek şekilde yapma .
  3. Theme.MaterialDrawerLayout öğesinin bunun yerine çizim yapabilmesi için normal durum çubuğu renklendirmesini devre dışı bırakmak .

Yeni uygulama paketini kullanacağınızı varsayacağım.

İlk olarak, düzeniniz şöyle görünmelidir:

<!-- The important thing to note here is the added fitSystemWindows -->
<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">

    <!-- Your normal content view -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!-- We use a Toolbar so that our drawer can be displayed
             in front of the action bar -->
        <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="?attr/colorPrimary" />

        <!-- The rest of your content view -->

    </LinearLayout>

    <!-- Your drawer view. This can be any view, LinearLayout
         is just an example. As we have set fitSystemWindows=true
         this will be displayed under the status bar. -->
    <LinearLayout
        android:layout_width="304dp"
        android:layout_height="match_parent"
        android:layout_gravity="left|start"
        android:fitsSystemWindows="true">

        <!-- Your drawer content -->

    </LinearLayout>

</android.support.v4.widget.DrawerLayout>

Ardından Faaliyetinizde / Parçanızda:

public void onCreate(Bundled savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Your normal setup. Blah blah ...

    // As we're using a Toolbar, we should retrieve it and set it
    // to be our ActionBar
    Toolbar toolbar = (...) findViewById(R.id.my_awesome_toolbar);
    setSupportActionBar(toolbar);

    // Now retrieve the DrawerLayout so that we can set the status bar color.
    // This only takes effect on Lollipop, or when using translucentStatusBar
    // on KitKat.
    DrawerLayout drawerLayout = (...) findViewById(R.id.my_drawer_layout);
    drawerLayout.setStatusBarBackgroundColor(yourChosenColor);
}

Ardından, DrawerLayout öğesinin durum çubuğunun arkasında görünür olduğundan emin olmanız gerekir. Bunu, değerler-v21 temanızı değiştirerek yaparsınız:

değerler V21 / themes.xml

<style name="Theme.MyApp" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:statusBarColor">@android:color/transparent</item>
    <item name="android:windowTranslucentStatus">true</item>
</style>

Not: <fragment android:name="fragments.NavigationDrawerFragment">yerine a kullanılırsa

<LinearLayout
    android:layout_width="304dp"
    android:layout_height="match_parent"
    android:layout_gravity="left|start"
    android:fitsSystemWindows="true">

    <!-- Your drawer content -->

</LinearLayout>

gerçek düzende, yöntemden fitsSystemWindows(boolean)döndürdüğünüz bir görünümü çağırırsanız, istenen efekt elde edilir onCreateView.

@Override
public View onCreateView(LayoutInflater inflater, 
                         ViewGroup container,
                         Bundle savedInstanceState) {
    View mDrawerListView = inflater.inflate(
        R.layout.fragment_navigation_drawer, container, false);
    mDrawerListView.setFitsSystemWindows(true);
    return mDrawerListView;
}

3
Evet, DrawerLayoutsistem çubuklarının arkasına yerleştirilmesi gerekiyor. Ardından DrawerLayout, pencere iç metinlerine yerleştirilecek şekilde çekmece görünümünde ayarlamanız gerekir .
Chris Banes

11
Hiç işe yaramaz. Yeni bir demo uygulamasında yukarıdaki kodla sonuç, @ScootrNova'nın açıkladığı şeye benziyor. Bu ekran görüntüsüne bakın: imgur.com/QLk3syt
Michael Schmidt

6
Görünüşe göre layout_marginTopçekmece içeriğinizin düzeninde bir negatif kullanmanız gerekiyor . Aksi takdirde, çekmece içeriğinizin düzeninin arka planı durum çubuğunun üstüne çizilir ve diğer her şey aşağı itilir. Ancak bu, attr / statusBarSize veya Android tarafından sağlanan gibi bir şey olmadığını bildiğim kadarıyla biraz kaba bir çözüm gibi görünüyor.
Charles Madere

26
Çekmecenin durum çubuğundan görülebildiği efekti elde etmek için, android: fitsSystemWindows'u DrawerLayout'ta false değerine ayarladım, android: fitsSystemWindows ana içerik mizanpajımda (Araç Çubuğunu içeren düzen) ve <öğe adı = "android: windowTranslucentStatus"> Temama doğru </item> - Lollipop'ta
Jakob

8
Bu cevap eksik. Ayrıca gezinme çekmecenizi bir ScrimLayout içine sarmanız gerekir. Bkz. Stackoverflow.com/a/26926998/174149
Markus Hi

138

DÜZENLEME: Yeni Tasarım Destek Kitaplığı bunu destekler ve önceki yönteme artık gerek yoktur.

Bu, şimdi yeni Android Tasarım Destek Kütüphanesi kullanılarak gerçekleştirilebilir .

Tüm yeni özellikleri gösteren Chris Banes tarafından Cheesesquare örnek uygulamasını görebilirsiniz .


Önceki yöntem:

Hiçbir tam çözüm olmadığı için, istenen sonucu elde etmenin yolu budur.

İlk olarak projenize bir ScrimInsetsFrameLayout ekleyin.

/*
* 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, insetForegroundayarlanabilir bir stil oluşturun .

değerler / attrs.xml

<declare-styleable name="ScrimInsetsView">
    <attr name="insetForeground" format="reference|color" />
</declare-styleable>

Senin etkinliğin xml dosyası güncelleyin ve emin olun android:fitsSystemWindowshem true olarak ayarlanır DrawerLayoutyanı sıra ScrimInsetsFrameLayout.

düzen / activity_main.xml

<android.support.v4.widget.DrawerLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".MainActivity">

    <!-- The main content view -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!-- Your main content -->

    </LinearLayout>

    <!-- The navigation drawer -->
    <com.example.app.util.ScrimInsetsFrameLayout 
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/scrimInsetsFrameLayout"
        android:layout_width="320dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="@color/white"
        android:elevation="10dp"
        android:fitsSystemWindows="true"
        app:insetForeground="#4000">

        <!-- Your drawer content -->

    </com.example.app.util.ScrimInsetsFrameLayout>

</android.support.v4.widget.DrawerLayout>

Etkinliğinizin onCreate yönteminin içinde, durum çubuğu arka plan rengini çekmece düzeninde ayarlayın.

MainActivity.java

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

    // ...

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
    mDrawerLayout.setStatusBarBackgroundColor(
        getResources().getColor(R.color.primary_dark));
}

Son olarak, uygulamanızın temasını DrawerLayoutdurum çubuğunun arkasında olacak şekilde güncelleyin .

değerler V21 / styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:statusBarColor">@android:color/transparent</item>
</style>

Sonuç:


10
Bu benim için en iyisi oldu. Bu şeyi işe almak için 2 gün geçirdim ve bu bir. Bu Cevap olarak işaretlenmelidir. Çok teşekkür ederim.
kalehv

2
Ben appcompat kullanmıyorum ve bu işe yaramadı. :( Bu uygulama olmadan uyumak için herhangi bir rehber var mı?
Jared Rummler

3
Bu en mükemmel cevap. 4.X'den 5.X'e kadar çeşitli Android cihazlarda uyguladım ve test ettim ve mükemmel çalıştığını doğrulayabilirim. Çok teşekkürler.
Aritra Roy

2
Dediğim gibi, mükemmel çalışıyor, ama küçük bir sorunum var. Gezinme Çekmecesi'ndeki etkinliğin saydam durum çubuğu vardır, ancak diğer tüm etkinlikler durum çubuğundan "birincilDark" rengini kaybetmiştir. Nasıl geri alınır?
Aritra Roy

5
Çekmece parçasının etrafına sarılmış bu ek düzeni kullanmaktan başka bir yol olmadığını kabul etmek üç günümü aldı. Aksi takdirde durum çubuğu gri olur (ilk çocuğun arka plan rengi) veya çekmece durum çubuğunun altında görüntülenir.
Denis Loh

96

En son Android Destek Kitaplığı'nın (rev 22.2.0) piyasaya sürülmesiyle bir Tasarım Destek Kitaplığı var ve bunun bir parçası olarak NavigationView adlı yeni bir görünüm var . Bu yüzden her şeyi kendi ScrimInsetsFrameLayoutbaşımıza yapmak yerine ve diğer tüm şeyleri kullanmak yerine bu görüşü kullanırız ve her şey bizim için yapılır.

Misal

Aşama 1

Ekle Design Support Librarysizin için build.gradledosyanın

dependencies {
    // Other dependencies like appcompat
    compile 'com.android.support:design:22.2.0'
}

Adım 2

Şunu NavigationViewekleyin DrawerLayout:

<android.support.v4.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"> <!-- this is important -->

     <!-- Your contents -->

     <android.support.design.widget.NavigationView
         android:id="@+id/navigation"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:layout_gravity="start"
         app:menu="@menu/navigation_items" /> <!-- The items to display -->
 </android.support.v4.widget.DrawerLayout>

Aşama 3

Yeni bir menü kaynağı oluşturun /res/menuve görüntülemek istediğiniz öğeleri ve simgeleri ekleyin:

<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <group android:checkableBehavior="single">
        <item
            android:id="@+id/nav_home"
            android:icon="@drawable/ic_action_home"
            android:title="Home" />
        <item
            android:id="@+id/nav_example_item_1"
            android:icon="@drawable/ic_action_dashboard"
            android:title="Example Item #1" />
    </group>

    <item android:title="Sub items">
        <menu>
            <item
                android:id="@+id/nav_example_sub_item_1"
                android:title="Example Sub Item #1" />
        </menu>
    </item>

</menu>

4. Adım

NavigationView uygulamasını başlatın ve tıklama olaylarını işleyin:

public class MainActivity extends AppCompatActivity {

    NavigationView mNavigationView;
    DrawerLayout mDrawerLayout;

    // Other stuff

    private void init() {
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mNavigationView = (NavigationView) findViewById(R.id.navigation_view);
        mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(MenuItem menuItem) {
                mDrawerLayout.closeDrawers();
                menuItem.setChecked(true);
                switch (menuItem.getItemId()) {
                    case R.id.nav_home:
                        // TODO - Do something
                        break;
                    // TODO - Handle other items
                }
                return true;
            }
        });
    }
}

Adım 5

Sete emin olun android:windowDrawsSystemBarBackgroundsve android:statusBarColorde values-v21aksi takdirde Çekmece StatusBar "altında" görüntülenir `kazandı

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Other attributes like colorPrimary, colorAccent etc. -->
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:statusBarColor">@android:color/transparent</item>
</style>

İsteğe Bağlı Adım

NavigationView öğesine bir Başlık ekleyin. Bunun için yeni bir düzen oluşturun ve app:headerLayout="@layout/my_header_layout"NavigationView öğesine ekleyin .

Sonuç

navigasyon görünümünü gösteren resim

notlar

  • Vurgulanan renk ile tanımlanan renk kullanan colorPrimaryöznitelik
  • Liste Öğeleri kullanmak rengi aracılığıyla tanımlanan textColorPrimaryöznitelik
  • Simgeler kullanmak rengi aracılığıyla tanımlanan textColorSecondaryöznitelik

Ayrıca , Chris Banes tarafından NavigationView'i vurgulayan ve Design Support Library'nin ( FloatingActionButton , TextInputLayout , Snackbar , TabLayout vb. Gibi) diğer yeni görünümleri gösteren örnek uygulamayı da kontrol edebilirsiniz .


1
teşekkürler @reVerse !!. > Listedeki her öğeyi ve simgeyi stil dosyalarından güncellemek istiyorsan bunu kullanarak şunları yapabilirsin:<item name="itemTextColor">@color/YOUR_COLOR</item> <item name="itemIconTint">@color/YOUR_COLOR</item>
Juan Saravia

Seçilen öğenin arka plan rengini nasıl değiştirirsiniz?
Joop

2
Bu yaklaşım yine de ActionBar'ın arkasındaki NavigationView öğesini üretir.
southerton

1
@southerton, elbette, bir Toolbar- bunu kullanmanın bir yolu yokActionBar
reVerse

1
@ reegan29 mDrawerLayout.openDrawer(GravityCompat.START);İstediğiniz yeri arayın . Bir kullanıyorsanız ActionBarDrawerToggle, hamburger simgesine tıklar tıklamaz otomatik olarak yapılmalıdır.
Ters

6

Çalışmasını sağlayın, değerler-v21 stillerinde veya xml temasının bu özelliği kullanması gerekir:

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

Bu sihri yaratır!


3
Bu, eylem çubuğumun durum çubuğunun arkasında da görünmesini sağlar.
Michiel

Ama elde etmeye çalıştığımız etki, Gmail 5.0 uygulamasına bakmak mı? Durum çubuğunun arkasında Yan Çubuğu gösterir.
Nicolas Jafelle

Söylemek istediğim bu değil. Gezinti çekmecesi bu kod satırıyla durum çubuğunun arkasında olmasına rağmen, araç çubuğu / eylem çubuğu da öyle.
Michiel

2
Poster ve yanıtlayıcı, AppCompat'ı tasarlayan bir Google çalışanı olduğundan içeriği yazarken ne yaptığını bildiğinden eminim.
afollestad

@Mixx, Normal içerik görünümünüz için android: fitsSystemWindows = "true" değerini ayarlayabilirsiniz (örneğin, kabul edilen cevap mizanpajı alınırsa). Android 4.4 için bile çalışabilir. Ancak burada küçük bir fark var: Android 5.0'da durum çubuğundaki şeffaflık seviyesi GMail'den biraz daha yüksek (daha yüksek alfa değeri), durum çubuğunu daha da karanlık yapıyor.
Qianqian

6

Yukarıdaki tüm yaklaşımlar doğrudur ve çalışıyor olabilir. Yukarıdaki kılavuzu izleyerek çalışan bir demo oluşturdum ve 2.x - 5.x üzerinde test ettim

Github'dan klonlayabilirsiniz

Oynamak için önemli olan ana aktivitedir.

toolbar = (Toolbar) findViewById(R.id.toolbar);
res = this.getResources();

this.setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
    ScrimInsetsFrameLayout scrimInsetsFrameLayout = (ScrimInsetsFrameLayout)
            findViewById(R.id.linearLayout);
    scrimInsetsFrameLayout.setOnInsetsCallback(this);
} 

ve geri arama

@Override
public void onInsetsChanged(Rect insets) {
    Toolbar toolbar = this.toolbar;
    ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)
        toolbar.getLayoutParams();
    lp.topMargin = insets.top;
    int top = insets.top;
    insets.top += toolbar.getHeight();
    toolbar.setLayoutParams(lp);
    insets.top = top; // revert
}

Kesinlikle V21 için Tema sihir yapar

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- API 21 theme customizations can go here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/accent_material_light</item>
    <item name="windowActionModeOverlay">true</item>
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:statusBarColor">@android:color/transparent</item>
    <item name="android:windowTranslucentStatus">true</item>
</style>

ve ScrimInsetsFrameLayout

Yeni Tasarım Destek kütüphanesi ile bu artık daha kolay

compile 'com.android.support:design:22.2.0'

@Chris Banes üzerinden klon https://github.com/chrisbanes/cheesesquare


4

Burada bahsedilen tüm cevaplar çok eski ve uzundur.En yeni 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);

    }
}

çekmeceyi açtığınızda durum çubuğu renginizi saydam olarak değiştirir

Şimdi çekmeceyi kapattığınızda, durum çubuğu rengini tekrar koyu olarak değiştirmeniz gerekir, böylece bu şekilde yapabilirsiniz.

        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 sonra ana düzende tek bir satır ekleyin.

            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

    <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ışır ve uygulanması basittir. Yardımcı olursa işaretleyin.


Alternatif olarak, ActionBar'da özel bir görünüm kullanıyorsanız, özel görünümün görünürlüğünü onDrawerSlide () içinde INVISIBLE olarak ve onDrawerClosed () içinde VISIBLE olarak ayarlayabilirsiniz.
Milan

3

Tasarım Destek Kütüphanesi kullanıyorum. Ve sadece özel tema kullanarak Gezinti Çekmecesi açıldığında şeffaf Durum Çubuğu elde ettim.

resim açıklamasını buraya girin

resim açıklamasını buraya girin

<style name="NavigationStyle" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/primaryColor</item>
    <item name="colorPrimaryDark">@color/primaryColorDark</item>

    <!-- To Make Navigation Drawer Fill Status Bar and become Transparent Too -->
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:statusBarColor">@android:color/transparent</item>

</style>

Son olarak Manifest Dosyasına tema ekleyin

<activity
  ........
  ........
 android:theme="@style/NavigationStyle"> 
</activity>

android:fitsSystemWindows="true""DrawerLayout" içindeki özelliği kullanmayı unutmayın


1
api seviye 19 cihazlar için nasıl kullanılır?
AndroidGuy

2

Bu en basit ve benim için çalıştı:

Değerler-21'de:

<resources>
    <style name="AppTheme" parent="AppTheme.Base">
        ...
        <item name="android:windowTranslucentStatus">true</item>
    </style>
    <dimen name="topMargin">25dp</dimen>
</resources>

Değerlerde:

<resources>
    <dimen name="topMargin">0dp</dimen>
</resources>

Ve araç çubuğunuza ayarlayın

android:layout_marginTop="@dimen/topMargin"

Bunu da yaptım ve Lollipop'ta bir cazibe gibi çalıştı. Ama 24dpüst kenarda kullandım.
Rafa

Ekranı Android 7.1 olan cihazlara böldüğünüzde, uygulama ekranın ikinci kısmı ise bu boşluğu üstte görebilirsiniz.
Cícero Moura

1

Kullanmak yerine ScrimInsetsFrameLayout... Sadece sabit yüksekliği 24dpve arka planı olan bir görünüm eklemek daha kolay değil primaryColormi?

Bunun hiyerarşiye kukla bir görünüm eklemeyi içerdiğini anlıyorum, ancak bana daha temiz görünüyor.

Zaten denedim ve iyi çalışıyor.

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!-- THIS IS THE VIEW I'M TALKING ABOUT... -->
        <View
            android:layout_width="match_parent"
            android:layout_height="24dp"
            android:background="?attr/colorPrimary" />

        <android.support.v7.widget.Toolbar
            android:id="@+id/activity_base_toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:elevation="2dp"
            android:theme="@style/ThemeOverlay.AppCompat.Dark" />

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

    </LinearLayout>

    <fragment
        android:id="@+id/activity_base_drawer_fragment"
        android:name="com.myapp.drawer.ui.DrawerFragment"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:elevation="4dp"
        tools:layout="@layout/fragment_drawer" />

</android.support.v4.widget.DrawerLayout>

Ekranı Android 7.1 olan cihazlara böldüğünüzde, uygulama ekranın ikinci kısmı ise bu boşluğu üstte görebilirsiniz.
Cícero Moura

0

Şunu deneyin:

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


<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--Main layout and ads-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <FrameLayout
            android:id="@+id/ll_main_hero"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1">

        </FrameLayout>

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

            <View
                android:layout_width="320dp"
                android:layout_height="50dp"
                android:layout_gravity="center"
                android:background="#ff00ff" />
        </FrameLayout>


    </LinearLayout>

    <!--Toolbar-->
    <android.support.v7.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/toolbar"
        android:elevation="4dp" />
</FrameLayout>


<!--left-->
<ListView
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:choiceMode="singleChoice"
    android:divider="@null"
    android:background="@mipmap/layer_image"
    android:id="@+id/left_drawer"></ListView>

<!--right-->
<FrameLayout
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="right"
    android:background="@mipmap/layer_image">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@mipmap/ken2"
        android:scaleType="centerCrop" />
</FrameLayout>

tarzı:

<style name="ts_theme_overlay" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/red_A700</item>
    <item name="colorPrimaryDark">@color/red1</item>
    <item name="android:windowBackground">@color/blue_A400</item>
</style>

Ana Etkinlik ActionBarActivity'yi genişletir

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

Artık onCreateOptionsMenuAraç Çubuğu ile normal ActionBar'ı beğenebilirsiniz.

Bu benim düzenim

  • TOP: Sol Çekmece - Sağ Çekmece
    • MID: Araç Çubuğu (ActionBar)
    • ALT: Liste Parçası

Umarım anlarsın! İyi eğlenceler!

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.