博文地址

我的GitHub 我的博客 我的微信 我的邮箱
baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

基本使用演示

MainActivity

// 可操控的属性有:alpha;x/y;scaleX/scaleY;rotation/rotationX/rotationY;transitionX/transitionY;pivotX/pivotY
public class MainActivity extends ListActivity {
private ImageView iv_src;
private boolean b = true; private String[] array = {"重启当前Activity,启动一个新的Activity",
"最简单的ObjectAnimator,控制scaleX、rotationX",
"不存在get/set方法时不会有任何效果\n为Object的某个属性手动提供get/set方法",
"只有set没有get方法时,get的值不存在,但是set可以正常使用",
"监听动画更新:AnimatorUpdateListener\n监听动画状态:AnimatorListener",
"组合动画:AnimatorSet.playTogether\n组合动画:AnimatorSet.with/before/after",
"组合动画:AnimatorUpdateListener\n组合动画:PropertyValuesHolder",
"组合动画:PVHolder + KeyFrame\nView的animate动画,最简洁的属性动画",
"View的animate动画也可以组合动画\n可以在animate动画前/后执行一些操作",
"最简单的ValueAnimator,控制translationY\n要明白ValueAnimator只是帮你计算插值的"}; protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏
setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, array)); iv_src = new ImageView(this);
iv_src.setBackgroundColor(0x330000ff);
iv_src.setImageResource(R.drawable.icon);
getListView().addHeaderView(iv_src);
} @Override
protected void onListItemClick(ListView l, View view, int position, long id) {
switch (position) {
case 0:
b = !b;
Toast.makeText(this, "目前为:" + b, Toast.LENGTH_SHORT).show();
break;
case 1:
if (b) recreate();//重启当前Activity
else startActivity(new Intent(this, SecondActivity.class));
break;
case 2://最简单的ObjectAnimator,控制scaleX、rotationX
if (b) ObjectAnimator.ofFloat(iv_src, "scaleX", 1f, 0.1f, 3f, 0.1f, 1f)//X轴缩放
.setDuration(1000)
.start();
else ObjectAnimator.ofFloat(iv_src, "rotationX", 0.0f, 720.0f)//沿X轴旋转
.setDuration(500)
.start();
break;
case 3://不存在get/set方法时不会有任何效果,可以为Object的某个属性手动提供get/set方法
int i = new Random().nextInt(8) + 1;
if (b) ObjectAnimator.ofFloat(iv_src, "width", 100 * i)//没任何效果,但并不会报错
.setDuration(500)
.start();
else ObjectAnimator.ofInt(new WrapperView(iv_src), "width", 100 * i) //提供set方法
.setDuration(500)
.start();
break;
case 4://只有set没有get方法时,get的值不存在,但是set可以正常使用
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
iv_src.setBackgroundColor(Color.WHITE); //有set方法,但是没有get方法,所以get结果为0
if (b) ObjectAnimator.ofArgb(iv_src, "backgroundColor", Color.RED)
.setDuration(1000)
.start();
else ObjectAnimator.ofArgb(iv_src, "backgroundColor", Color.RED, Color.GREEN, Color.BLUE)
.setDuration(3000)
.start();
}
break;
case 5://监听动画更新:AnimatorUpdateListener,监听动画状态:AnimatorListener
AnimHelper.addAnimListener(iv_src).start();
break;
case 6://组合动画:AnimatorSet.playTogether/with/before/after
if (b) AnimHelper.combinedAnimPlayTogether(iv_src).start();
else AnimHelper.combinedAnimAfterBefore(iv_src).start();
break;
case 7://组合动画:AnimatorUpdateListener,PropertyValuesHolder
if (b) AnimHelper.combinedAnimUpdate(iv_src).start();
else AnimHelper.propertyValuesHolder(iv_src).start();
break;
case 8://组合动画:PVHolder + KeyFrame,View的animate动画,最简洁的属性动画
if (b) AnimHelper.pVHolderKeyFrame(iv_src).start();
else iv_src.animate().y(200 * (new Random().nextInt(8))).setDuration(500).start();//ViewPropertyAnimator
break;
case 9://View的animate动画也可以组合动画,也可以在animate动画前/后执行一些操作
if (b) iv_src.animate()
.setDuration(1000)
.rotation(360 * new Random().nextInt(8))
.scaleX(new Random().nextInt(8) * 0.5f)
.setInterpolator(new DecelerateInterpolator())
.start();
else iv_src.animate()
.alpha(0.1f)
.y(1500)
.setDuration(800)
.withStartAction(() -> iv_src.setX(300))
.withEndAction(() -> {
iv_src.setX(0);
iv_src.setY(0);
iv_src.setAlpha(1f);
})
.start();
break;
case 10://最简单的ValueAnimator,控制translationY,要明白ValueAnimator只是帮你计算插值的
if (b) AnimHelper.valueAnimator(iv_src).start();
else AnimHelper.valueAnimator(iv_src, getListView()).start();
break;
}
}
}

