$30 off During Our Annual Pro Sale. View Details »

Android School 07

Android School 07

Adam Jodłowski

April 29, 2013
Tweet

More Decks by Adam Jodłowski

Other Decks in Programming

Transcript

  1. Android School
    Warsztat 07
    Adam Jodłowski

    View Slide

  2. 2
    Animowane grafiki

    potrzebujemy osobne grafiki dla każdej klatki oraz XML w /res/drawable

    id="@+id/spinner_animation_id" android:oneshot="false">






    odtwarzanie animacji
    ImageView iv = (ImageView) findViewById(R.id.imageView);
    iv.setImageDrawable(getResources().getDrawable(R.drawable.my_animation));
    AnimationDrawable anim = (AnimationDrawable) iv.getDrawable();
    ...
    anim.start();

    View Slide

  3. 3
    Animacje przejść

    zaprezentowane zostanie klasyczne API, nowa wersja oparta jest na Animator i została
    przeportowana w projekcie NineOldAndroids dla starszych platform

    możemy w prosty sposób animować obiekty (pod)typu View, klatki animacji są
    interpolowane na podstawie definicji przekształceń, najczęściej z plików XML
    Animation anim = AnimationUtils.loadAnimation(ctx, R.anim.myanim);
    view.startAnimation(anim);

    przykład zmiany przezroczystości

    android:shareInterpolator="false">
    android:toAlpha="0.0"
    android:startOffset="0"
    android:duration="5000">



    aby reagować na zmiany stanu animacji, warto zaimplementować
    android.view.animation.Animation.AnimationListener

    View Slide

  4. 4
    Animacje przejść

    przykład skalowania widoków
    android:pivotY="50%"
    android:fromXScale="1.0"
    android:fromYScale="1.0"
    android:toXScale="2.0"
    android:toYScale="2.0"
    android:duration="2000" />

    sekwencje w węźle układamy korzystając z właściwości startOffset i duration

    przykład obrotu
    android:toDegrees="360"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="5000" />

    przykład przesunięcia


    wszystkie animacje w formie XML można również tworzyć w sposób programowy

    View Slide

  5. 5
    Animacje programowe

    przykład tworzenia animacji przejść w sposób programowy
    private Animation inFromLeftAnimation() {
    Animation anim = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, -1.0f,
    Animation.RELATIVE_TO_PARENT, 0.0f,
    Animation.RELATIVE_TO_PARENT, 0.0f,
    Animation.RELATIVE_TO_PARENT, 0.0f);
    anim.setDuration(300);
    anim.setInterpolator(new AccelerateInterpolator());
    return anim;
    }
    private Animation outToRightAnimation() {
    Animation anim = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0.0f,
    Animation.RELATIVE_TO_PARENT, +1.0f,
    Animation.RELATIVE_TO_PARENT, 0.0f,
    Animation.RELATIVE_TO_PARENT, 0.0f);
    anim.setDuration(300);
    anim.setInterpolator(new AccelerateInterpolator());
    return anim;
    }
    .
    .
    .

    View Slide

  6. 6
    Interpolatory

    interpolatory określają tempo i efekty przejść, rozróżniamy m.in.
    AccelerateInterpolator, AnticipateInterpolator,
    BounceInterpolator, CycleInterpolator, OvershootInterpolator

    aplikujemy je jako właściwości w XML dla węzła
    android:interpolator="@android:anim/bounce_interpolator"

    możemy tworzyć również własne interpolatory oraz modyfikować
    istniejące
    .
    .
    .
    .
    .

    View Slide

  7. 7
    Zapoznaj się z różnymi rodzajami animacji i
    przekształceń komponentów wizualnych.

    View Slide

  8. 8
    ViewFlipper

    komponent zawierający widoki podrzędne, które wyświetla
    pojedynczo i opcjonalnie animuje przejścia między nimi
    setInAnimation(ctx, android.R.anim.slide_in_left);
    setOutAnimation(ctx, android.R.anim.slide_out_right);
    showNext();
    showPrevious();
    setDisplayedChild(index);
    setFlipInterval(5000);
    setAutoStart(true);
    startFlipping();
    stopFlipping();

    umieszczamy komponent w layoucie danego ekranu a w jego
    środku widoki, które mają być animowane

    View Slide

  9. 9
    Przetestuj komponent ViewFlipper.

    View Slide

  10. 10
    Reakcja na dotyk

    każdy widok może zarejestrować metodę zwrotną, wywoływaną w
    reakcji na dotyk
    ImageView iv = (ImageView) findViewById(R.id.imageView1);
    iv.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
    Log.d("AS", "ACTION=" + event.getAction());
    Log.d("AS", "X=" + event.getX());
    Log.d("AS", "Y=" + event.getY());
    return true;
    }
    });
    .
    .

    View Slide

  11. 11
    Rozpoznawanie gestów, GestureDetector

    przesłaniamy metodę aktywności i rozpoznajemy dotyk
    @Override
    public boolean onTouchEvent(MotionEvent touchevent) {
    switch (touchevent.getAction()) {
    case MotionEvent.ACTION_DOWN:
    startX = touchevent.getX();
    break;
    case MotionEvent.ACTION_UP:
    if (startX < touchevent.getX()) ...
    if (startX > touchevent.getX()) ...
    break;
    case MotionEvent.ACTION_MOVE:
    touchevent.getX(); ...
    touchevent.getY(); ...
    break;
    }
    return false;
    }
    ● GestureDetector wykrywa za nas najpopularniejsze proste gesty, używamy do tego interfejsu
    SimpleOnGestureListener
    onDown();
    onSingleTapConfirmed();
    onDoubleTap();
    onLongPress();
    onScroll();
    onFling();
    ● ScaleGestureDetector wykrywa gesty wielodotykowe służące do skalowania widoków

    View Slide

  12. 12
    Przykład rozpoznawania gestów

    tworzymy obiekt własnego detektora gestów i używamy go w aktywności lub konkretnym widoku
    GestureDetector myGestureDetector = new GestureDetector(new MyGestureDetector());
    @Override
    public boolean onTouchEvent(MotionEvent me) {
    return myGestureDetector.onTouchEvent(me);
    }

    przykład implementacji detektora
    class MyGestureDetector extends SimpleOnGestureListener {
    private static final int MIN_DISTANCE = 120;
    private static final int MAX_DISTANCE = 250;
    private static final int VELOCITY = 200;
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
    if (Math.abs(e1.getY() - e2.getY()) > MAX_DISTANCE) return false;
    if (e1.getX() - e2.getX() > MIN_DISTANCE && Math.abs(velocityX) > VELOCITY) {
    flipper.setInAnimation(inFromRightAnimation());
    flipper.setOutAnimation(outToLeftAnimation());
    flipper.showNext();
    } else if (e2.getX() - e1.getX() > MIN_DISTANCE && Math.abs(velocityX) > VELOCITY) {
    flipper.setInAnimation(inFromLeftAnimation());
    flipper.setOutAnimation(outToRightAnimation());
    flipper.showPrevious();
    }
    return super.onFling(e1, e2, velocityX, velocityY);
    }
    ...
    }

    View Slide

  13. 13
    Przetestuj możliwości wykrywania dotyku.

    View Slide

  14. 14
    Sensory

    urządzenia mogą posiadać wiele czujników, m.in.
    światła
    bliskości
    temperatury
    ciśnienia
    przyspieszenia
    pola magnetycznego

    możemy zgłosić w manifeście wymaganie posiadania
    czujnika przez urządzenie
    android:name="android.hardware.sensor.proximity" />

    symulowanie odczytów w emulatorze zapewnia projekt
    Sensor Simulator

    View Slide

  15. 15
    Inicjalizacja i odczyt wartości

    musimy pobrać usługę SensorManagera i zainicjować interesujący nas sensor
    SensorManager sensorManager = (SensorManager)
    this.getSystemService(SENSOR_SERVICE);
    Sensor lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
    sensorManager.registerListener(this, lightSensor,
    SensorManager.SENSOR_DELAY_NORMAL); // rejestracja
    ...
    sensorManager.unregisterListener(this, lightSensor); // wyrejestrowanie

    częstotliwość odczytów może być regulowana dodatkowymi parametrami, jak
    SENSOR_DELAY_UI, SENSOR_DELAY_GAME, SENSOR_DELAY_FASTEST

    implementujemy interfejs SensorEventListener
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    Log.d("AS", "dokladnosc sensora " + sensor.getName() + " wynosi: " +
    accuracy);
    }
    @Override
    public void onSensorChanged(SensorEvent event) {
    String values = "";
    for (float v : event.values) values += v + ", ";
    Log.d("AS", "odczyt " + event.sensor.getName() + ": " + values);
    }

    View Slide

  16. 16
    Możliwości API sensorów

    odczyty z sensorów udostępniają wartości pomocnicze
    wykorzystywany prąd w mA
    maksymalną przyjmowaną wartość
    rozdzielczość czujnika
    nazwę producenta, typ i wersję

    korzystamy z pakietu android.hardware

    najczęściej wykorzystujemy akcelerometr, spoczywający
    telefon powinien zwrócić odczyty (0, 0, 9.81) w osiach X,
    Y i Z, podaje on siły działające na urządzenie
    uwzględniając grawitację

    orientację ekranu odczytujemy z
    Display.getRotation()/getOrientation()*

    View Slide

  17. 17
    Przetestuj możliwości odczytu wartości sensorów.

    View Slide

  18. 18
    Zadanie domowe:
    Stwórz aplikację wykorzystującą poznane techniki
    animacji i rozpoznawania dotyku.

    View Slide