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

Android School 07

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

Android School 07

Avatar for Adam Jodłowski

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()*