View包装类

View包装类,为不存在get/set方法的属性提供get/set方法

// View包装类,为不存在get/set方法的属性提供get/set方法
public class WrapperView {
private View mTarget; public WrapperView(View target) {
mTarget = target;
} public int getWidth() {
return mTarget.getLayoutParams().width;
} public void setWidth(int width) {
mTarget.getLayoutParams().width = width;
mTarget.requestLayout();
} public int getHeight() {
return mTarget.getLayoutParams().height;
} public void setHeight(int height) {
mTarget.getLayoutParams().height = height;
mTarget.requestLayout();//Call this when something has changed which has invalidated the layout of this view
}
}

构建动画的工具类

public class AnimHelper {

    //监听动画绘制过程
public static ObjectAnimator addAnimListener(View view) {
ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", 0.1f, 1f).setDuration(1000);
//方法一,实现AnimatorListener接口,监听开始Start、结束End、被取消Cancel、重复Repeat等事件
//方法二,继承AnimatorListenerAdapter,只实现自己想实现的事件
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
Log.i("bqt", "【onAnimationStart】");
} @Override
public void onAnimationEnd(Animator animation) {
Log.i("bqt", "【onAnimationEnd】");
}
});
anim.addUpdateListener(animation -> {
Float value = (Float) animation.getAnimatedValue();
view.setRotationX((1 - value) * 360);
Log.i("bqt", "onAnimationUpdate--" + value); //非常频繁
});
return anim;
} public static AnimatorSet combinedAnimPlayTogether(View view) {
ObjectAnimator anim1 = ObjectAnimator.ofFloat(view, "scaleX", 0, 2f, 1f);
ObjectAnimator anim2 = ObjectAnimator.ofFloat(view, "alpha", 0, 1f);
ObjectAnimator anim3 = ObjectAnimator.ofFloat(view, "rotationY", 360); AnimatorSet animSet = new AnimatorSet().setDuration(2000);
animSet.playTogether(anim1, anim2, anim3);
return animSet;
} public static AnimatorSet combinedAnimAfterBefore(View view) {
ObjectAnimator anim1 = ObjectAnimator.ofFloat(view, "scaleX", 1.0f, 2f);
ObjectAnimator anim2 = ObjectAnimator.ofFloat(view, "scaleY", 0.1f, 1f);
ObjectAnimator anim3 = ObjectAnimator.ofFloat(view, "x", 0, -view.getWidth(), 0);
ObjectAnimator anim4 = ObjectAnimator.ofFloat(view, "y", 0, view.getY() + 500f, 0);
ObjectAnimator anim5 = ObjectAnimator.ofFloat(view, "rotationX", 360 * 2); AnimatorSet animSet = new AnimatorSet();
animSet.play(anim1).with(anim2);//anim1,anim2同时执行
animSet.play(anim2).with(anim3);//anim1,anim2,anim3同时执行
animSet.play(anim4).after(anim3).before(anim5);//anim4在anim1,anim2,anim3之后,在anim5之前
animSet.setDuration(1000);
return animSet;
} public static Animator combinedAnimUpdate(View view) {
//ObjectAnimator anim = ObjectAnimator.ofFloat(view, "包青天", 0.5f, 0.1f, 2f).setDuration(2000);
ValueAnimator anim = ValueAnimator.ofFloat(0.5f, 0.1f, 2f).setDuration(2000); //效果和上面的ObjectAnimator完全一样
anim.addUpdateListener(animation -> {
float cVal = (Float) animation.getAnimatedValue();
view.setScaleX(cVal);
view.setAlpha(cVal);
view.setRotationX(cVal * 360);
});
return anim;
} public static ObjectAnimator propertyValuesHolder(View view) {
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 0.2f, 1f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 0.8f, 0, 2f);
PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("rotationY", 360 * 2f, 0);
return ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvhY, pvhZ).setDuration(1000);//三个动画是同时执行的
} public static ObjectAnimator pVHolderKeyFrame(View view) {
Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
Keyframe kf1 = Keyframe.ofFloat(0.5f, 360f);
Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
kf1.setInterpolator(new AccelerateInterpolator());
PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
return ObjectAnimator.ofPropertyValuesHolder(view, pvhRotation).setDuration(1000);
} public static ValueAnimator valueAnimator(View view) {
ValueAnimator animator = ValueAnimator.ofFloat(0, 800, 0).setDuration(500);//没有设置要操作的【对象】及【对象的属性】
//animator.setTarget(view);//对ValueAnimator来说,这个方法是空方法(没有意义),因为它不会作用在任何View上
//对ValueAnimator来说,是通过addUpdateListener,在回调中根据动画的值来手动设置属性的值的
animator.addUpdateListener(animation -> {
Float f = (Float) animation.getAnimatedValue();//这里只能强转为of**时指定的类型
view.setTranslationY(f);//设置要操作的对象的属性。或者你可以使用获取到的值做任何事情
});
return animator;
} public static ValueAnimator valueAnimator(View view, ListView listView) {
ValueAnimator animator = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
animator = ValueAnimator.ofArgb(Color.GREEN).setDuration(5000);
animator.addUpdateListener(animation -> {
Integer greenColor = (Integer) animation.getAnimatedValue(); //实时获取值
int myColor = (int) (animation.getAnimatedFraction() * Color.YELLOW);
int count = listView.getAdapter().getCount();
for (int i = 1; i < count; i++) {
if (i % 2 == 0) listView.getChildAt(i).setBackgroundColor(greenColor);
else listView.getChildAt(i).setBackgroundColor(myColor);
}
});
}
return animator;
}
}

