Android
Wygląd materiału
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
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:
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'
Ustaw motyw swojej aplikacji na taki, który nie ma
ActionBar
. W tym celu edytuj plik styles.xml w obszarzeres/values
i ustaw motywTheme.AppCompat
.
W tym przykładzie używamyTheme.AppCompat.NoActionBar
jakoTheme.AppCompat.NoActionBar
nadrzędny TwojegoAppTheme
:<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
lubTheme.AppCompat.DayNight.NoActionBar
lub dowolnego innego motywu, który z natury nie maActionBar
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.
W swoim
Activity
ustawToolbar
jakoToolbar
ActionBar
dla tegoActivity
. Pod warunkiem, że korzystasz z biblioteki appcompat iAppCompatActivity
, możesz użyć metodysetSupportActionBar()
:@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):
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ć nanormal
lubmini
aby przełączać się między wersją normalną lub mniejszą. -
app:rippleColor
: Ustawia kolor efektu tętnienia przyciskuFloatingActionButton
. 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łnianieapp:useCompatPadding
. Może wartość logiczna, na przykładtrue
lubfalse
. Ustaw natrue
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.
Prosty przycisk:
@style/Widget.AppCompat.Button
<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"/>
Kolorowy przycisk:
@style/Widget.AppCompat.Button.Colored
StylWidget.AppCompat.Button.Colored
rozszerza stylWidget.AppCompat.Button
i automatycznie stosuje kolor akcentu wybrany w motywie aplikacji.<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
) dlaButton
i przypisać go do atrybutuandroid: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>
Przycisk bez obramowania:
@style/Widget.AppCompat.Button.Borderless
<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"/>
Kolorowy przycisk bez obramowania:
@style/Widget.AppCompat.Button.Borderless.Colored
<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.
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ącyCoordinatorLayout
) lub całyCoordinatorLayout
jest wypełnionySTATE_HIDDEN
: domyślnie wyłączone (i włączone z atrybutemapp: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.
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 wersji22.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.