Animationseffekte können den interaktiven Effekt der Benutzeroberfläche erheblich verbessern. Daher sind Animationsanwendungsszenarien in der mobilen Entwicklung relativ häufig. Die Beherrschung grundlegender Animationseffekte ist in der ausgereiften Softwareentwicklung unverzichtbar. Darüber hinaus sind Benutzer viel empfänglicher für Animationen als für Texte und Bilder. Der Einsatz von Animationseffekten kann den Eindruck des Benutzers vom Produkt vertiefen. Daher werden in diesem Artikel einige gängige Animationseffekte im Android-Design vorgestellt.
Grundkenntnisse
Bevor die Animationseffekte in Android eingeführt werden, ist es notwendig, den Bildverarbeitungsmechanismus in Android einzuführen. Zu den Spezialeffekten von Bildern gehören grafische Skalierung, Spiegelung, Spiegelung, Drehung, Übersetzung usw. Die Spezialeffektverarbeitungsmethode von Bildern wird durch Multiplizieren der Grafikmatrix des Originalbilds mit einer Spezialeffektmatrix erreicht, um eine neue Grafikmatrix zu bilden. Die Matrix-Klasse verwaltet eine 3*3-Matrix, um die Koordinaten von Pixeln zu ändern. Das Bildschirmkoordinatensystem des Android-Telefons verwendet die obere linke Ecke als Ursprung, von links nach rechts die positive Richtung der x-Achse und von oben nach unten die positive Richtung der y-Achse. Die erste Zeile stellt die x-Koordinate des Pixels dar: x = 1*x 0*y 0*z, die zweite Zeile stellt die y-Koordinate des Pixels dar: y = 0*x 1*y 0*z und die dritte Zeile stellt das Pixel dar. Die Z-Koordinate von: z = 0*x 0*y 1*z. Die Spezialeffektverarbeitung von Bildern wird durch Ändern des Werts der Grafikmatrix erreicht. Unter Android hilft uns die Matrix-Klasse dabei, einige grundlegende Verwendungszwecke von Matrizen zu kapseln, sodass wir sie direkt verwenden können. Beim Bearbeiten von Bildern mit Code ist es am besten, eine Kopie des Bildes im Speicher zu verarbeiten, anstatt das Originalbild zu verarbeiten. Daher müssen Sie Bitmap verwenden, um eine leere Bitmap mit derselben Größe und demselben Format wie das Originalbild zu erstellen.
Grundlegende Schritte zum Bearbeiten von Fotos:
1. Erstellen Sie eine leere Bitmap und speichern Sie die Breiten- und Höheninformationen im Einklang mit dem Originalbild.
2. Erstellen Sie ein Zeichenbrett ;
3. Erstellen Sie einen Pinsel
4. Legen Sie die Matrix fest
5. Zeichnen Sie genau das gleiche Aussehen wie im Originalbild.
Die Codes für Bildskalierungs-, Übersetzungs-, Rotations- und Spiegeloperationen sind unten angegeben.
/** * 图片缩放 * */ private void zoom() { Bitmap srcBitmap = BitmapFactory.decodeFile("mnt/sdcard/b.jpg"); iv_src.setImageBitmap(srcBitmap); Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig()); Canvas canvas = new Canvas(copyBitmap); Paint paint = new Paint(); paint.setColor(Color.BLACK); Matrix matrix = new Matrix(); matrix.setScale(0.6f, 0.6f); canvas.drawBitmap(srcBitmap, matrix, paint); iv_dest.setImageBitmap(copyBitmap); } /** * 图片平移 * */ public void translation(){ Options ops = new Options(); ops.inSampleSize = 4; //等比放缩 Bitmap srcBitmap = BitmapFactory.decodeFile("/mnt/sdcard/b.jpg",ops); iv_src.setImageBitmap(srcBitmap); Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig()); Canvas canvas = new Canvas(copyBitmap); Paint paint = new Paint(); paint.setColor(Color.BLACK); Matrix matrix = new Matrix(); matrix.setTranslate(100, 100); canvas.drawBitmap(srcBitmap, matrix, paint); iv_dest.setImageBitmap(copyBitmap); } /** * 旋转 * */ public void scole(){ Bitmap srcBitmap = BitmapFactory.decodeFile("/mnt/sdcard/b.jpg"); iv_src.setImageBitmap(srcBitmap); Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig()); Canvas canvas = new Canvas(copyBitmap); Paint paint = new Paint(); paint.setColor(Color.BLACK); Matrix matrix = new Matrix(); matrix.setRotate(180, srcBitmap.getWidth()/2, srcBitmap.getHeight()/2);//绕原点旋转 canvas.drawBitmap(srcBitmap, matrix, paint); iv_dest.setImageBitmap(copyBitmap); } /** * 镜面特效/倒影特效 * 原理一样,一个关于x轴旋转,一个关于y轴旋转 */ public void mirror(){ Bitmap srcBitmap = BitmapFactory.decodeFile("/mnt/sdcard/b.jpg"); iv_src.setImageBitmap(srcBitmap); Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig()); Canvas canvas = new Canvas(copyBitmap); Paint paint = new Paint(); paint.setColor(Color.BLACK); Matrix matrix = new Matrix(); matrix.setScale(-1, 1); matrix.postTranslate(srcBitmap.getWidth(), 0); canvas.drawBitmap(srcBitmap, matrix, paint); iv_dest.setImageBitmap(copyBitmap); }
Kommen wir als Nächstes zum heutigen Thema. Die Animation unter Android ist in drei Typen unterteilt: Rahmenanimation, Ansichtsanimation (Tween-Animation) und Attributanimation. Diese drei Animationen werden im Folgenden vorgestellt.
Frame-Animation:
Frame-Animation ist die gebräuchlichste dieser drei Animationen, die sich auf Animationen bezieht, die Frame für Frame abgespielt werden. Um es deutlicher auszudrücken: Es handelt sich um den Effekt eines schnellen Bildwechsels. Es wird über eine Animationsliste implementiert und erstellt eine Drawable-Sequenz. Diese Drawables können einzeln gemäß dem angegebenen Zeitintervall angezeigt werden, dh die vorgefertigten Bilder werden nacheinander abgespielt.
Grundschritte für die Verwendung von Frame-Animationen:
1. Erstellen Sie die für jeden Frame der Frame-Animation erforderlichen Bilder und legen Sie sie im entsprechenden Drawable-xxx- oder Drawable-Verzeichnis ab
2 . Erstellen Sie im Zeichenverzeichnis eine Frame-Animations-XML-Datei und wählen Sie „animation-list“ als Stammknoten aus. Das Oneshot-Attribut repräsentiert die automatische Ausführung der Frame-Animation. Bei „true“ bedeutet dies, dass die Animation nur einmal abgespielt wird und beim letzten Frame stoppt. Bei „false“ bedeutet dies, dass die Animation in einer Schleife abgespielt wird.
3. Aktivieren Sie die Animation im JAVA-Code. Legen Sie den Hintergrund- oder ImageView-SRC der Ansicht fest, rufen Sie dann das AnimationDrawable-Objekt des Steuerelements ab und starten Sie die Animation
als Beispiel für die Animationsrahmenanimation mit der Methode AnimationDrawable.start ().
Code in XML-Datei:
<?xml version="1.0" encoding="utf-8"?><animation-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@drawable/desktop_rocket_launch_1" android:duration="200" /> <item android:drawable="@drawable/desktop_rocket_launch_2" android:duration="200" /></animation-list>
Implementierung von Java-Code:
iv = new ImageView(this); //开启帧动画 rocket为上述xml文件 iv.setBackgroundResource(R.drawable.rocket); AnimationDrawable ad = (AnimationDrawable) iv.getBackground(); ad.start();
Attributanimation:
Ansichtsklasse nach Android 3.0 hinzugefügt Neue Attribute, die zum Aufzeichnen von Animationsverhalten verwendet werden, können nur auf Systemen mit Android 3.0 oder höher ausgeführt werden, was bedeutet, dass Systeme mit API-11 oder höher ausgeführt werden. Die Eigenschaftsanimation ändert die Position der aktuellen Ansicht und erzeugt Animationseffekte durch dynamisches Ändern der Breite, Höhe, Koordinaten und anderer Eigenschaften des Steuerelements.
Animationseffekte werden durch die Steuerung der Eigenschaften von Steuerelementen erzielt. Eigenschaftsanimationen sind viel flexibler und leistungsfähiger als Tweening-Animationen. Es ist zu beachten, dass die Eigenschaftsanimation nicht zwischen Verschiebung, Skalierung, Transparenz und anderen Animationen unterscheidet. Die Kernidee besteht darin, die Eigenschaften eines Steuerelements zu ändern. Wir können die vier Effekte der Tween-Animation erzielen.
属性动画跟补间动画比,属性动画是真正改变了控件的属性,会改变当前的视图所在的位置,因此当控件的位置改变后只要点击到了控件“身上”就能触发onClick 事件。而补间动画则并没用改变控件的真实属性,因此不管属性动画执行后将控件移动到了哪个位置,只能通过点击该控件的原始位置才能触发onClick 事件。
通过xml 文件实现属性动画步骤:
1. 在res 下创建属性动画文件。在res 目录下创建animator 文件夹,然后创建一个objectAnimator 资源文件。资源名称自定义即可。
2. 编写属性动画文件。指定属性值。
3. 编写代码使用属性动画文件。通过AnimatorInflater加载图片资源,指定要显示动画的控件,并开启动画。
属性动画可以通过xml文件实现,但通常属性动画是通过JAVA代码实现。这里仅给出用xml文件实现淡化动画的案例,其他案例均以JAVA代码的方式实现。
JAVA代码的方式实现属性动画。
public class MainActivity extends Activity { private ImageView iv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv = (ImageView) findViewById(R.id.iv); } /** * 淡化动画 * @param view */ public void alpha(View view) { ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "alpha", new float[] { 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f }); oa.setDuration(3000); oa.setRepeatCount(ObjectAnimator.INFINITE); oa.setRepeatMode(ObjectAnimator.REVERSE); oa.start(); } /** * 平移动画 * @param view */ public void trans(View view) { ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "translationX", new float[] { 10f, 20f, 30f, 40f, 60f, 80f }); oa.setDuration(3000); oa.setRepeatCount(ObjectAnimator.INFINITE); oa.setRepeatMode(ObjectAnimator.REVERSE); oa.start(); } /** * 缩放动画 */ public void scale(View view) { ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "scaleX", new float[] { 1f, 2f, 3f, 4f, 5f, 6f }); oa.setDuration(3000); oa.setRepeatCount(ObjectAnimator.INFINITE); oa.setRepeatMode(ObjectAnimator.REVERSE); oa.start(); } /** * 旋转动画 */ public void rotate(View view) { ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "rotationY", new float[] { 90f, 180f, 270f, 360f }); oa.setDuration(3000); oa.setRepeatCount(ObjectAnimator.INFINITE); oa.setRepeatMode(ObjectAnimator.REVERSE); oa.start(); } /** * 水平平移 + 竖直平移 */ public void set(View view) { AnimatorSet set = new AnimatorSet(); ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "translationX", new float[] { 10f, 20f, 30f, 40f, 60f, 80f }); oa.setDuration(3000); ObjectAnimator oa2 = ObjectAnimator.ofFloat(iv, "translationY", new float[] { -10f, -20f, -30f, -40f, -60f, -80f }); oa2.setDuration(3000); set.playTogether(oa, oa2); set.start(); } }
xml文件实现淡化效果:
<?xml version="1.0" encoding="utf-8"?> <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:duration="3000" android:propertyName="alpha" android:repeatCount="3" android:repeatMode="reverse" android:valueFrom="0.0" android:valueTo="1.0" > </objectAnimator>
然后在java代码中实现这样一段代码:
public void alpha(View view) { Animator animator = AnimatorInflater.loadAnimator(this, R.animator.alpha); animator.setTarget(iv); animator.start(); }
View动画:
渐变动画也叫补间动画。补间动画通过对View 的内容进行一系列的图形变换(包括平移、缩放、旋转、改变透明度)来实现动画效果。动画效果的定义可以采用XML 文件来做也可以采用java 代码来做。
使用XML 文件实现View动画的步骤:
1. 在res 目录下创建anim 文件夹。
2. 在anim 文件夹中创建xml文件,文件名可以自定义。
3. 编辑xml文件。定义不同的标签,表示不同的动画效果。alpha表示淡化,
4. 添加Java 逻辑代码,使用AnimationUtils 工具类加载xml 文件,获取Animation 对象,调用startAnimation 让ImageView 执行此动画。
View动画中常用属性的含义:
duration 动画时长
fromAlpha 起始透明度,1 为完全不透明,0 为完全透明
repeatCount 重复次数,INFINITE表示无限重复
toAlpha 目标透明度
repeatMode 重复模式,restart 为重新开始,reverse表示来回播放
渐变动画在代码中使用的是AlphaAnimation 类来定义,在XML 文件中使用
使用编码方式同样可以实现view动画,直接创建相应的动画对象,然后添加相应的属。代使用编码方式实现view动画跟用XML 文件实现View动画其实是一模一样的,无非就是在JAVA代码中设定相关的属性罢了。
使用XML 文件实现View动画的代码:
1 . 在anim文件夹下新建下列文件:
<!-- alpha_demo.xml 文件夹下 --> <?xml version="1.0" encoding="utf-8"?> <alpha xmlns:android="http://schemas.android.com/apk/res/android" android:duration="2000" android:fromAlpha="0.0" android:repeatCount="infinite" android:repeatMode="reverse" android:toAlpha="1.0" > </alpha> <!-- rotate_demo.xml 文件夹下 --> <?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:duration="2000" android:fromDegrees="0" android:pivotX="50%" android:pivotY="50%" android:repeatCount="2" android:repeatMode="reverse" android:toDegrees="360" > </rotate> <!-- scale_demo.xml 文件夹下 --> <?xml version="1.0" encoding="utf-8"?> <scale xmlns:android="http://schemas.android.com/apk/res/android" android:duration="2000" android:fromXScale="20%" android:fromYScale="20%" android:pivotX="50%" android:pivotY="50%" android:repeatCount="2" android:repeatMode="reverse" android:toXScale="200%" android:toYScale="200%" > </scale> <!-- set_demo.xml 文件夹下 --> <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true" > <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:duration="2000" android:fromDegrees="0" android:pivotX="50%" android:pivotY="50%" android:repeatCount="2" android:repeatMode="reverse" android:toDegrees="360" > </rotate> <scale xmlns:android="http://schemas.android.com/apk/res/android" android:duration="2000" android:fromXScale="20%" android:fromYScale="20%" android:pivotX="50%" android:pivotY="50%" android:repeatCount="2" android:repeatMode="reverse" android:toXScale="200%" android:toYScale="200%" > </scale> </set> <!-- trans_demo.xml 文件夹下 --> <?xml version="1.0" encoding="utf-8"?> <translate xmlns:android="http://schemas.android.com/apk/res/android" android:duration="2000" android:fromXDelta="0" android:fromYDelta="0" android:repeatCount="2" android:repeatMode="reverse" android:toXDelta="100%" android:toYDelta="100%" > </translate>
2 . 在java代码中实现下列逻辑:
import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.ImageView; public class MainActivity extends Activity { private ImageView iv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv = (ImageView) findViewById(R.id.iv); } /** * 淡化动画 * @param view */ public void alpha(View view){ Animation aa = AnimationUtils.loadAnimation(this, R.anim.alpha_demo); iv.startAnimation(aa); } /** * 平移动画 * @param view */ public void trans(View view){ Animation ta = AnimationUtils.loadAnimation(this, R.anim.trans_demo); iv.startAnimation(ta); } /** * 缩放动画 */ public void scale(View view){ Animation sa = AnimationUtils.loadAnimation(this, R.anim.scale_demo); iv.startAnimation(sa); } /** * 旋转动画 */ public void rotate(View view){ Animation ra = AnimationUtils.loadAnimation(this, R.anim.rotate_demo); iv.startAnimation(ra); } /** * 旋转 + 放缩 */ public void set(View view){ Animation set = AnimationUtils.loadAnimation(this, R.anim.set_demo); iv.startAnimation(set); } }
使用java代码实现View动画的代码
import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.AnimationSet; import android.view.animation.AnimationUtils; import android.view.animation.RotateAnimation; import android.view.animation.ScaleAnimation; import android.view.animation.TranslateAnimation; import android.widget.ImageView; public class MainActivity extends Activity { private ImageView iv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv = (ImageView) findViewById(R.id.iv); } /** * 渐变动画 * @param view */ public void alpha(View view) { AlphaAnimation aa = new AlphaAnimation(0.0f, 1.0f); aa.setDuration(2000); aa.setRepeatCount(Animation.INFINITE); aa.setRepeatMode(Animation.REVERSE); iv.startAnimation(aa); } /** * 平移动画 * @param view */ public void trans(View view) { TranslateAnimation ta = new TranslateAnimation( Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1f, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1f); ta.setDuration(2000); ta.setRepeatCount(Animation.INFINITE); ta.setRepeatMode(Animation.REVERSE); iv.startAnimation(ta); } /** * 缩放动画 */ public void scale(View view) { ScaleAnimation sa = new ScaleAnimation(0.2f, 2.0f, 0.2f, 2.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); sa.setDuration(2000); sa.setRepeatCount(Animation.INFINITE); sa.setRepeatMode(Animation.REVERSE); iv.startAnimation(sa); } /** * 旋转动画 */ public void rotate(View view) { RotateAnimation ra = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); ra.setDuration(2000); ra.setRepeatCount(Animation.INFINITE); ra.setRepeatMode(Animation.REVERSE); iv.startAnimation(ra); } /** * 旋转 + 平移 + 放缩 * AnimationSet添加各个动画 */ public void set(View view) { AnimationSet set = new AnimationSet(false); RotateAnimation ra = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); ra.setDuration(2000); ra.setRepeatCount(Animation.INFINITE); ra.setRepeatMode(Animation.REVERSE); ScaleAnimation sa = new ScaleAnimation(0.2f, 2.0f, 0.2f, 2.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); sa.setDuration(2000); sa.setRepeatCount(Animation.INFINITE); sa.setRepeatMode(Animation.REVERSE); TranslateAnimation ta = new TranslateAnimation( Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1f, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1f); ta.setDuration(2000); ta.setRepeatCount(Animation.INFINITE); ta.setRepeatMode(Animation.REVERSE); set.addAnimation(ta); set.addAnimation(sa); set.addAnimation(ra); iv.startAnimation(set); } }
自此Android下的三种动画全部讲解完毕。