有这样一个需求,需要点击图片放大缩小动画,效果:

我们借助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:///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;
}
分享这个小例子的初衷,是希望大家对于一个小小的知识点,我们可以跟进看看其中的实现过程,了解过程,麻雀虽小但五脏俱全,希望对你有帮助。https://mp.weixin.qq.com/s/CAi8m7uiq_JsIMgEjXh2dA
















