2016-04-15 2 views
0

Я создал новое приложение с Android Studio 2.0 и хочу, чтобы мой навигационный ящик находился ниже Toolbar. Я знаю, что спецификации Material Design говорят, что он должен быть выше Toolbar, но у моего Drawer не будет столько записей, и я хочу увидеть аккуратную анимацию значков, предоставляемую Google.NavigationView без серых границ при использовании fitsSystemWindows

Я постарался получить то, что я хочу, разместив DrawerLayout на верхнем уровне CoordinatorLayout.

<?xml version="1.0" encoding="utf-8"?> 
<android.support.design.widget.CoordinatorLayout 
    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" 
    tools:context="com.company.app.MainActivity"> 

    <android.support.design.widget.AppBarLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:theme="@style/AppTheme.AppBarOverlay"> 

     <android.support.v7.widget.Toolbar 
      android:id="@+id/toolbar" 
      android:layout_width="match_parent" 
      android:layout_height="?attr/actionBarSize" 
      android:background="?attr/colorPrimary" 
      app:popupTheme="@style/AppTheme.PopupOverlay" /> 

    </android.support.design.widget.AppBarLayout> 

    <android.support.v4.widget.DrawerLayout 
     android:id="@+id/drawer_layout" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     app:layout_behavior="@string/appbar_scrolling_view_behavior" 
     tools:openDrawer="start"> 

     <include layout="@layout/content_main" /> 

     <android.support.design.widget.NavigationView 
      android:id="@+id/nav_view" 
      android:layout_width="wrap_content" 
      android:layout_height="match_parent" 
      android:layout_gravity="start" 
      app:menu="@menu/activity_main_drawer" /> 

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

</android.support.design.widget.CoordinatorLayout> 

Я использую android:fitsSystemWindow="true" на макете верхнего уровня, так что я могу подкрасить строку состояния. Но когда я это делаю, у ящика навигации есть серая верхняя граница.

enter image description here

Когда я использовал бы его так, как Google, указанный его (над панелью инструментов), то граница будет хорошо, но это, как он выглядит некрасиво. Есть ли способ удалить это?

Я экспериментировал с переопределением NavigationView.onInsetsChanged(Rect rect) и смог разместить предметы наверху, но серая граница осталась.

+0

Что вы имеете в виду под "тонировки" в строке состояния ? Этот цвет поступает из вашего 'colorPrimaryDark' – Pztar

+0

Да, это правда. Но для того, чтобы иметь эффект оттенка от 'colorPrimaryDark', вы должны использовать' android: fitsSystemWindow = "true" 'в корневом элементе. И это приводит к тому, что эта серая граница в «NavigationView» – Saenic

ответ

8

У меня была головная боль, пытаясь понять это также и удалось найти this, в котором описывается, как CoordinatorLayout передает fitsSystemWindows своему ребенку. Я определенно думаю, что это ошибка, так как NavigationView уже он установлен false, но потом я прочитал это:

NavigationView заботится о защите полотняных строк состояния для вас, гарантируя, что ваш NavigationView взаимодействует со статусом бар соответственно на устройствах API21 +.

от Android Developers Blog. Поэтому я не уверен, что об этом думать. Я думаю, это могло быть связано с тем, что NavigationView никогда не предназначался для использования таким образом.

Тем не менее, вот решение, которое вы можете попробовать, устраняет проблему с серой панелью, но я не понял, может ли это вызвать больше проблем. Если так, пожалуйста, отправьте ответ.

В activity_main.xml: класс

<android.support.design.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:fitsSystemWindows="true"> 

    <android.support.design.widget.NavigationView 
     android:id="@+id/nav_view" 
     android:layout_width="240dp" 
     android:layout_height="match_parent" 
     android:layout_marginTop="100dp" 
     android:fitsSystemWindows="false"/> 

</android.support.design.widget.CoordinatorLayout> 

В MainActivity:

public class MainActivity extends AppCompatActivity { 

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

     NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); 
     if (navigationView != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { 
      navigationView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() { 
       @Override 
       public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) { 
        return insets; 
       } 
      }); 
     } 
    } 
} 

вы должны получить это:

Screenshot

+0

Вау, спасибо, «OnApplyWindowInsetsListener» действительно сделал трюк. – Saenic

+0

Рад, что это сработало. У меня есть ощущение, что могут возникнуть проблемы, когда представление будет обновляться позже во время выполнения. Я бы подумал, что поэтому передается параметр 'View'. Если это так, просто нужно условие 'if', чтобы представление, применяющее вставки, было' CoordinatorLayout', прежде чем возвращать вставки. Дайте мне знать, если вы натолкнетесь на это, потому что я еще так далеко не достиг. – Brian

Смежные вопросы