该小程序是实现一个ImageView在布局FrameLayout中的位移的。
布局文件如下:
实际效果图如下:
其中的ImageView是一个圆形(sun.xml):
我们使用fragment来实现布局并且通过ObjectAnimator实现sun的平移:
public class SunsetFragment extends Fragment{
private View mSceneView;
private View mSunView;
private View mSkyView;
public static SunsetFragment newInstance() {
return new SunsetFragment();
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_sunset, container, false);
mSceneView = view;
mSunView = view.findViewById(R.id.sun);
mSkyView = view.findViewById(R.id.sky);
mSceneView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startAnimation();
}
});
return view;
}
//太阳的开始和结束的坐标
private void startAnimation() {
float sunYStart = mSunView.getTop();
float sunYEnd = mSkyView.getHeight();
ObjectAnimator heightAnimator = ObjectAnimator.ofFloat(mSunView, "y", sunYStart, sunYEnd).setDuration(3000);
heightAnimator.start();
}
}
ObjectAnimator.ofFloat(mSunView, "y", sunYStart, sunYEnd)表示对mSunView进行"Y"轴方向的平移,平移的开始点是sunYStart,结束点是sunYEnd。
我们进入ObjectAnimator.java看下这个方法:
/** * Constructs and returns an ObjectAnimator that animates between float values. A single * value implies that that value is the one being animated to, in which case the start value * will be derived from the property being animated and the target object when {@link #start()} * is called for the first time. Two values imply starting and ending values. More than two * values imply a starting value, values to animate through along the way, and an ending value * (these values will be distributed evenly across the duration of the animation). * * @param target The object whose property is to be animated. This object should * have a public method on it calledsetName(), where
name is * the value of the
propertyName parameter. * @param propertyName The name of the property being animated. * @param values A set of values that the animation will animate between over time. * @return An ObjectAnimator object that is set up to animate between the given values. */ public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) { ObjectAnimator anim = new ObjectAnimator(target, propertyName); anim.setFloatValues(values); return anim; }
这段英文的意思大家应该很清楚了,主要注意的是这个propertyName。这个propertyName是需要target这个对象有setpropertyName方法的。
第一句创建anim不用说了,第二句anim.setFloatValues(values)可以看下:
@Override public void setFloatValues(float... values) { if (mValues == null || mValues.length == 0) { // No values yet - this animator is being constructed piecemeal. Init the values with // whatever the current propertyName is if (mProperty != null) { setValues(PropertyValuesHolder.ofFloat(mProperty, values)); } else { setValues(PropertyValuesHolder.ofFloat(mPropertyName, values)); } } else { super.setFloatValues(values); } }
其中 mValues 来源于 ValueAnimator.java
/** * The property/value sets being animated. */ PropertyValuesHolder[] mValues;
PropertyValuesHolder由来源于android.animation.PropertyValuesHolder.java
/** * This class holds information about a property and the values that that property * should take on during an animation. PropertyValuesHolder objects can be used to create * animations with ValueAnimator or ObjectAnimator that operate on several different properties * in parallel. */ public class PropertyValuesHolder implements Cloneable