Szukaj…


Wprowadzenie

Material Design to kompleksowy przewodnik dotyczący projektowania wizualnego, ruchu i interakcji między platformami i urządzeniami.

Uwagi

Zobacz także oryginalny post na blogu na Androida, przedstawiający bibliotekę Design Support Library

Oficjalna dokumentacja

https://developer.android.com/design/material/index.html

Wytyczne dotyczące projektowania materiałów

https://material.io/guidelines

Inne zasoby projektowe i biblioteki

https://design.google.com/resources/

Zastosuj motyw AppCompat

Biblioteka obsługi AppCompat zawiera motywy do tworzenia aplikacji ze specyfikacją Material Design . Motyw z elementem nadrzędnym Theme.AppCompat jest również wymagany, aby działanie rozszerzało AppCompatActivity .

Pierwszym krokiem jest dostosowanie palety kolorów motywu, aby automatycznie pokolorować aplikację.
W res/styles.xml aplikacji możesz zdefiniować:

<!-- inherit from the AppCompat theme -->
<style name="AppTheme" parent="Theme.AppCompat">

    <!-- your app branding color for the app bar -->
    <item name="colorPrimary">#2196f3</item>
    
    <!-- darker variant for the status bar and contextual app bars -->
    <item name="colorPrimaryDark">#1976d2</item>

    <!-- theme UI controls like checkboxes and text fields -->
    <item name="colorAccent">#f44336</item>
</style>

Zamiast Theme.AppCompat , który ma ciemne tło, możesz także użyć Theme.AppCompat.Light lub Theme.AppCompat.Light.DarkActionBar .

Możesz dostosować motyw za pomocą własnych kolorów. Dobre wybory znajdują się w tabeli kolorów specyfikacji materiału i palecie materiałów . Kolory „500” są dobrym wyborem dla podstawowego (niebieski 500 w tym przykładzie); wybierz „700” tego samego odcienia dla ciemnego; oraz odcień o innym odcieniu niż kolor akcentujący. Kolor podstawowy służy do paska narzędzi aplikacji i jego wpisu na ekranie przeglądu (najnowsze aplikacje), ciemniejszy wariant do przyciemnienia paska stanu oraz kolor akcentu do podkreślenia niektórych elementów sterujących.

Po utworzeniu tego motywu zastosuj go do aplikacji w AndroidManifest.xml a także zastosuj motyw do dowolnej określonej aktywności. Jest to przydatne do zastosowania motywu AppTheme.NoActionBar , który pozwala implementować niestandardowe konfiguracje paska narzędzi.

<application android:theme="@style/AppTheme" 
    ...>
    <activity 
        android:name=".MainActivity"
        android:theme="@style/AppTheme" />
</application>

Możesz także zastosować motywy do poszczególnych widoków za pomocą android:theme i motyw ThemeOverlay . Na przykład za pomocą Toolbar :

<android.support.v7.widget.Toolbar
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:background="?attr/colorPrimary"
  android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />

lub Button :

<Button
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:theme="@style/MyButtonTheme"/>

<!-- res/values/themes.xml -->
<style name="MyButtonTheme" parent="ThemeOverlay.AppCompat.Light">
    <item name="colorAccent">@color/my_color</item>
</style>

Dodawanie paska narzędzi

