有这样一个需求,需要点击图片放大缩小动画,效果:
我们借助Android自带动画Animation ,很容易实现
初始化对象
- Animation animation;
- private ImageView iv_good;
- animation= AnimationUtils.loadAnimation(this, R.anim.anim_small);
按钮点击事件
- iv_good.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- iv_good.startAnimation(animation);
- }
- });
属性动画
res/anim/anim_small.xml
- <?xml version="1.0" encoding="utf-8"?>
- <set xmlns:android="http://schemas.android.com/apk/res/android"
- android:fillAfter="false">
- <scale
- android:duration="300"
- android:fromXScale="1"
- android:fromYScale="1"
- android:pivotX="50%"
- android:pivotY="50%"
- android:toXScale="2"
- android:toYScale="2" />
- <scale
- android:duration="300"
- android:fromXScale="1"
- android:fromYScale="1"
- android:pivotX="50%"
- android:pivotY="50%"
- android:startOffset="300"
- android:toXScale="0.5"
- android:toYScale="0.5" />
- </set>
- <ImageView
- android:id="@+id/iv_good"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@mipmap/ic_good"/>
下面我们重点来关注AnimationUtils 这个类中loadAnimation的方法,跟进进去看看
- /**
- * Loads an {@link Animation} object from a resource
- *
- * @param context Application context used to access resources
- * @param id The resource id of the animation to load
- * @return The animation object reference by the specified id
- * @throws NotFoundException when the animation cannot be loaded
- */
- public static Animation loadAnimation(Context context, @AnimRes int id)
- throws NotFoundException {
- XmlResourceParser parser = null;
- try {
- parser = context.getResources().getAnimation(id);
- return createAnimationFromXml(context, parser);
- } catch (XmlPullParserException ex) {
- NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
- Integer.toHexString(id));
- rnf.initCause(ex);
- throw rnf;
- } catch (IOException ex) {
- NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
- Integer.toHexString(id));
- rnf.initCause(ex);
- throw rnf;
- } finally {
- if (parser != null) parser.close();
- }
- }
我们发现重要的是调用createAnimationFromXml方法。再次跟进看看createAnimationFromXml方法。
- private static Animation createAnimationFromXml(Context c, XmlPullParser parser)
- throws XmlPullParserException, IOException {
- return createAnimationFromXml(c, parser, null, Xml.asAttributeSet(parser));
- }
- private static Animation createAnimationFromXml(Context c, XmlPullParser parser,
- AnimationSet parent, AttributeSet attrs) throws XmlPullParserException, IOException {
- Animation anim = null;
- // Make sure we are on a start tag.
- int type;
- int depth = parser.getDepth();
- while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
- && type != XmlPullParser.END_DOCUMENT) {
- if (type != XmlPullParser.START_TAG) {
- continue;
- }
- String name = parser.getName();
- if (name.equals("set")) {
- anim = new AnimationSet(c, attrs);
- createAnimationFromXml(c, parser, (AnimationSet)anim, attrs);
- } else if (name.equals("alpha")) {
- anim = new AlphaAnimation(c, attrs);
- } else if (name.equals("scale")) {
- anim = new ScaleAnimation(c, attrs);
- } else if (name.equals("rotate")) {
- anim = new RotateAnimation(c, attrs);
- } else if (name.equals("translate")) {
- anim = new TranslateAnimation(c, attrs);
- } else {
- throw new RuntimeException("Unknown animation name: " + parser.getName());
- }
- if (parent != null) {
- parent.addAnimation(anim);
- }
- }
- return anim;
- }
细心的你,不难发现XmlPullParser,其实就是我们上面定义的anim_small.xml,解析出这份xml里面的属性,进行加载动画效果。Android系统已经为我们解析分装好,我们只需要使用轮子就好了。
- /**
- * Add a child animation to this animation set.
- * The transforms of the child animations are applied in the order
- * that they were added
- * @param a Animation to add.
- */
- public void addAnimation(Animation a) {
- mAnimations.add(a);
- boolean noMatrix = (mFlags & PROPERTY_MORPH_MATRIX_MASK) == 0;
- if (noMatrix && a.willChangeTransformationMatrix()) {
- mFlags |= PROPERTY_MORPH_MATRIX_MASK;
- }
- boolean changeBounds = (mFlags & PROPERTY_CHANGE_BOUNDS_MASK) == 0;
- if (changeBounds && a.willChangeBounds()) {
- mFlags |= PROPERTY_CHANGE_BOUNDS_MASK;
- }
- if ((mFlags & PROPERTY_DURATION_MASK) == PROPERTY_DURATION_MASK) {
- mLastEnd = mStartOffset + mDuration;
- } else {
- if (mAnimations.size() == 1) {
- mDuration = a.getStartOffset() + a.getDuration();
- mLastEnd = mStartOffset + mDuration;
- } else {
- mLastEnd = Math.max(mLastEnd, a.getStartOffset() + a.getDuration());
- mDuration = mLastEnd - mStartOffset;
- }
- }
- mDirty = true;
- }
分享这个小例子的初衷,是希望大家对于一个小小的知识点,我们可以跟进看看其中的实现过程,了解过程,麻雀虽小但五脏俱全,希望对你有帮助。
作者:洪生鹏
来源:51CTO