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

Android School 02

Android School 02

Formatowanie i stylizowanie łańcuchów znaków. Menu opcji, toasty, okna dialogowe i alerty. Intencje niejawne, własne filtry intencji.

Adam Jodłowski

March 23, 2013
Tweet

More Decks by Adam Jodłowski

Other Decks in Programming

Transcript

  1. Android School
    Warsztat 02
    Adam Jodłowski

    View full-size slide

  2. 2
    Odwoływanie się do zasobów

    zasoby umieszczone w odpowiednich podkatalogach lub
    definiowane w XML (/res/values) zarządzane przez plik
    R, mają nadane symboliczne identyfikatory tekstowe
    @id/moj_przycisk
    @string/komunikat_sukces
    @drawable/logo

    zasoby pobieramy programowo dzięki kontekstowi
    Drawable pic =
    getResources().getDrawable(R.drawable.pic);
    String hello =
    getResources().getString(R.string.hello);
    String[] arr =
    getResources().getStringArray(R.array.arr);

    View full-size slide

  3. 3
    Formatowanie i stylizowanie łańcuchów znaków

    znaczniki formatujące tekst

    Hello %1$s!

    String formattedHello = String.format(
    getResources().getString(R.string.hello), "Android");

    ostylowanie tekstu za pomocą znaczników HTML

    <font color=\"green\">Goodbye</font> <b>
    %1$s</b>!

    String formattedGoodbye =
    String.format(getResources().getString(R.string.goodbye
    ), "Android");
    textView.setText(android.text.Html.fromHtml(formattedGo
    odbye));

    View full-size slide

  4. 4
    Przejrzyj różne rodzaje zasobów istniejące w projekcie,
    pobierz je w kodzie, sformatuj i ostyluj treść TextView.

    View full-size slide

  5. 5
    Menu opcji

    strukturę menu opcji definiujemy jako plik XML w katalogu /res/menu
    korzeń pliku, jest kontenerem dla menu
    grupuje elementy w jednej kategorii
    reprezentuje pojedyńczy element, może zawierać zagnieżdżony
    element tworząc podmenu


    android:icon="@drawable/informacje"
    android:title="@string/informacje" />
    android:icon="@drawable/pomoc"
    android:title="@string/pomoc" />

    View full-size slide

  6. 6
    Podpinanie menu opcji do aktywności

    musimy przesłonić metodę zwrotną tworzenia menu i reakcji na wybór
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main_menu, menu);
    return true; // wyswietl menu
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.informacje:
    pokazInformacje();
    return true;
    case R.id.pomoc:
    pokazPomoc();
    return true;
    default:
    return super.onOptionsItemSelected(item);
    }
    }

    View full-size slide

  7. 7
    Toasty

    podstawowy mechanizm nieinwazyjnych powiadomień
    Toast toast = Toast.makeText(kontekst, wiadomosc, czas
    trwania);
    toast.show();

    czas trwania to jedna z dwóch stałych
    Toast.LENGTH_SHORT i Toast.LENGTH_LONG

    możemy wypozycjonować toast na ekranie
    toast.setGravity(...);
    używając flag zdefiniowanych w android.view.Gravity.* i podając
    wielkości marginesów (w pikselach)

    możemy ustawić layout całego toastu na własny (uwaga na root!)
    LayoutInflater inflater = getLayoutInflater();
    View layout = inflater.inflate(R.layout.toast_layout,
    (ViewGroup) findViewById(R.id.toast_layout_root));
    toast.setView(layout);

    View full-size slide

  8. 8
    Stwórz menu (opcjonalnie z zagnieżdżeniem) i podepnij je
    do aktywności.
    Wyświetl Toast na naciśnięcie przycisku menu, zmień
    jego domyślną pozycję, ustaw marginesy w jednostkach
    niezależnych od gęstości (dp) korzystając z programowego
    pobierania zasobów typu dimen.

    View full-size slide

  9. 9
    Okna dialogowe

    są modalne, asynchroniczne i zarządzane

    najprostszym sposobem na utworzenie okna
    dialogowego jest skorzystanie z buildera klasy
    AlertDialog
    AlertDialog.Builder dialog = new
    AlertDialog.Builder(aktywnosc);
    dialog.setTitle("Potwierdzenie");
    dialog.setMessage("Zapisac zmiany?");
    dialog.setPositiveButton("Tak", listener);
    dialog.setNegativeButton("Nie", listener);
    dialog.setNeutralButton("Anuluj", listener);
    dialog.show();

    Klasa listenerów to
    DialogInterface.OnClickListener()

    View full-size slide

  10. 10
    Dialog z listą checkboksów

    przykład bardziej złożonego dialogu
    final String[] colors = new String[] {"niebieski", "biały",
    "czerwony"};
    AlertDialog.Builder dialog = new AlertDialog.Builder(activity);
    dialog.setTitle("Wybierz kolory");
    dialog.setMultiChoiceItems(colors, new boolean[] {false, true,
    false}, new DialogInterface.OnMultiChoiceClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which, boolean
    isChecked) {
    // reakcja na klikniecie checkboksa
    }
    });
    dialog.setPositiveButton("Zatwierdz", listener);
    dialog.setNegativeButton("Anuluj", listener);
    dialog.show();

    View full-size slide

  11. 11
    Utwórz i wyświetl okno dialogowe, zareaguj na decyzję
    użytkownika za pomocą listenerów.

    View full-size slide

  12. 12
    Zezwolenia

    wiele czynności systemowych wymaga zezwoleń
    udzielonych przez użytkownika podczas instalacji
    aplikacji (wysyłanie SMS, odbieranie połączeń, łączenie
    z Internetem, itd.)

    dodajemy je w manifeście, zakładka Permissions > Add
    > Uses Permission

    CALL_PHONE, CAMERA, INTERNET, VIBRATE, ...

    próba wykonania czynności, na którą aplikacja nie
    otrzymała zezwolenia, zakończy się niepowodzeniem

    View full-size slide

  13. 13
    Intencje niejawne

    poznaliśmy dotychczas intencje jawne (explicit), dzięki
    którym przechodziliśmy pomiędzy aktywnościami
    naszej własnej aplikacji

    w intencji niejawnej (implicit) nie specyfikujemy nazwy
    (klasy) komponentu docelowego

    podajemy nazwę akcji do wykonania i opcjonalnie dane
    (data) w postaci URI, ich typ MIME, kategorię intencji i
    wartości extras

    określamy jaką czynność chcemy wykonać, ale nie
    musimy znać komponentu, który to potrafi (nie mamy
    też gwarancji, że takowy istnieje w systemie)

    View full-size slide

  14. 14
    Intencje niejawne

    aktywności odpalamy w sposób tradycyjny
    Intent intent = new Intent(akcja, [URI]);
    startActivity(intent);

    przykładowe parametry dla intencji systemowych
    Intent.ACTION_VIEW
    Uri.parse("http://www.android.com")
    Intent.ACTION_CALL
    Uri.parse("tel:(+48)111222333")
    Intent.ACTION_DIAL
    Uri.parse("tel:(+48)111222333")
    Intent.ACTION_VIEW
    Uri.parse("geo:52.408333,16.908333?z=18")
    Intent.ACTION_VIEW
    Uri.parse("http://maps.google.com/maps?saddr=" + s_lat + ","
    + s_lon + "&daddr=" + d_lat + "," + d_lon)
    Intent.ACTION_VIEW
    Uri.parse("market://details?id=com.rovio.angrybirds")

    View full-size slide

  15. 15
    Przetestuj działanie niejawnych intencji systemowych,
    pamiętaj o zezwoleniach!

    View full-size slide

  16. 16
    Jak to działa?

    aktywności, usługi (services) i odbiorcy komunikatów rozgłoszeniowych
    (broadcast receivers) mogą deklarować filtry intencji

    intencje niejawne przechodzą przez te filtry i trafiają do wszystkich
    pasujących do nich komponentów, deklarujących ich obsługę

    chęć odbioru intencji rejestrujemy w manifeście, w węźle danego
    komponentu – ustalamy nazwę akcji i jej schemat URI w postaci






    aby ograniczyć obsługiwane intencje do specyficznych przypadków,
    możemy dodać kolejne węzły filtrujące
    android:port="80" android:path="/search" />


    dokumentacja zawiera informacje o priorytetach składowych filtrów

    View full-size slide

  17. 17
    Reakcja na intencję niejawną

    jeśli intencja pasuje do jednego z filtrów komponentu i ma on
    najwyższy priorytet albo zostanie ręcznie wybrany przez
    użytkownika – zostanie on uruchomiony przez system operacyjny

    przykładowa aktywność odbierająca intencję, może odczytać akcję,
    składowe URI i inne dane pomocnicze, aby sprawdzić, czy dane
    wejściowe są poprawne
    Intent intent = getIntent();
    String action = intent.getAction();
    String uriPath = intent.getDataString();
    if (uruchomiono aktywnosc przez odpowiednia intencje) {
    // przetwarzamy dane...
    }

    w razie potrzeby, zamykamy aktywność odbiorczą i zwracamy
    rezultat

    View full-size slide

  18. 18
    W pierwszej aplikacji zaimplementuj nową aktywność
    przyjmującą intencję swojego własnego typu, przetestuj jej
    działanie wywołując tę intencję niejawną z drugiej, osobnej
    aplikacji.
    Stwórz trzecią aplikację z aktywnością zdolną do
    przetworzenia tej samej intencji niejawnej co pierwsza
    aplikacja, odpal intencję niejawną w drugiej aplikacji i
    zaobserwuj co się stanie.

    View full-size slide

  19. 19
    Zadanie domowe:
    Połącz wiedzę z dotychczasowych warsztatów i stwórz
    przykładową aplikację demonstrującą poznane techniki.

    View full-size slide