Toolbar to uogólnienie Toolbar ActionBar do użytku w układach aplikacji. Natomiast ActionBar jest tradycyjnie ramach Activity's nieprzezroczystej okna wystrój kontrolowany przez ramach, Toolbar może być umieszczony w dowolnym poziomie zagnieżdżenia w hierarchii widoku. Można go dodać, wykonując następujące czynności:

  1. Upewnij się, że w zależności od pliku dodana jest następująca zależność do pliku build.gradle modułu (np. Aplikacji):

    compile 'com.android.support:appcompat-v7:25.3.1'
    
  2. Ustaw motyw swojej aplikacji na taki, który nie ma ActionBar . W tym celu edytuj plik styles.xml w obszarze res/values i ustaw motyw Theme.AppCompat .
    W tym przykładzie używamy Theme.AppCompat.NoActionBar jako Theme.AppCompat.NoActionBar nadrzędny Twojego AppTheme :

    <style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
        <item name="colorPrimary">@color/primary</item>
        <item name="colorPrimaryDark">@color/primaryDark</item>
        <item name="colorAccent">@color/accent</item>
    </style>
    

    Możesz także użyć Theme.AppCompat.Light.NoActionBar lub Theme.AppCompat.DayNight.NoActionBar lub dowolnego innego motywu, który z natury nie ma ActionBar

  1. Dodaj Toolbar do układu aktywności:

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:elevation="4dp"/>
    

    Pod Toolbar możesz dodać resztę swojego układu.

  1. W swoim Activity ustaw Toolbar jako Toolbar ActionBar dla tego Activity . Pod warunkiem, że korzystasz z biblioteki appcompat i AppCompatActivity , możesz użyć metody setSupportActionBar() :

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
     
        //...
    } 
    

Po wykonaniu powyższych kroków możesz użyć metody getSupportActionBar() , aby manipulować Toolbar ustawionym jako ActionBar .

Na przykład możesz ustawić tytuł, jak pokazano poniżej:

getSupportActionBar().setTitle("Activity Title");

Możesz na przykład ustawić kolor tytułu i tła, jak pokazano poniżej:

CharSequence title = "Your App Name";
SpannableString s = new SpannableString(title);
s.setSpan(new ForegroundColorSpan(Color.RED), 0, title.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
getSupportActionBar().setTitle(s);
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(Color.argb(128, 0, 0, 0)));

Dodawanie FloatingActionButton (FAB)

W projekcie materiału pływający przycisk akcji reprezentuje akcję podstawową w działaniu.
Wyróżniają się okrągłą ikoną unoszącą się nad interfejsem użytkownika i mają zachowania ruchowe, które obejmują morfowanie, uruchamianie i przenoszenie punktu kontrolnego.

Upewnij się, że do pliku build.gradle aplikacji w zależnościach dodano następującą zależność:

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

Teraz dodaj FloatingActionButton do pliku układu:

<android.support.design.widget.FloatingActionButton
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_margin="16dp"
      android:src="@drawable/some_icon"/>

gdzie atrybut src odwołuje się do ikony, która powinna zostać użyta dla akcji swobodnej.
Wynik powinien wyglądać mniej więcej tak (zakładając, że twoim akcentem jest Materiał Różowy): Materiał FAB

Domyślnie kolor tła przycisku FloatingActionButton zostanie ustawiony na kolor akcentu motywu. Zauważ też, że FloatingActionButton wymaga marginesu wokół niego, aby działać poprawnie. Zalecany margines na dole to 16dp dla telefonów i 24dp dla tabletów.