自定义 TypeEvaluator 实现抛物线动画效果

// 自定义TypeEvaluator实现抛物线动画效果
public class TypeEvaluatorActivity extends Activity {
private static final int RADIUS_BALL = 10; //小球的半径
private static final int RADIUS_TRACE = 3; //轨迹的半径
private ImageView iv_src;
RelativeLayout layout; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏
initView();
layout = new RelativeLayout(this);
layout.setBackgroundColor(Color.LTGRAY);
layout.setOnClickListener(v -> anim());
layout.addView(iv_src, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
setContentView(layout);
} private void initView() {
Bitmap bitmap = Bitmap.createBitmap(2 * RADIUS_BALL, 2 * RADIUS_BALL, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setAntiAlias(true);
paint.setDither(true);
canvas.drawCircle(RADIUS_BALL, RADIUS_BALL, RADIUS_BALL, paint);
iv_src = new ImageView(this);
iv_src.setImageBitmap(bitmap);
} private void anim() {
final int color = 0xFF000000 + new Random().nextInt(0xFFFFFF);
Point point = new Point();
((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getSize(point);
PointF startPointF = new PointF(0, 0);
PointF endPointF = new PointF(point.x - iv_src.getWidth(), point.y - iv_src.getHeight()); ValueAnimator animator = new ValueAnimator().setDuration(1000);
animator.setInterpolator(new LinearInterpolator()); //插值器,默认为AccelerateDecelerateInterpolator【慢-快-慢】
//通过new创建的ValueAnimator必须setObjectValues和setEvaluator,并且一定要先setObjectValues,再setEvaluator
animator.setObjectValues(startPointF, endPointF); animator.setEvaluator((TypeEvaluator<PointF>) (fraction, startValue, endValue) -> { //估值器
//只要能保证:当fraction=0时返回值为startValue,并且当fraction=1时返回值为endValue,就是一个比较合理的函数
PointF pointF = new PointF();
pointF.x = startValue.x + fraction * (endValue.x - startValue.x);// x方向匀速移动
pointF.y = startValue.y + fraction * fraction * (endValue.y - startValue.y);// y方向抛物线加速移动
return pointF;
}); animator.addUpdateListener(animation -> {
PointF pointf = (PointF) animation.getAnimatedValue();
iv_src.setX(pointf.x);
iv_src.setY(pointf.y);
addTrace(pointf, color);
});
animator.start();
} private void addTrace(PointF pointf, int color) {
View view = new View(this);
view.setBackgroundColor(color);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(2 * RADIUS_TRACE, 2 * RADIUS_TRACE);
layoutParams.leftMargin = (int) pointf.x + RADIUS_TRACE;
layoutParams.topMargin = (int) pointf.y + RADIUS_TRACE;
layout.addView(view, layoutParams);
}
}

使用 LayoutTransition 为布局容器中子View的显示与消失设置过渡动画

public class LayoutTransitionActivity extends ListActivity {

    private GridLayout gl_container;//父布局

    protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] array = {"点击添加一个View,点击添加的View删除此View"};
setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, array)); gl_container = new GridLayout(this);
gl_container.setColumnCount(4);
gl_container.setLayoutTransition(new LayoutTransition());//布局动画,当容器中的视图发生变化时存在过渡的动画效果
getListView().addFooterView(gl_container); addCheckBox(LayoutTransition.APPEARING, "APPEARING");//当一个View在VG中【出现】时设置的动画
addCheckBox(LayoutTransition.CHANGE_APPEARING, "CHANGE_APPEARING");
//当一个View在ViewGroup中【出现】时,对此View对其他View位置造成影响,对【其他View】设置的动画
addCheckBox(LayoutTransition.DISAPPEARING, "DISAPPEARING");//当一个View在VG中【消失】时设置的动画
addCheckBox(LayoutTransition.CHANGE_DISAPPEARING, "CHANGE_DISAPPEARING");
//当一个View在ViewGroup中【消失】时,对此View对其他View位置造成影响,对【其他View】设置的动画
addCheckBox(-1, "等价于是否设置xml中GridLayout的animateLayoutChanges属性为true");
} @Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Button button = new Button(this);
button.setText(gl_container.getChildCount() + 1 + "");
gl_container.addView(button, gl_container.getChildCount());//放置在最后那个位置
button.setOnClickListener(view -> gl_container.removeView(button));
} private void addCheckBox(int transitionType, String text) {
CheckBox checkBox = new CheckBox(this);
checkBox.setText(text);
checkBox.setChecked(true);
checkBox.setOnCheckedChangeListener((v, isChecked) -> {
LayoutTransition mTransition = new LayoutTransition(); //默认为全部开启状态,默认的动画效果都是可以更改的
if (transitionType == -1) mTransition = isChecked ? mTransition : null;
else mTransition.setAnimator(transitionType, isChecked ? mTransition.getAnimator(transitionType) : null);
gl_container.setLayoutTransition(mTransition);
});
getListView().addFooterView(checkBox);
}
}

