Android(安卓)仿58同城进度条加载内容动画效果的实现
16lz
2021-01-24
前言
由于工作需要,有个需求要求做成58同城类似的进度条加载动画效果,这就需要自定义View ,然后用到 ObjectAnimator 属性动画
1.自定义View
import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Path;import android.support.v4.content.ContextCompat;import android.util.AttributeSet;import android.view.View;public class ShapeView extends View { //初始形状 public Shape mCurrentShape = Shape.CIRCLE; private Paint mPaint; private Path mPath; public enum Shape { CIRCLE, RECTANGLE, TRIANGLE, } public ShapeView(Context context) { this(context, null); } public ShapeView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public ShapeView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mPath = new Path(); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.FILL); } public Shape getCurrentShape() { return mCurrentShape; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //指定View的宽高 int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); setMeasuredDimension(width > height ? height : width, width > height ? height : width); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int center = getWidth() / 2; switch (mCurrentShape) { case CIRCLE: //画圆 mPaint.setColor(ContextCompat.getColor(getContext(), android.R.color.holo_blue_dark)); canvas.drawCircle(center, center, center, mPaint); break; case RECTANGLE: //画正方形 mPaint.setColor(ContextCompat.getColor(getContext(), android.R.color.holo_red_dark)); canvas.drawRect(0, 0, getRight(), getBottom(), mPaint); break; case TRIANGLE: //用Path画三角形 mPaint.setColor(ContextCompat.getColor(getContext(), android.R.color.holo_green_dark)); //指定path的起点 mPath.moveTo(getWidth() / 2, 0); mPath.lineTo(0, (float) (getWidth() / 2 * Math.sqrt(3))); mPath.lineTo(getWidth(), (float) (getWidth() / 2 * Math.sqrt(3))); canvas.drawPath(mPath, mPaint); break; } } /** * 轮询改变当前View绘制的形状 */ public void changeShape() { switch (mCurrentShape) { case CIRCLE: mCurrentShape = Shape.RECTANGLE; break; case RECTANGLE: mCurrentShape = Shape.TRIANGLE; break; case TRIANGLE: mCurrentShape = Shape.CIRCLE; break; } invalidate(); }}
2.布局文件 layout_loading_view.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical"> <com.xinrui.headsettest.view.ShapeView android:id="@+id/shapeview" android:layout_width="30dp" android:layout_height="30dp" android:layout_marginBottom="90dp" /> <View android:id="@+id/shadowview" android:layout_width="33dp" android:layout_height="6dp" android:background="@drawable/loading_shadow" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="正在加载中,请稍候..." /></LinearLayout>
3.项目中运用
import android.animation.Animator;import android.animation.AnimatorListenerAdapter;import android.animation.AnimatorSet;import android.animation.ObjectAnimator;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.animation.AccelerateInterpolator;import android.view.animation.DecelerateInterpolator;import com.xinrui.headsettest.view.ShapeView;public class LoadingViewActivity extends Activity { private ShapeView mShapeView; private View mShadowView; boolean isStopAnimation = false; float mTranslateDistance =80.0f; long mAnimateTime = 500; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.layout_loading_view); initLayout(); } /** *加载布局,初始化控件 */ private void initLayout() { mShapeView = findViewById(R.id.shapeview); mShadowView = findViewById(R.id.shadowview); //开启动画 mShadowView.post(new Runnable() { @Override public void run() { startDropAnimation(); } }); } /** * 定义 下落动画 和 阴影缩小动画 */ private void startDropAnimation() { if (isStopAnimation) { return; } //下落的动画 ObjectAnimator mTranslateAnimation = ObjectAnimator.ofFloat(mShapeView, "translationY", 0, mTranslateDistance); mTranslateAnimation.setInterpolator(new AccelerateInterpolator()); //阴影缩小动画 ObjectAnimator mScaleAnimation = ObjectAnimator.ofFloat(mShadowView, "scaleX", 1f, 0.4f); AnimatorSet mAnimatorSet = new AnimatorSet(); mAnimatorSet.playTogether(mTranslateAnimation, mScaleAnimation); mAnimatorSet.setDuration(mAnimateTime); mAnimatorSet.setInterpolator(new AccelerateInterpolator()); mAnimatorSet.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); mShapeView.changeShape(); startUpAnimation(); } }); mAnimatorSet.start(); } /** * 定义 弹起动画 和 阴影放大动画 */ private void startUpAnimation() { if (isStopAnimation) { return; } //弹起的动画 ObjectAnimator mTranslateAnimation = ObjectAnimator.ofFloat(mShapeView, "translationY", mTranslateDistance, 0); //阴影放大的动画 ObjectAnimator mScaleAnimation = ObjectAnimator.ofFloat(mShadowView, "scaleX", 0.4f, 1f); AnimatorSet mAnimatorSet = new AnimatorSet(); mAnimatorSet.playTogether(mTranslateAnimation, mScaleAnimation); mAnimatorSet.setDuration(mAnimateTime); mAnimatorSet.setInterpolator(new DecelerateInterpolator()); mAnimatorSet.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { super.onAnimationStart(animation); //弹起时旋转 startRotateAnimation(); } @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); startDropAnimation(); } }); mAnimatorSet.start(); } //旋转动画 private void startRotateAnimation() { if (isStopAnimation) { return; } ObjectAnimator mRotateAnimation = null; switch (mShapeView.getCurrentShape()) { case CIRCLE: case RECTANGLE: mRotateAnimation = ObjectAnimator.ofFloat(mShapeView, "rotation", 0, 180); break; case TRIANGLE: mRotateAnimation = ObjectAnimator.ofFloat(mShapeView, "rotation", 0, -120); break; } mRotateAnimation.setDuration(mAnimateTime); mRotateAnimation.start(); }}
更多相关文章
- Android(安卓)Transition(Android过渡动画)
- Android(安卓)动画之TranslateAnimation应用详解
- Android(安卓)开源组件和第三方库汇总
- Android(安卓)椭圆轨迹动画
- Android属性动画源代码解析(超详细)
- ViewPager的切换动画
- Android(安卓)动画资源
- android 布局边框阴影1dp
- Android(安卓)使用动画效果后的控件位置处理 类似系统通知栏下拉