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

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. 2 Animowane grafiki • potrzebujemy osobne grafiki dla każdej klatki

    oraz XML w /res/drawable <?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" id="@+id/spinner_animation_id" android:oneshot="false"> <item android:drawable="@drawable/sync_1" android:duration="100" /> <item android:drawable="@drawable/sync_2" android:duration="100" /> <item android:drawable="@drawable/sync_3" android:duration="100" /> <item android:drawable="@drawable/sync_4" android:duration="100" /> </animation-list> • odtwarzanie animacji ImageView iv = (ImageView) findViewById(R.id.imageView); iv.setImageDrawable(getResources().getDrawable(R.drawable.my_animation)); AnimationDrawable anim = (AnimationDrawable) iv.getDrawable(); ... anim.start();
  2. 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 <?xml version="1.0" encoding="utf-8" ?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> <alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:startOffset="0" android:duration="5000"> </alpha> </set> • aby reagować na zmiany stanu animacji, warto zaimplementować android.view.animation.Animation.AnimationListener
  3. 4 Animacje przejść • przykład skalowania widoków <scale android:pivotX="50%" 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 <set> układamy korzystając z właściwości startOffset i duration • przykład obrotu <rotate android:fromDegrees="0" android:toDegrees="360" android:pivotX="50%" android:pivotY="50%" android:duration="5000" /> • przykład przesunięcia <translate android:toXDelta="100[%][p]" android:duration="2500" /> • wszystkie animacje w formie XML można również tworzyć w sposób programowy
  4. 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; } . . .
  5. 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 <set> android:interpolator="@android:anim/bounce_interpolator" • możemy tworzyć również własne interpolatory oraz modyfikować istniejące . . . . .
  6. 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
  7. 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; } }); . .
  8. 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
  9. 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); } ... }
  10. 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 <uses-feature android:name="android.hardware.sensor.proximity" /> • symulowanie odczytów w emulatorze zapewnia projekt Sensor Simulator
  11. 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); }
  12. 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()*