Oto właściwości, których możesz użyć do dalszego dostosowania FloatingActionButton (zakładając, że xmlns:app="http://schemas.android.com/apk/res-auto jest zadeklarowany jako przestrzeń nazw u góry układu):

  • app:fabSize : Można ustawić na normal lub mini aby przełączać się między wersją normalną lub mniejszą.
  • app:rippleColor : Ustawia kolor efektu tętnienia przycisku FloatingActionButton . Może być zasobem koloru lub szesnastkowym.
  • app:elevation : Może być łańcuchem, liczbą całkowitą, wartością logiczną, wartością koloru, zmiennoprzecinkową, wartością wymiaru.
  • app:useCompatPadding : Włącz dopełnianie app:useCompatPadding . Może wartość logiczna, na przykład true lub false . Ustaw na true aby używać paddingu kompatybilnego na api-21 i nowszych, aby zachować spójny wygląd ze starszymi poziomami api.

Więcej przykładów na temat FAB można znaleźć tutaj .

Przyciski w stylu Material Design

Biblioteka obsługi AppCompat definiuje kilka przydatnych stylów przycisków , z których każdy rozszerza podstawowy styl Widget.AppCompat.Button , który jest domyślnie stosowany do wszystkich przycisków, jeśli używasz motywu AppCompat . Ten styl pomaga upewnić się, że wszystkie przyciski domyślnie wyglądają tak samo, zgodnie ze specyfikacją projektowania materiałów .

W tym przypadku akcentem jest różowy.

  1. Prosty przycisk: @style/Widget.AppCompat.Button

    Prosty obraz przycisku

    <Button
        style="@style/Widget.AppCompat.Button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp" 
        android:text="@string/simple_button"/>
    
  1. Kolorowy przycisk: @style/Widget.AppCompat.Button.Colored
    Styl Widget.AppCompat.Button.Colored rozszerza styl Widget.AppCompat.Button i automatycznie stosuje kolor akcentu wybrany w motywie aplikacji.

    Kolorowy obraz przycisku

    <Button
        style="@style/Widget.AppCompat.Button.Colored"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp" 
        android:text="@string/colored_button"/>
    

    Jeśli chcesz dostosować kolor tła bez zmiany koloru akcentu w głównym motywie , możesz utworzyć niestandardowy motyw (rozszerzający motyw ThemeOverlay ) dla Button i przypisać go do atrybutu android:theme przycisk:

    <Button  
         style="@style/Widget.AppCompat.Button.Colored"  
         android:layout_width="wrap_content"  
         android:layout_height="wrap_content" 
         android:layout_margin="16dp"
         android:theme="@style/MyButtonTheme"/> 
    

    Zdefiniuj motyw w res/values/themes.xml :

     <style name="MyButtonTheme" parent="ThemeOverlay.AppCompat.Light"> 
          <item name="colorAccent">@color/my_color</item> 
     </style>
    
  2. Przycisk bez obramowania: @style/Widget.AppCompat.Button.Borderless

    Obraz przycisku bez obramowania

    <Button
        style="@style/Widget.AppCompat.Button.Borderless"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp" 
        android:text="@string/borderless_button"/>
    
  1. Kolorowy przycisk bez obramowania: @style/Widget.AppCompat.Button.Borderless.Colored

    Kolorowy przycisk bez obramowania

    <Button
        style="@style/Widget.AppCompat.Button.Borderless.Colored"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp" 
        android:text="@string/borderless_colored_button"/>
    

Jak korzystać z TextInputLayout

Upewnij się, że do pliku build.gradle aplikacji w zależnościach dodano następującą zależność:

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

Pokaż podpowiedź z EditText jako pływającą etykietę, gdy wprowadzona zostanie wartość.

<android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

     <android.support.design.widget.TextInputEditText
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:hint="@string/form_username"/>

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

Aby wyświetlić ikonę oka wyświetlającą hasło w TextInputLayout, możemy skorzystać z następującego kodu:

<android.support.design.widget.TextInputLayout
    android:id="@+id/input_layout_current_password"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:passwordToggleEnabled="true">

    <android.support.design.widget.TextInputEditText

        android:id="@+id/current_password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/current_password"
        android:inputType="textPassword" />

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

gdzie app:passwordToggleEnabled="true" i android:inputType="textPassword" parametry są wymagane.

app powinna używać przestrzeni nazw xmlns:app="http://schemas.android.com/apk/res-auto"

Więcej szczegółowych informacji i przykładów można znaleźć w dedykowanym temacie .

Dodanie TabLayout

TabLayout zapewnia poziomy układ wyświetlania kart i jest powszechnie używany w połączeniu z ViewPager .

Upewnij się, że do pliku build.gradle aplikacji w zależnościach dodano następującą zależność:

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

Teraz możesz dodawać elementy do TabLayout w swoim układzie za pomocą klasy TabItem .

Na przykład:

<android.support.design.widget.TabLayout
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:id="@+id/tabLayout">

    <android.support.design.widget.TabItem
        android:text="@string/tab_text_1"
        android:icon="@drawable/ic_tab_1"/>

    <android.support.design.widget.TabItem
        android:text="@string/tab_text_2"
        android:icon="@drawable/ic_tab_2"/>

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

Dodaj OnTabSelectedListener aby otrzymywać powiadomienia, gdy karta w TabLayout zostanie wybrana / niezaznaczona / ponownie wybrana:

TabLayout tabLayout = (TabLayout) findViewById(R.id.tabLayout);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        int position = tab.getPosition();
        // Switch to view for this tab
    }

    @Override
    public void onTabUnselected(TabLayout.Tab tab) {

    }

    @Override
    public void onTabReselected(TabLayout.Tab tab) {

    }
});

