又到了动画总结的时间了,今天要总结的是一个对话框形式的动画效果,老样子gif图不太清晰,但是总体的效果是可以看的清楚的,一个动态的等待对话框,我只是简单的实现了一些动画,如果需要更复杂的需求,可以联系我更改,联系方式在文章的底部,欢迎骚扰,接下来看动态效果图:
效果的总体实现就如上图所示,这里展示了一组动画效果,首先这里我解释一下我做的思路:1.总体应该是建立在对话框的基础上,然后针对对话框进行自定义的布局,接下来就是对布局文件的操作,上半部分为四个圆球,开始动画前四个小球是重叠在一起的,然后下半部分是一个静态的文字描述,最后就是点击形成对话框展示了,一个很容易的分析效果,接下来就来说一下编写的具体流程了:
1.一个圆形小球文件的编写,这里如果有美工帮助的情况下,可以摆脱他帮忙做四个图片,但是本着万事不求人的态度,同样可以利用代码去编写四个颜色小球的文件,这里就需要用到shape了,shape的具体用法我在之后也会去整理一下的,那么现在先看一下小球的代码
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid
android:width="1dp"
android:color="@android:color/holo_red_light"
android:dashGap="0dp"
android:dashWidth="5dp" />
</shape>
注:这里是做了一个红色的小球,那么你需要其他颜色的小球,只需要更改color这个属性就可以了。
2.对话框的创建,这里我还是用的系统的对话框,只不过在这里我对属性做了一些变更,首先看下代码的实现
LayoutInflater inflater = LayoutInflater.from(context);
// 得到加载view
View v = inflater.inflate(R.layout.dialog_loading, null);
// 加载布局
LinearLayout layout = v.findViewById(R.id.dialog_loading_view);
//黑色圆球
ivBlack = v.findViewById(R.id.iv_black);
//红色圆球
ivRed = v.findViewById(R.id.iv_red);
//绿色圆球
ivGreen = v.findViewById(R.id.iv_green);
//蓝色圆球
ivBlue = v.findViewById(R.id.iv_blue);
// 提示文字
tipTextView = (TextView) v.findViewById(R.id.tipTextView);
// 设置加载文字信息
tipTextView.setText(msg);
// 创建自定义样式dialog
Dialog loadingDialog = new Dialog(context, R.style.MyDialogStyle);
// 是否可以按“返回键”消失
loadingDialog.setCancelable(true);
// 点击加载框以外的区域
loadingDialog.setCanceledOnTouchOutside(false);
// 设置布局
loadingDialog.setContentView(layout, new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT));
//将显示Dialog的方法封装在这里面
Window window = loadingDialog.getWindow();
WindowManager.LayoutParams lp = window.getAttributes();
///设置窗口宽度
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
//设置窗口高度
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
//居中显示
window.setGravity(Gravity.CENTER);
window.setAttributes(lp);
//设置动画效果
window.setWindowAnimations(R.style.PopWindowAnimStyle);
//展示对话框
loadingDialog.show();
注:这段的代码详细作用我已经写下来了,每一行的作用,总体就是创建一个对话框,并且设置对话框的样式和对话框的高度信息等内容,其中R.styleable.MyDialogStyle是设置对话框的一些属性内容,R.style.PopWindowAnimStyle是设置对话框的进出动画,这部分的代码我就不详细表述了,因为这不涉及到我这里所要总结的内容。
3.接下来这步是本节的重点内容,如何将对话框的小球动起来,这里我总共做了两种动画,平移动画和透明度动画,平移动画是针对三个往外移动的小球,一个透明动画则是针对中间绿色小球的显示和隐藏设置,具体动画代码为下方所示:
//开始动画
private void startAnimation() {
int length = 120;
//计算出每个动画的坐标位置
double degree = Math.toRadians(60);
float blueWidth = (float) (-length * Math.sin(degree));
float blueHeight = (float) (-length * Math.cos(degree));
float redWidth = (float) (length * Math.sin(degree));
float redHeight = (float) (-length * Math.cos(degree));
float blackWidth = 0;
float blackHeight = length;
//开始制作动画
ObjectAnimator animator = ObjectAnimator.ofFloat(ivBlue, "translationX", 0, blueWidth);
//执行的时长
animator.setDuration(2000);
//动画重复播放
animator.setRepeatCount(ValueAnimator.INFINITE);
//倒放动画
animator.setRepeatMode(ValueAnimator.REVERSE);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(ivBlue, "translationY", 0, blueHeight);
animator2.setDuration(2000);
animator2.setRepeatCount(ValueAnimator.INFINITE);
animator2.setRepeatMode(ValueAnimator.REVERSE);
ObjectAnimator animator3 = ObjectAnimator.ofFloat(ivBlack, "translationX", 0, blackWidth);
animator3.setDuration(2000);
animator3.setRepeatCount(ValueAnimator.INFINITE);
animator3.setRepeatMode(ValueAnimator.REVERSE);
ObjectAnimator animator4 = ObjectAnimator.ofFloat(ivBlack, "translationY", 0, blackHeight);
animator4.setDuration(2000);
animator4.setRepeatCount(ValueAnimator.INFINITE);
animator4.setRepeatMode(ValueAnimator.REVERSE);
ObjectAnimator animator5 = ObjectAnimator.ofFloat(ivRed, "translationX", 0, redWidth);
animator5.setDuration(2000);
animator5.setRepeatCount(ValueAnimator.INFINITE);
animator5.setRepeatMode(ValueAnimator.REVERSE);
ObjectAnimator animator6 = ObjectAnimator.ofFloat(ivRed, "translationY", 0, redHeight);
animator6.setDuration(2000);
animator6.setRepeatCount(ValueAnimator.INFINITE);
animator6.setRepeatMode(ValueAnimator.REVERSE);
//透明动画
ObjectAnimator animator7 = ObjectAnimator.ofFloat(ivGreen, "alpha", 1, 0);
animator7.setDuration(2000);
animator7.setRepeatCount(ValueAnimator.INFINITE);
animator7.setRepeatMode(ValueAnimator.REVERSE);
AnimatorSet set = new AnimatorSet();
AnimatorSet.Builder builder = set.play(animator);
builder.with(animator2).with(animator3).with(animator4).with(animator5)
.with(animator6).with(animator7);
set.start();
//针对第一个动画的监听,当重复时变换小球的颜色,形成小球变更的效果
animator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
//因为动画会倒放一边,同样会调用该方法,所以设置一个标记,当是两次调用时,才变
//小球的颜色
flag = !flag;
if (flag) {
return;
}
count++;
switch (count % 3) {
case 0:
ivBlack.setImageResource(R.drawable.shape_black_circle);
ivBlue.setImageResource(R.drawable.shape_blue_circle);
ivRed.setImageResource(R.drawable.shape_red_circle);
Log.e("结果,", "0");
break;
case 1:
Log.e("结果,", "1");
ivBlack.setImageResource(R.drawable.shape_red_circle);
ivBlue.setImageResource(R.drawable.shape_black_circle);
ivRed.setImageResource(R.drawable.shape_blue_circle);
break;
case 2:
Log.e("结果,", "2");
ivBlack.setImageResource(R.drawable.shape_blue_circle);
ivBlue.setImageResource(R.drawable.shape_red_circle);
ivRed.setImageResource(R.drawable.shape_black_circle);
break;
}
}
});
}
注:这里的动画总共包含7个,3个小球的平移动画,一个中心小球的隐藏出现动画,因为这里我用的是属性动画,所以显得代码比较冗长,同样可以使用视图动画实现,条条大路通罗马,因此这里可以使用多种方式,然后我通过builder将动画关联在一起,同时监听第一个动画的状态,当动画重复执行时,则针对动画去变更小球的颜色属性,达到改变小球的效果(这里特别提一下的是:因为这里调用了ValueAnimator.REVERCE,所以一次动画效果,会执行两次Repeat方法,所以我们要屏蔽掉一次改变小球的动画,这里我是用一个boolean类型的变量,每次调用变更一下boolean值的属性,只有在为真的情况下才会改变小球的颜色。)
这里整个控件就完成了,具体代码我就不展示了,毕竟还在学习中,只是做个简单的整理笔记,如果想要代码的可以联系我:微信:a18756901908,欢迎共同进步。