使用 LayoutAnimationController 为布局容器中的控件播放同样的动画

public class LayoutAnimationControllerActivity extends ListActivity {
LinearLayout linearLayout; protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] array = {"点击添加HeaderView",
"点击添加的HeaderView",
"移除添加移除View时没任何动画效果",
"ListView不支持addView操作"//UnsupportedOperationException:addView(View) is not supported in AdapterView
};
setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, array));
getListView().setLayoutAnimation(getLayoutAnimationController());//android:layoutAnimation="@anim/layout_anim"
addFooterView();
} private void addFooterView() {
linearLayout = new LinearLayout(this);
linearLayout.setOrientation(LinearLayout.VERTICAL);
new Handler().postDelayed(() -> linearLayout.addView(getView(v -> linearLayout.removeView(v))), 500);
new Handler().postDelayed(() -> linearLayout.addView(getView(v -> linearLayout.removeView(v))), 1500);
new Handler().postDelayed(() -> linearLayout.addView(getView(v -> linearLayout.removeView(v))), 3500);
linearLayout.setLayoutAnimation(getLayoutAnimationController());
getListView().addHeaderView(linearLayout);
} private LayoutAnimationController getLayoutAnimationController() {
Animation animation = AnimationUtils.loadAnimation(this, android.R.anim.slide_in_left);//补间动画
LayoutAnimationController lac = new LayoutAnimationController(animation);//布局动画
lac.setOrder(LayoutAnimationController.ORDER_NORMAL);//显示顺序 normal=0 默认,reverse=1 倒序,random=2 随机
lac.setDelay(0.6f);//显示间隔时间,注意单位是秒,可以为70%,也可以是一个浮点数
return lac;
} @Override
protected void onListItemClick(ListView l, View v, int position, long id) {
int index = position - getListView().getHeaderViewsCount();
if (index == 0) {
getListView().addHeaderView((getView(view -> getListView().removeHeaderView(view))));
} else if (index == 1) {
linearLayout.addView(getView(view -> linearLayout.removeView(view)));
}
} private ImageView getView(View.OnClickListener listener) {
ImageView iv = new ImageView(this);
iv.setImageResource(R.drawable.ic_launcher);
iv.setOnClickListener(listener);
return iv;
}
}