Karty można również dodawać / usuwać programowo z TabLayout .

TabLayout.Tab tab = tabLayout.newTab();
tab.setText(R.string.tab_text_1);
tab.setIcon(R.drawable.ic_tab_1);
tabLayout.addTab(tab);

tabLayout.removeTab(tab);
tabLayout.removeTabAt(0);
tabLayout.removeAllTabs();

TabLayout ma dwa tryby, stały i przewijany.

tabLayout.setTabMode(TabLayout.MODE_FIXED);
tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);

Można je również zastosować w XML:

<android.support.design.widget.TabLayout
    android:id="@+id/tabLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:tabMode="fixed|scrollable" />

Uwaga: tryby TabLayout wykluczają się wzajemnie, co oznacza, że tylko jeden może być aktywny na raz.

Kolor wskaźnika tabulacji to kolor akcentu zdefiniowany dla motywu Projektowanie materiałów.
Możesz zastąpić ten kolor, definiując niestandardowy styl w styles.xml a następnie stosując styl do TabLayout:

<style name="MyCustomTabLayoutStyle" parent="Widget.Design.TabLayout">
    <item name="tabIndicatorColor">@color/your_color</item>
</style>

Następnie możesz zastosować styl do widoku, używając:

<android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        style="@style/MyCustomTabLayoutStyle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
</android.support.design.widget.TabLayout>

RippleDrawable

Efekt dotykowy Ripple został wprowadzony przy projektowaniu materiałów w Androidzie 5.0 (API poziom 21), a animacja została zaimplementowana przez nową klasę RippleDrawable .

Drawable, który pokazuje efekt tętnienia w odpowiedzi na zmiany stanu. Pozycja zakotwiczenia tętnienia dla danego stanu może być określona przez wywołanie setHotspot(float x, float y) z odpowiednim identyfikatorem atrybutu stanu.

5.0

Zasadniczo efekt tętnienia dla zwykłych przycisków działa domyślnie w interfejsie API 21 i nowszych, a dla innych widoków dotykowych można to osiągnąć, określając:

android:background="?android:attr/selectableItemBackground">

dla zmarszczek zawartych w widoku lub:

android:background="?android:attr/selectableItemBackgroundBorderless"

dla zmarszczek wykraczających poza granice widoku.

Na przykład na poniższym obrazie

  • B1 to przycisk, który nie ma żadnego tła,
  • B2 jest skonfigurowany z android:background="android:attr/selectableItemBackground"
  • B3 jest skonfigurowany z android:background="android:attr/selectableItemBackgroundBorderless"

