Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Android Code Lab 02

Android Code Lab 02

Użycie NavigationDrawer na starszych wersjach Androida.

Kod źródłowy: https://dl.dropboxusercontent.com/u/20220/CodeLab02.zip

Adam Jodłowski

November 08, 2013
Tweet

More Decks by Adam Jodłowski

Other Decks in Programming

Transcript

  1. Wykorzystanie NavigationDrawera Komponent NavigationDrawer zajmuje się za nas animacją, ukrywaniem

    i pokazywaniem swojej zawartości. Do zadań programisty należy: 1. Dostarczenie odpowiedniego layoutu aktywności z użyciem widoku DrawerLayout 2. Obsługa interakcji użytkownika z opcjami wyświetlanymi w drawerze 3. Ewentualne pokazywanie i ukrywanie drawera programowo, w reakcji na inne zdarzenia niż swipe po ekranie Dobrą praktyką jest podpięcie NavigationDrawera do ikonki aplikacji w ActionBarze, z uwagi na nieoczywistość zastosowania tego rodzaju nawigacji w aplikacji. Aby skorzystać z komponentu, należy mieć dołączoną i skonfigurowaną bibliotekę Support Library (v4), jest ona dołączana automatycznie do nowotworzonych projektów. Część prezentacji zakłada przypadek pisania aplikacji dla wersji API 11+ z uwagi na wykorzystanie ActionBara. Aby przystosować kod do starszych wersji platformy, wystarczy skorzystać z ActionBarCompat zgodnie z Code Lab 01.
  2. Layout głównej aktywności Aby skorzystać z NavigationDrawera, modyfikujemy plik layoutu

    aktywności wg wzoru: <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawerLayout" android:layout_width="match_parent" android:layout_height="match_parent"> <FrameLayout android:id="@+id/appContent" android:layout_width="match_parent" android:layout_height="match_parent" /> <RelativeLayout android:id="@+id/drawer" android:layout_width=" 240dp" android:layout_height="match_parent" android: layout_gravity="start" /> </android.support.v4.widget.DrawerLayout>
  3. Layout głównej aktywności Aby skorzystać z NavigationDrawera, modyfikujemy plik layoutu

    aktywności wg wzoru: <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawerLayout" android:layout_width="match_parent" android:layout_height="match_parent"> <FrameLayout android:id="@+id/appContent" android:layout_width="match_parent" android:layout_height="match_parent" /> <RelativeLayout android:id="@+id/drawer" android:layout_width=" 240dp" android:layout_height="match_parent" android: layout_gravity="start" /> </android.support.v4.widget.DrawerLayout> zawartość głównego ekranu, musi to być pierwszy element wewnątrz DrawerLayoutu (typowo stanowi kontener na fragmenty) podawajmy maksymalnie 320dp pozioma grawitacja drawera: do lewej zawartość drawera ustawiamy jako root całego layoutu
  4. Przykładowy layout <android.support.v4.widget.DrawerLayout xmlns:android="http: //schemas.android.com/apk/res/android" android:id="@+id/drawerLayout" android:layout_width="match_parent" android:layout_height="match_parent" > <FrameLayout

    android:id="@+id/drawerContent" android:layout_width="match_parent" android:layout_height="match_parent" /> <RelativeLayout android:id="@+id/drawer" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="start" android:background="#eee" > <ImageView android:id="@+id/logoViewDrawer" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:src="@drawable/ic_launcher" /> <ListView android:id="@+id/listViewDrawer" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/logoViewDrawer" android:choiceMode="singleChoice" android:divider="@android:color/transparent" android:dividerHeight="0dp" /> </RelativeLayout> </android.support.v4.widget.DrawerLayout>
  5. Nasłuchiwanie zdarzeń drawera Potrzebujemy obiektu implementującego interfejs DrawerLayout.DrawerListener: mDrawerLayout =

    (DrawerLayout) findViewById(R.id.drawerLayout); mDrawerLayout.setDrawerListener(new DrawerListener() { @Override public void onDrawerClosed(View drawerView) { Log.d("CodeLab", "onDrawerClosed"); } @Override public void onDrawerOpened(View drawerView) { Log.d("CodeLab", "onDrawerOpened"); } @Override public void onDrawerSlide(View drawerView, float slideOffset) { Log.d("CodeLab", "onDrawerSlide: " + slideOffset); } @Override public void onDrawerStateChanged(int newState) { Log.d("CodeLab", "onDrawerStateChanged: " + newState); } });
  6. Współpraca drawera z ikonką aplikacji w ActionBarze (1) Uwaga: jeśli

    nie masz w aktualnym projekcie dołączonego ActionBarCompat, możesz tymczasowo zmienić wartość android:minSdkVersion w manifeście na >10. ActionBarDrawerToggle spaja ActionBar z NavigationDrawerem oraz pokazuje go i ukrywa na kliknięcie ikonki aplikacji w ActionBarze. Dobrą praktyką jest zastąpienie tradycyjnej ikonki przycisku w górę, ikonką drawera, która podpowiada użytkownikowi, że zastosowano właśnie taki rodzaj nawigacji. Wspomnianą ikonę najlepiej dodać do zasobów aplikacji z paczki Android Design Icons.
  7. Współpraca drawera z ikonką aplikacji w ActionBarze (2) Zmodyfikuj klasę

    głównej aktywności według podanego niżej kodu: public class MainActivity extends Activity { private DrawerLayout mDrawerLayout; private ActionBarDrawerToggle mDrawerToggle; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout); mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer, R.string.action_drawer_open, R.string.action_drawer_close) { public void onDrawerClosed(View view) { getActionBar().setTitle("Main App View"); } public void onDrawerOpened(View drawerView) { getActionBar().setTitle("Drawer visible"); } };
  8. Współpraca drawera z ikonką aplikacji w ActionBarze (2) Zmodyfikuj klasę

    głównej aktywności według podanego niżej kodu: public class MainActivity extends Activity { private DrawerLayout mDrawerLayout; private ActionBarDrawerToggle mDrawerToggle; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout); mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer, R.string.action_drawer_open, R.string.action_drawer_close) { public void onDrawerClosed(View view) { getActionBar().setTitle("Main App View"); } public void onDrawerOpened(View drawerView) { getActionBar().setTitle("Drawer visible"); } }; aktywność zawierająca NavigationDrawera ikonka symbolizująca NavigationDrawer dwa zasoby typu ‘string’ opisujące wykonywane akcje (otwarcie i zamknięcie) tutaj również możemy nasłuchiwać zdarzeń
  9. Współpraca drawera z ikonką aplikacji w ActionBarze (3) mDrawerLayout. setDrawerListener(mDrawerToggle);

    getActionBar().setDisplayHomeAsUpEnabled(true); // getActionBar().setHomeButtonEnabled(true); // API 14 i wyzej } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); mDrawerToggle. syncState(); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mDrawerToggle. onConfigurationChanged(newConfig); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (mDrawerToggle.onOptionsItemSelected(item)) { return true; } return super.onOptionsItemSelected(item); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } }
  10. Współpraca drawera z ikonką aplikacji w ActionBarze (3) mDrawerLayout. setDrawerListener(mDrawerToggle);

    getActionBar().setDisplayHomeAsUpEnabled(true); // getActionBar().setHomeButtonEnabled(true); // API 14 i wyzej } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); mDrawerToggle. syncState(); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mDrawerToggle. onConfigurationChanged(newConfig); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (mDrawerToggle.onOptionsItemSelected(item)) { return true; } return super.onOptionsItemSelected(item); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } } niech Toggle nasłuchuje synchronizacja po utworzeniu synchronizacja zmiany konfiguracji przekazujemy zdarzenie wyboru elementu menu opcji do komponentu Toggle, jeśli je obsłużył, zatrzymujemy propagację tego zdarzenia
  11. Reakcja na wybór elementów drawera Interakcja użytkownika z elementami drawera

    następuje w sposób tradycyjny, należy zarejestrować odpowiednie obiekty nasłuchujące na przyciski, wybór elementów listy czy gesty dotykowe. Typową reakcją jest podmiana fragmentów stanowiących główną zawartość aplikacji, kiedy drawer jest niewidoczny (w naszym przykładowym layoucie XML, kontenerem na fragmenty jest FrameLayout o id appContent). Pomocne dodatkowe metody wywołujące pokazanie się i ukrycie drawera: mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout); mDrawerLayout.openDrawer(GravityCompat.START); mDrawerLayout.closeDrawer(GravityCompat.START);