几十种 Interpolator 演示

SecondActivity

public class SecondActivity extends ListActivity {
private final String[][] array = {INTERPOLATORS1, INTERPOLATORS2, INTERPOLATORS3, INTERPOLATORS4, INTERPOLATORS5, INTERPOLATORS6,}; protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏
requestWindowFeature(Window.FEATURE_NO_TITLE);//取消标题栏
String[] names = {"-1-", "-2-", "-3-", "-4-", "-5-", "-6-", //
"自定义TypeEvaluator实现抛物线动画效果", //
"使用LayoutTransition为布局容器中子View的显示与消失设置过渡动画", //
"使用LayoutAnimationController为布局容器中的控件播放同样的动画",};
setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, names));
} @Override
protected void onListItemClick(ListView l, View v, int position, long id) {
switch (position) {
case 6:
startActivity(new Intent(this, TypeEvaluatorActivity.class));
break;
case 7:
startActivity(new Intent(this, LayoutTransitionActivity.class));
break;
case 8:
startActivity(new Intent(this, LayoutAnimationControllerActivity.class));
break;
default:
Intent intent = new Intent(this, InterpolatorActivity.class);
intent.putExtra(InterpolatorActivity.EXTRA_NAME, array[position]);
startActivity(intent);
break;
}
} public static final String[] INTERPOLATORS1 = new String[]{"EaseBackInInterpolator", "EaseBackInOutInterpolator", "EaseBackOutInterpolator",
"EaseBounceInInterpolator", "EaseBounceInOutInterpolator", "EaseBounceOutInterpolator", "EaseBreathInterpolator", "EaseCircularInInterpolator",
"EaseCircularInOutInterpolator", "EaseCircularOutInterpolator",};
public static final String[] INTERPOLATORS2 = new String[]{"EaseCubicInInterpolator", "EaseCubicInOutInterpolator", "EaseCubicOutInterpolator",
"EaseExponentialInInterpolator", "EaseExponentialInOutInterpolator", "EaseExponentialOutInterpolator", "EaseInBackInterpolator",
"EaseInBounceInterpolator", "EaseInCircInterpolator", "EaseInCubicInterpolator",};
public static final String[] INTERPOLATORS3 = new String[]{"EaseInElasticInterpolator", "EaseInExpoInterpolator", "EaseInOutBackInterpolator",
"EaseInOutBounceInterpolator", "EaseInOutCircInterpolator", "EaseInOutCubicInterpolator", "EaseInOutElasticInterpolator",
"EaseInOutExpoInterpolator", "EaseInOutQuadInterpolator", "EaseInOutQuartInterpolator",};
public static final String[] INTERPOLATORS4 = new String[]{"EaseInOutQuintInterpolator", "EaseInOutSineInterpolator", "EaseInQuadInterpolator",
"EaseInQuartInterpolator", "EaseInQuintInterpolator", "EaseInSineInterpolator", "EaseOutBackInterpolator", "EaseOutBounceInterpolator",
"EaseOutCircInterpolator", "EaseOutCubicInterpolator",};
public static final String[] INTERPOLATORS5 = new String[]{"EaseOutElasticInterpolator", "EaseOutExpoInterpolator", "EaseOutQuadInterpolator",
"EaseOutQuartInterpolator", "EaseOutQuintInterpolator", "EaseOutSineInterpolator", "EaseQuadInInterpolator", "EaseQuadInOutInterpolator",
"EaseQuadOutInterpolator", "EaseQuartInInterpolator",};
public static final String[] INTERPOLATORS6 = new String[]{"EaseQuartInOutInterpolator", "EaseQuartOutInterpolator", "EaseQuintInInterpolator",
"EaseQuintInOutInterpolator", "EaseQuintOutInterpolator",};
}