(Zdjęcie dzięki uprzejmości: http://blog.csdn.net/a396901990/article/details/40187203 )

Możesz to samo osiągnąć w kodzie, używając:

int[] attrs = new int[]{R.attr.selectableItemBackground};
TypedArray typedArray = getActivity().obtainStyledAttributes(attrs);
int backgroundResource = typedArray.getResourceId(0, 0);
myView.setBackgroundResource(backgroundResource);

Fale można również dodawać do widoku za pomocą atrybutu android:foreground taki sam sposób, jak powyżej. Jak sama nazwa wskazuje, w przypadku dodania tętnienia do pierwszego planu, tętnienia pojawią się nad każdym widokiem, do którego zostały dodane (np. ImageView , LinearLayout zawierający wiele widoków itp.).

Jeśli chcesz dostosować efekt tętnienia do widoku, musisz utworzyć nowy plik XML katalogu, który można rysować.

Oto kilka przykładów:

Przykład 1 : Bezgraniczna zmarszczka

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="#ffff0000" />

Przykład 2 : Falowanie maską i kolorem tła

<ripple android:color="#7777777"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/mask"
        android:drawable="#ffff00" />
    <item android:drawable="@android:color/white"/>
</ripple>

Jeśli istnieje view z tłem określonym już shape , corners i innymi znacznikami, aby dodać tętnienie do tego widoku, użyj mask layer i ustaw tętnienie jako tło widoku.

Przykład :

 <?xml version="1.0" encoding="utf-8"?>
    <ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="?android:attr/colorControlHighlight">
        <item android:id="@android:id/mask">
           <shape 
              android:shape="rectangle">
              solid android:color="#000000"/>
               <corners
                 android:radius="25dp"/>
            </shape>
        </item>
        <item android:drawable="@drawable/rounded_corners" />
    </ripple>

Przykład 3 : Wsiądź na zasób, który można wyciągnąć

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="#ff0000ff">
    <item android:drawable="@drawable/my_drawable" />
</ripple>

Sposób użycia: Aby dołączyć plik tętnienia xml do dowolnego widoku, ustaw go jako tło w następujący sposób (zakładając, że plik tętnienia ma nazwę my_ripple.xml ):

<View 
    android:id="@+id/myViewId"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/my_ripple" />

Selektor:

Fala rysująca może być również używana zamiast selektorów listy stanów kolorów, jeśli twoja wersja docelowa to v21 lub wyższa (możesz również umieścić selektor drawable-v21 folderze drawable-v21 ):

<!-- /drawable/button.xml: -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/button_pressed"/>
    <item android:drawable="@drawable/button_normal"/>
</selector>

<!--/drawable-v21/button.xml:-->
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?android:colorControlHighlight">
   <item android:drawable="@drawable/button_normal" />
</ripple>

W takim przypadku kolor domyślnego stanu widoku byłby biały, a stan naciśnięcia pokazywałby falowanie.

Uwaga: Korzystanie z ?android:colorControlHighlight spowoduje, że tętnienie będzie ?android:colorControlHighlight ten sam kolor, co wbudowane tętnienia w aplikacji.

Aby zmienić tylko kolor tętnienia, możesz dostosować kolor android:colorControlHighlight w swoim motywie w następujący sposób:

<?xml version="1.0" encoding="utf-8"?>
<resources>

  <style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
    <item name="android:colorControlHighlight">@color/your_custom_color</item>
  </style>

</resources>

a następnie użyj tego motywu w swoich działaniach itp. Efekt będzie podobny do poniższego obrazu:

(Zdjęcie dzięki uprzejmości: http://blog.csdn.net/a396901990/article/details/40187203 )

Dodaj szufladę nawigacji

Szuflady nawigacyjne służą do nawigowania do miejsc docelowych najwyższego poziomu w aplikacji.

Upewnij się, że dodałeś bibliotekę wsparcia projektowania w pliku build.gradle w zależności:

 dependencies {
    // ...
    compile 'com.android.support:design:25.3.1'
}

Następnie dodaj DrawerLayout i NavigationView do pliku zasobów układu XML.
DrawerLayout to tylko fantazyjny pojemnik, który pozwala na DrawerLayout NavigationView , faktycznej szuflady nawigacji, z lewej lub prawej strony ekranu. Uwaga: w przypadku urządzeń mobilnych standardowy rozmiar szuflady wynosi 320dp.

<!-- res/layout/activity_main.xml -->
<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/navigation_drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">
    <! -- You can use "end" to open drawer from the right side -->

    <android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">

        <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.design.widget.CoordinatorLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_drawer"
        android:layout_width="320dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/drawer_header"
        app:menu="@menu/navigation_menu" />

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

Teraz, jeśli chcesz, utwórz plik nagłówka, który będzie służył jako górna część szuflady nawigacji. Służy to do nadania szufladzie znacznie bardziej eleganckiego wyglądu.

<!-- res/layout/drawer_header.xml -->
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="190dp">

    <ImageView
        android:id="@+id/header_image"
        android:layout_width="140dp"
        android:layout_height="120dp"
        android:layout_centerInParent="true"
        android:scaleType="centerCrop"
        android:src="@drawable/image" />

    <TextView
        android:id="@+id/header_text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/header_image"
        android:text="User name"
        android:textSize="20sp" />

</RelativeLayout>

Jest to określone w znaczniku NavigationView w app:headerLayout="@layout/drawer_header" .
Ta app:headerLayout napełnia określony układ do nagłówka. Można to alternatywnie zrobić w czasie wykonywania za pomocą:

// Lookup navigation view
NavigationView navigationView = (NavigationView) findViewById(R.id.navigation_drawer);
// Inflate the header view at runtime
View headerLayout = navigationView.inflateHeaderView(R.layout.drawer_header);

Aby automatycznie wypełnić szufladę nawigacji elementami nawigacyjnymi zgodnymi z projektem materiału, utwórz plik menu i dodaj elementy w razie potrzeby. Uwaga: chociaż ikony przedmiotów nie są wymagane, są one sugerowane w specyfikacji projektowania materiałów .
Odwołuje się do tego w tagu NavigationView w app:menu="@menu/navigation_menu" attribute .

<!-- res/menu/menu_drawer.xml -->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/nav_item_1"
        android:title="Item #1"
        android:icon="@drawable/ic_nav_1" />
    <item
        android:id="@+id/nav_item_2"
        android:title="Item #2"
        android:icon="@drawable/ic_nav_2" />
    <item
        android:id="@+id/nav_item_3"
        android:title="Item #3"
        android:icon="@drawable/ic_nav_3" />
    <item
        android:id="@+id/nav_item_4"
        android:title="Item #4"
        android:icon="@drawable/ic_nav_4" />
</menu>

Aby podzielić elementy na grupy, umieść je w <menu> zagnieżdżonym w innym <item> za pomocą atrybutu android:title lub zawiń je tagiem <group> .

Teraz, gdy układ jest gotowy, przejdź do kodu Activity :

  // Find the navigation view
  NavigationView navigationView = (NavigationView) findViewById(R.id.navigation_drawer);
  navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
      @Override
      public boolean onNavigationItemSelected(MenuItem item) {
          // Get item ID to determine what to do on user click
          int itemId = item.getItemId();
          // Respond to Navigation Drawer selections with a new Intent
          startActivity(new Intent(this, OtherActivity.class));
          return true;
      }
  });

  DrawerLayout drawer = (DrawerLayout) findViewById(R.id.navigation_drawer_layout);
  // Necessary for automatically animated navigation drawer upon open and close
  ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, "Open navigation drawer", "Close navigation drawer");
  // The two Strings are not displayed to the user, but be sure to put them into a separate strings.xml file.
  drawer.addDrawerListener(toggle);
  toogle.syncState();

