Tym razem kilka uzupełnień związanych z ActionBar. Moje uwagi:
- podobać się może kompatybilność wstecz i możliwość używania nawet na dość starych urządzeniach.
- ukrywanie i zarządzenie widokiem trochę toporne jak dla mnie, ale da się przeżyć
- nawigacje zakładkowa i listowa - przyzwoite, ale nic nadzwyczajnego nie widzę, w Windows możemy wstawić dowolną zawartość do paska aplikacyjnego, a poza tym mamy nowoczesne kontrolki Hub i Pivot do nawigacji
- interaktywne widoki akcji na pasku - własne lub predefiniowane kontrolki pokazywane na stałe lub rozwijane, spełnia to swoją rolę. W Windows 8.x oraz Windows Phone 8.1 (XAML WinRT, HTML5) każdy może ogólnodostępnymi metodami dla kontrolek modyfikować zawartość paska aplikacyjnego (jest to normalna kontrolka). W Windows Phone nie nowszym niż 8.0 i w Silverlight na WP 8.1 mamy komponent systemowy o dość ograniczonej konfiguracji, który nie jest kontrolką XAML. W Android nie mamy do końca uniwersalnych mechanizmów dla całej platformy w zakresie modyfikacji zawartości komponentów wizualnych mimo wprowadzenia uniwersalnych fragmentów (może wynika to z tego, że dołożono je później do platformy, w Windows uniwersalne kontrolki były od początku)
Szczegóły poniżej:
Poprawa interakcji dzięki ActionBar
Dostępny na wszystkie wersje Android
- natywny support od Android 3.0
- dostępny na Android 2.x jako rozszerzenie
- rozszerzenie ActionBarSherlock http://actionbarsherlock.com/ (na bazie biblioteki kompatybilnościowej dla Android)
- inne rozwiązanie: <sdk>/samples/android-14/ActionBarCompat
Sterowanie wyglądem
- obrazki
- setIcon - inna ikona niż domyślna ikona aktywności
- setLogo - ustawienie większego obrazka niż ikona po lewej stronie
- setBackgroundDrawable - użycie bitmapy lub czegoś podobnego do tła
- tekst
- setTitle
- setSubtitle
- setDisplayShowTitleEnabled - pokazywanie/ukrywanie tytułu i podtytułu
- …
Ukrywanie
- programowo
- ActionBar.hide / ActionBar.show
- ActionBar.isShowing - informacja, czy pasek jest widoczny
- statycznie
- aktywność z motywem Theme.Holo.NoActionBar
Overlaying
Lepszy user experience przy ukrywaniu/pokazywaniu
- Overlay pozwala ukrywać/pokazywać ActionBar bez resizowania aktywności
- Włączanie overlay przy pomocy stylu
- zdefiniowanie nowego stylu dziedziczącego po Theme.Holo
- ustawienie windowActionBarOverlay na true
- Włączanie overlay programowo
- pobieramy referencję na okno za pomocą Activity.getWindow
- używamy requestFeature do zatwierdzenia Window.FEATURE_ACTION_BAR_OVERLAY
- aplikacja musi określić, co ukrywa/pokazuje ActionBar
- zwykle zdarzenia dotykowe
- często ukrywamy po wyborze akcji
public class XActivity extends Activity {
…
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN)
toggleActionBar();
return true;
}
private void toggleActionBar() {
ActionBar actionBar = getActionBar();
if (actionBar.isShowing())
actionBar.hide();
else
actionBar.show();
}
}
values/styles.xml
<resources>
<style name=”Theme.Holo.ActionBarOverlay” parent=”android:style/Theme.Holo”>
<item name=”android:windowActionBarOverlay”>true</item>
</style>
</resources>
manifest
<activity …
android.theme=”style/Theme.Holo.ActionBarOverlay”
…>
…
</activity>
Nawigacja
Tryby nawigacji
- standardowa
- zakładki
- lista - wybór widoków z listy drop-down
Kontrolowanie umieszczenia zakładek
- W zależności od dostępnej przestrzeni
- stos zakładek pod głównym ActionBar, jeśli zachodzi taka potrzeba
- na głównym ActionBar, jeśli pozwala przestrzeń
- możliwość robienia miejsca przez umieszczenie listy akcji na dole i ukrywanie ikony/tytułu
Pokazywanie na ActionBar:
ActionBar actionBar = getActionBar();
int currentOptions = actionBar.getDisplayOptions();
boolean currentVisibleValue = (currentOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0;
boolean newVisibleValue = !currentVisibleValue;
actionBar.setDisplayShowHomeEnabled(newVisibleValue);
actionBar.setDisplayShowTitleEnabled(newVisibleValue);
Nawigacja listowa
- lista jest tworzona jako SpinnerAdapter
- w większości przypadków ukrywamy tytuł
- każda pozycja reprezentuje ekran
- każdy ekran zaimplementowany jako Fragment
ActionBar.OnNavigationListener
- pojedyncza instancja obsługuje wszystkie ekrany
- onNavigationItemSelected wołany przy każdej zmianie wyboru
- indeks wyboru
- ID wyboru, jeśli dotyczy
- każdy wybór wiąże się z pokazaniem odpowiedniego Fragment-u
- pełnoekranowy fragment dołączamy do android.R.id.content
- niepełnoekranowy fragment dołączamy do odpowiedniej ViewGroup
public class XActivity extends Activity {
ActionBar.OnNavigationListener _navigationListener;
…
}
public class SimpleNavigationListener implements ActionBar.OnNavigationListener {
…
public boolean onNavigationItemSelected(int i, long l) {
String fragmentClassName = _fragmentList[i];
Fragment theFragment = Fragment.instantiate(_containingActivity, fragmentClassName);
FragmentTransaction fragmentTransaction = _containigActivity.getFragmentManager(). beginTransaction();
fragmentTransaction.replace(android.R.id.content, theFragment); //lub viewGroupId
fragmentTransaction.commit();
return true;
}
public static SimpleNavigationListener SetupListNavigation(Activity containingActivity, …) {
…
SimpleNavigationListener listener = new SimpleNavigationListener(containingActivity, …);
ActionBar actionBar = containingActivity.getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
actionBar.setListNavigationCallbacks(displayNameList, listener);
actionBar.setDisplayShowTitleEnabled(false);
}
}
Interaktywność
Widoki akcji - interaktywne widgety, które pokazują się w ActionBar
- pozwalają pokazywać okazjonalnie używane UI w ActionBar i zaoszczędzić miejsce na ekranie
- zastępuje pojedynczy element z akcją (może być stale widoczny lub automatycznie być ukrywany i pokazywany)
Definicja w XML
- specyfikujemy klasę widoku dla elementów menuItem atrybutem actionViewClass
- można używać większość klas dziedziczących po View (wbudowanych lub własnych)
- najczęściej używaną klasą jest SearchView (ma wbudowaną świadomość ActionBar)
<menu …>
<item …
android:actionViewClass=”android.widget.SearchView”
</menu>
Własne widoki akcji
Poprzez zasób z layoutem
- tak jak każdy zasób dla layoutu
- wiążemy z menuItem stosując atrybut actionLayout
<menu …>
<item …
android:actionLayout=”@layout/action_view_layout”
</menu>
Pokazywanie i ukrywanie widoków akcji
- domyślnie widok akcji jest widoczny cały czas
- możliwość dynamicznego pokazywania i ukrywania
- w atrybucie showAsAction zawieramy collapseActionView (po naciśnięciu przycisku następuje rozwinięcie do kontrolki)
- programowo
- pobieramy referencję na pozycję przy użyciu menu.findItem
- menuItem.isActionViewExpanded / menuItem.expandActionView / menuItem.collapseActionView
- odpowiadanie na pokazywanie / ukrywanie
- implementujemy interfejs onActionExpandListener (możliwość anulowania akcji przez zwrócenie false)
- boolean onMenuItemActionExpand(MenuItem menuItem)
- boolean onMenuItemActionCollapse(MenuItem menuItem)
- wiążemy listener z menuItem metodą setOnActionExpandListener
Dostępność zawartości widoku akcji z poziomu kodu
- metoda getActionView
- przy actionViewClass - zwraca referencję na tą klasę
- przy actionLayout - zwraca główny node layoutu
- zawartość z widoku akcji jest dostępna poprzez metodę findViewById
TextView
- setOnEditorActionListener
- TextView.OnEditorActionListener
- boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent)
public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
if (keyEvent != null) {
if (keyEvent.getAction() == KeyEvent.ACTION_DOWN && keyEvent.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
CharSequence enterText = textView.getText();
…
}
}
return false;
}
Brak komentarzy:
Prześlij komentarz