InterpolatorActivityInterpolatorActivity

public class InterpolatorActivity extends ListActivity {
private ObjectAnimator mAnimator;
private static final String IN_PG_NAME = "com.bqt.anim.interpolator.";
public static final String EXTRA_NAME = "interpolators";
private String[] mInterpolators; protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏
mInterpolators = getIntent().getStringArrayExtra(EXTRA_NAME); //传过来的名字
setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, mInterpolators)); ImageView iv_src = new ImageView(this);
iv_src.setBackgroundColor(0x330000ff);
iv_src.setImageResource(R.drawable.icon);
getListView().addHeaderView(iv_src); DisplayMetrics metric = new DisplayMetrics();
((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(metric);
mAnimator = ObjectAnimator.ofFloat(iv_src, "y", 0, metric.heightPixels, 0).setDuration(1500);
} @Override
protected void onListItemClick(ListView l, View v, int position, long id) {
if (position == 0) recreate();
else anim(position - 1);
} private void anim(int position) {
String name = mInterpolators[position];
try {
Class<?> clazz = Class.forName(IN_PG_NAME + name);
TimeInterpolator interpolator = (TimeInterpolator) clazz.newInstance();
mAnimator.cancel();
mAnimator.setInterpolator(interpolator);
mAnimator.start();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}

2019-5-11

属性动画 补间动画 帧动画 基本使用案例 MD的更多相关文章

  1. js 动画补间 Tween

    1 /* RunningList (触发过程中可以安全的删除自己) 2 如果触发过程中删除(回调函数中删除正在遍历的数组), 不仅 len 没有变(遍历前定义的len没有变, 真实的len随之减少), ...

  2. android 帧动画,补间动画,属性动画的简单总结

      帧动画——FrameAnimation 将一系列图片有序播放,形成动画的效果.其本质是一个Drawable,是一系列图片的集合,本身可以当做一个图片一样使用 在Drawable文件夹下,创建ani ...

  3. Android动画-补间(Tween)动画

    Android动画的两种方式,其中帧动画上篇文章已经讲了,这次主要讲解的就是补间动画,补间动画就是动画业务场景中常用的旋转,平移,缩放,和渐变效果,帧动画是通过轮播动画实现动画效果,补间动画通过在两个 ...

  4. Android笔记(六十四) android中的动画——补间动画(tweened animation)

    补间动画就是只需要定义动画开始和结束的位置,动画中间的变化由系统去补齐. 补间动画由一下四种方式: 1.AplhaAnimation——透明度动画效果 2.ScaleAnimation ——缩放动画效 ...

  5. Android Animation 动画Demo(Frame帧动画)

    上一页介绍Animation动画第一:Tween吐温动画. 本文介绍了以下Animation也有动画的形式:Frame帧动画. Frame动画是一系列照片示出的顺序按照一定的处理,和机制,以放电影很阶 ...

  6. Android 动画 属性动画 视图动画 补间动画 帧动画 详解 使用

    Android动画 Property Animation res/animator/filename.xml In Java: R.animator.filename In XML: @[packag ...

  7. android104 帧动画,补间动画,属性动画

    ##帧动画FrameAnimation* 多张图片快速切换,形成动画效果* 帧动画使用xml定义 package com.itheima.frameanimation; import android. ...

  8. Android基础笔记(十)- 帧动画、补间动画具体解释、对话框

    帧动画 补间动画Tween Animation 对话框以及面试中的注意点 帧动画 帧动画非常easy,我们首先看一下Google官方解释This is a traditional animation ...

  9. Android中的帧动画与补间动画的使用

    前言 在日常开发中,我们有时候须要一些好看的动画效果,这时能够充分利用Android提供的这几种动画来实现. Android提供了3种类型的动画: 补间动画:补间动画能够应用于View,让你能够定义一 ...

随机推荐

  1. Linux中的文件

    一般情况下,每个存储设备或存储设备的分区(存储设备是硬盘.软盘.U盘 ..)被格式化为文件系统后,都会有两部份,一部份是iNode,另一部份是Block.Block是用来存储数据用的,而iNode就是 ...

  2. 05-树9 Huffman Codes (30 分)

    In 1953, David A. Huffman published his paper "A Method for the Construction of Minimum-Redunda ...

  3. JavaScript var、let、const

    var申明的变量是有作用域的 如果一个变量在函数体内部申明,则该变量的作用域为整个函数体,在函数体外不可引用该变量: 'use strict'; function foo() { var x = 1; ...

  4. Android Studio 本地化操作

    1.打开 string.xml 文件,在右上角,点 open-editor 2.点左上角的“地球”图标,就会弹出选择国家列表,输入zh会自动筛选,能很快选到中国简体中文 3.选择后,会在原来的列表中添 ...

  5. 冰多多团队-第一次Scrum例会

    冰多多团队-第一次Scrum会议 注:由于对课程要求的不熟悉,所以本文档为周会后的补充总结文档 会议基本情况 会议时间:3.28 19:00 - 19:30 会议地点:新主楼F座2楼沙发休息处 工作情 ...

  6. 动态查找之二叉树查找 c++实现

    算法思想 二叉搜索树(又称二叉查找树或二叉排序树)BST树 二叉查找树 二叉查找树,也称二叉搜索树,或二叉排序树.其定义也比较简单,要么是一颗空树,要么就是具有如下性质的二叉树: (1)若任意节点的左 ...

  7. DNA replication timing数据库 - Replication Domain

    DNA Replication Timing ReplicationDomain: a visualization tool and comparative database for genome-w ...

  8. kotlin基础 空值检查

    NULL检查机制 Kotlin的空安全设计对于声明可为空的参数,在使用时要进行空判断处理,有两种处理方式,字段后加!!像Java一样抛出空异常,另一种字段后加?可不做处理返回值为 null或配合?:做 ...

  9. x264 b_annexb格式和多slice

    实际应用环境:iOS,Android x264_param_t中有下面两个参数值得注意下int i_threads;        /* encode multiple frames in paral ...

  10. Vue ElementUI主页面搭建和导航栏使用,并在刷新页面的时候选中状态消失的问题解决

    <template> <div style="height:100%;width: 100%; padding:0 auto; margin: 0 auto;"& ...