Możesz teraz robić, co chcesz, w widoku nagłówka NavigationView

View headerView = navigationView.getHeaderView();
TextView headerTextView = (TextView) headerview.findViewById(R.id.header_text_view);
ImageView headerImageView = (ImageView) headerview.findViewById(R.id.header_image);
// Set navigation header text
headerTextView.setText("User name");
// Set navigation header image
headerImageView.setImageResource(R.drawable.header_image);

Widok nagłówka zachowuje się jak każdy inny View , więc po użyciu findViewById() i dodaniu kilku innych View do pliku układu możesz ustawić właściwości wszystkiego w nim.

Więcej szczegółowych informacji i przykładów można znaleźć w dedykowanym temacie .

Dolne arkusze w bibliotece obsługi projektu

Dolne arkusze przesuwają się w górę od dołu ekranu, aby wyświetlić więcej treści.
Zostały one dodane do biblioteki obsługi Androida w wersji v25.1.0 i obsługują przede wszystkim wersje.

Upewnij się, że do pliku build.gradle aplikacji w zależnościach dodano następującą zależność:

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

Trwałe dolne arkusze

BottomSheetBehavior arkusz dolny można uzyskać, dołączając zachowanie BottomSheetBehavior do zachowania dziecka Widok układu CoordinatorLayout :

<android.support.design.widget.CoordinatorLayout >

    <!-- .....   -->

    <LinearLayout
       android:id="@+id/bottom_sheet"
       android:elevation="4dp"
       android:minHeight="120dp"
       app:behavior_peekHeight="120dp"
       ...
       app:layout_behavior="android.support.design.widget.BottomSheetBehavior">

           <!-- .....   -->

       </LinearLayout>

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

Następnie w kodzie możesz utworzyć odwołanie, używając:

 // The View with the BottomSheetBehavior  
 View bottomSheet = coordinatorLayout.findViewById(R.id.bottom_sheet);  
 BottomSheetBehavior mBottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);  

Możesz ustawić stan swojego BottomSheetBehavior za pomocą metody setState () :

mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);

Możesz użyć jednego z tych stanów:

  • STATE_COLLAPSED : ten stan zwinięcia jest domyślny i pokazuje tylko część układu na dole. Wysokość może być kontrolowana za pomocą app:behavior_peekHeight attribute_peekHeight atrybut (domyślnie 0)

  • STATE_EXPANDED : w pełni rozwinięty stan dolnego arkusza, w którym widoczny jest cały dolny arkusz (jeśli jego wysokość jest mniejsza niż zawierający CoordinatorLayout ) lub cały CoordinatorLayout jest wypełniony

  • STATE_HIDDEN : domyślnie wyłączone (i włączone z atrybutem app:behavior_hideable ), włączenie to pozwala użytkownikom przesunąć palcem w dół po dolnym arkuszu, aby całkowicie ukryć dolny arkusz

Dalej, aby otworzyć lub zamknąć BottomSheet po kliknięciu wybranego widoku, przycisk Powiedzmy, że tutaj jest, jak przełączyć zachowanie arkusza i zaktualizować widok.

mButton = (Button) findViewById(R.id.button_2);
    //On Button click we monitor the state of the sheet
    mButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (mBottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED) {
                //If expanded then collapse it (setting in Peek mode).
                mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
                mButton.setText(R.string.button2_hide);
            } else if (mBottomSheetBehavior.getState() == BottomSheetBehavior.STATE_COLLAPSED) {
                //If Collapsed then hide it completely.
                mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
                mButton.setText(R.string.button2);
            } else if (mBottomSheetBehavior.getState() == BottomSheetBehavior.STATE_HIDDEN) {
                //If hidden then Collapse or Expand, as the need be.
                mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
                mButton.setText(R.string.button2_peek);
            }
        }
    });

Ale zachowanie BottomSheet ma również funkcję, w której użytkownik może wchodzić w interakcje z przesunięciem W GÓRĘ lub W DÓŁ za pomocą ruchu DRAG. W takim przypadku może nie być możliwe zaktualizowanie zależnego widoku (jak przycisk powyżej), jeśli stan arkusza zmienił się. W tym przypadku chcesz otrzymywać wywołania zwrotne zmian stanu, dlatego możesz dodać BottomSheetCallback aby nasłuchiwać zdarzeń machnięcia użytkownika:

mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetCallback() {  
    @Override  
    public void onStateChanged(@NonNull View bottomSheet, int newState) {  
      // React to state change and notify views of the current state
    }  
      @Override  
      public void onSlide(@NonNull View bottomSheet, float slideOffset) {  
       // React to dragging events and animate views or transparency of dependent views
   }  
 });  

A jeśli chcesz, aby Twój Dolny Arkusz był widoczny tylko w trybie ZWIJANY i ROZSZERZONY, a nigdy nie UKRYJ:

mBottomSheetBehavior2.setHideable(false);

Okno dialogowe dolnego arkusza

Możesz także wyświetlić BottomSheetDialogFragment zamiast Widoku w dolnym arkuszu. Aby to zrobić, musisz najpierw utworzyć nową klasę rozszerzającą BottomSheetDialogFragment.

W ramach metody setupDialog() można nadmuchać nowy plik układu i pobrać działanie BottomSheetBehaviora kontenera w działaniu. Po uzyskaniu takiego zachowania możesz utworzyć i powiązać z nim BottomSheetCallback , aby odrzucić Fragment, gdy arkusz jest ukryty.

public class BottomSheetDialogFragmentExample extends BottomSheetDialogFragment {
 
    private BottomSheetBehavior.BottomSheetCallback mBottomSheetBehaviorCallback = new BottomSheetBehavior.BottomSheetCallback() {
 
        @Override
        public void onStateChanged(@NonNull View bottomSheet, int newState) {
            if (newState == BottomSheetBehavior.STATE_HIDDEN) {
                dismiss();
            }
 
        }
 
        @Override
        public void onSlide(@NonNull View bottomSheet, float slideOffset) {
        }
    };
 
    @Override
    public void setupDialog(Dialog dialog, int style) {
        super.setupDialog(dialog, style);
        View contentView = View.inflate(getContext(), R.layout.fragment_bottom_sheet, null);
        dialog.setContentView(contentView);
 
        CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) ((View) contentView.getParent()).getLayoutParams();
        CoordinatorLayout.Behavior behavior = params.getBehavior();
 
        if( behavior != null && behavior instanceof BottomSheetBehavior ) {
            ((BottomSheetBehavior) behavior).setBottomSheetCallback(mBottomSheetBehaviorCallback);
        }
    }
}

Na koniec możesz wywołać metodę show () na instancji swojego fragmentu, aby wyświetlić go w dolnym arkuszu.

BottomSheetDialogFragment bottomSheetDialogFragment = new BottomSheetDialogFragmentExample();
bottomSheetDialogFragment.show(getSupportFragmentManager(), bottomSheetDialogFragment.getTag());

Więcej informacji można znaleźć w dedykowanym temacie

Dodaj Snackbar

Jedną z głównych cech w Material Design jest dodanie Snackbar , który teoretycznie zastępuje poprzedni Toast . Zgodnie z dokumentacją Androida:

Paski przekąskowe zawierają pojedynczy wiersz tekstu bezpośrednio związany z wykonywaną operacją. Mogą zawierać akcję tekstową, ale nie zawierają ikon. Grzanki są używane przede wszystkim do przesyłania wiadomości systemowych. Są one również wyświetlane u dołu ekranu, ale nie można ich przesuwać poza ekran.

wprowadź opis zdjęcia tutaj

W Androidzie nadal można używać tostów do wyświetlania wiadomości użytkownikom, jednak jeśli zdecydujesz się na użycie materiałów w swojej aplikacji, zaleca się korzystanie z paska przekąskowego. Zamiast wyświetlać się jako nakładka na ekranie, Snackbar wyskakuje z dołu.

Oto jak to się robi:

Snackbar snackbar = Snackbar
        .make(coordinatorLayout, "Here is your new Snackbar", Snackbar.LENGTH_LONG);
snackbar.show();

Jeśli chodzi o czas wyświetlania Snackbar , mamy opcje podobne do opcji oferowanych przez Toast lub możemy ustawić niestandardowy czas trwania w milisekundach:

  • LENGTH_SHORT
  • LENGTH_LONG
  • LENGTH_INDEFINITE
  • setDuration() (od wersji 22.2.1 )

Możesz także dodać dynamiczne funkcje do ActionCallback Snackbar takie jak ActionCallback lub niestandardowy kolor. Podczas dostosowywania Snackbar zwróć jednak uwagę na wytyczne projektowe oferowane przez system Android.

Wdrożenie Snackbar ma jednak jedno ograniczenie. Układ nadrzędny widoku, w którym zamierzasz wdrożyć Snackbar musi być układem CoordinatorLayout . Dzieje się tak, aby można było wykonać rzeczywiste okienko od dołu.

Oto jak zdefiniować CoordinatorLayout w pliku XML układu:

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/coordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
 
    //any other widgets in your layout go here.
 
</android.support.design.widget.CoordinatorLayout>

CoordinatorLayout musi zostać zdefiniowany w metodzie onCreate , a następnie użyty podczas tworzenia samego onCreate Snackbar .

Aby uzyskać więcej informacji na temat Snackbar , sprawdź oficjalną dokumentację lub dedykowany temat w dokumentacji.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow