自定义view-视察动画之雅虎新闻摘要加载

2024-02-16 20:50

本文主要是介绍自定义view-视察动画之雅虎新闻摘要加载,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这里写图片描述

首先布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"><include layout="@layout/fragment_page_first"/><com.hbwj.a20_.LoadingView
        android:id="@+id/thirdScreenView"android:layout_width="match_parent"android:layout_height="match_parent"tools:layout_editor_absoluteY="8dp"tools:layout_editor_absoluteX="8dp" /></RelativeLayout>

fragment_page_first布局和上一篇文章内容一样

LoadingView:自定义加载view

public class LoadingView extends View {// 旋转动画执行的时间private final long ROTATION_ANIMATION_TIME = 1400;private boolean mInitParams;private float mRotationRadius;//绕着旋转的动画的半径private float mCircleRadius;//小圆的半径private float mCurrentRotationAngle;// 小圆的颜色列表private int[] mCircleColors;//整体颜色背景private int mSplashColor = Color.WHITE;// 代表当前状态所画动画private LoadingState mLoadingState;//画笔private Paint mPaint;private int cententX, cententY;private float mCurrentRotationRadius;//当前半径// 空心圆初始半径private float mHoleRadius = 0F;// 屏幕对角线的一半private float mDiagonalDist;public LoadingView(Context context) {this(context, null);}public LoadingView(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public LoadingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mCircleColors = context.getResources().getIntArray(R.array.splash_circle_colors);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);if (!mInitParams) {initParams();}if (mLoadingState == null) {mLoadingState = new RotationState();}mLoadingState.drawable(canvas);}//初始化参数private void initParams() {mRotationRadius = getMeasuredWidth() / 4;// 每个小圆的半径 = 大圆半径的 1/8mCircleRadius = mRotationRadius / 8;mInitParams = true;mPaint = new Paint();mPaint.setAntiAlias(true);mPaint.setDither(true);cententX = getWidth() / 2;cententY = getHeight() / 2;mDiagonalDist= (float) Math.sqrt(cententX*cententX+cententY*cententY);}/*** 消失:给外部调用*/public void disappear() {//开始聚合动画//关闭动画if (mLoadingState instanceof RotationState) {RotationState rotationState = (RotationState) mLoadingState;rotationState.cancel();}mLoadingState = new MergeState();}public abstract class LoadingState {public abstract void drawable(Canvas canvas);}/*** 展开动画*/public class ExpendState extends LoadingState {ValueAnimator mAnimator;public ExpendState() {if (mAnimator == null) {mAnimator=ObjectAnimator.ofFloat(0,mDiagonalDist);//从0到圆的对角线的一半mAnimator.setDuration(ROTATION_ANIMATION_TIME);mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {mHoleRadius= (float) animation.getAnimatedValue();invalidate();}});mAnimator.start();}}@Overridepublic void drawable(Canvas canvas) {//画笔的宽度float strokeWidth=mDiagonalDist-mHoleRadius;
//            float strokeWidth=mDiagonalDist;mPaint.setStrokeWidth(strokeWidth );mPaint.setColor(mSplashColor);mPaint.setStyle(Paint.Style.STROKE);
//            float radius=strokeWidth/2;//向内float radius=strokeWidth/2+mHoleRadius;canvas.drawCircle(cententX,cententY,radius, mPaint);}}/*** 聚合动画*/public class MergeState extends LoadingState {ValueAnimator mAnimator;public MergeState() {if (mAnimator == null) {//从外圆的半径到中心位置mAnimator = ObjectAnimator.ofFloat(mRotationRadius, 0);mAnimator.setDuration(ROTATION_ANIMATION_TIME / 2);mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {mCurrentRotationRadius = (float) animation.getAnimatedValue();invalidate();}});// 开始的时候向后然后向前甩mAnimator.setInterpolator(new AnticipateInterpolator(5f));mAnimator.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {mLoadingState = new ExpendState();}});//不断重复使用//mAnimator.setRepeatCount(-1);mAnimator.start();}}@Overridepublic void drawable(Canvas canvas) {//绘制白色背景canvas.drawColor(mSplashColor);//画6个圆//没份的角度double precentAngle = 2 * Math.PI / mCircleColors.length;for (int i = 0; i < mCircleColors.length; i++) {mPaint.setColor(mCircleColors[i]);//当前的角度=初始化的角度+旋转的角度double currentAngle = precentAngle * i + mCurrentRotationAngle;float cx = (float) (cententX + mCurrentRotationRadius * Math.cos(currentAngle));float cy = (float) (cententY + mCurrentRotationRadius * Math.sin(currentAngle));canvas.drawCircle(cx, cy, mCircleRadius, mPaint);}}}/*** 旋转动画*/public class RotationState extends LoadingState {ValueAnimator mAnimator;public RotationState() {if (mAnimator == null) {//0-360度mAnimator = ObjectAnimator.ofFloat(0, 2 * (float) Math.PI);mAnimator.setDuration(ROTATION_ANIMATION_TIME);mAnimator.setInterpolator(new LinearInterpolator());mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {mCurrentRotationAngle = (float) animation.getAnimatedValue();invalidate();}});//不断重复使用mAnimator.setRepeatCount(-1);mAnimator.start();}}@Overridepublic void drawable(Canvas canvas) {//绘制白色背景canvas.drawColor(mSplashColor);//画6个圆//没份的角度double precentAngle = 2 * Math.PI / mCircleColors.length;for (int i = 0; i < mCircleColors.length; i++) {mPaint.setColor(mCircleColors[i]);//当前的角度=初始化的角度+旋转的角度double currentAngle = precentAngle * i + mCurrentRotationAngle;float cx = (float) (cententX + mRotationRadius * Math.cos(currentAngle));float cy = (float) (cententY + mRotationRadius * Math.sin(currentAngle));canvas.drawCircle(cx, cy, mCircleRadius, mPaint);}}public void cancel() {mAnimator.cancel();}}
}

MainActivity中使用

  final LoadingView loadingView = (LoadingView) findViewById(R.id.thirdScreenView);new Handler().postDelayed(new Runnable() {@Overridepublic void run() {loadingView.disappear();}},2000);

这篇关于自定义view-视察动画之雅虎新闻摘要加载的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/715673

相关文章

如何自定义Nginx JSON日志格式配置

《如何自定义NginxJSON日志格式配置》Nginx作为最流行的Web服务器之一,其灵活的日志配置能力允许我们根据需求定制日志格式,本文将详细介绍如何配置Nginx以JSON格式记录访问日志,这种... 目录前言为什么选择jsON格式日志?配置步骤详解1. 安装Nginx服务2. 自定义JSON日志格式各

Android自定义Scrollbar的两种实现方式

《Android自定义Scrollbar的两种实现方式》本文介绍两种实现自定义滚动条的方法,分别通过ItemDecoration方案和独立View方案实现滚动条定制化,文章通过代码示例讲解的非常详细,... 目录方案一:ItemDecoration实现(推荐用于RecyclerView)实现原理完整代码实现

SpringBoot项目启动报错"找不到或无法加载主类"的解决方法

《SpringBoot项目启动报错找不到或无法加载主类的解决方法》在使用IntelliJIDEA开发基于SpringBoot框架的Java程序时,可能会出现找不到或无法加载主类com.example.... 目录一、问题描述二、排查过程三、解决方案一、问题描述在使用 IntelliJ IDEA 开发基于

基于Spring实现自定义错误信息返回详解

《基于Spring实现自定义错误信息返回详解》这篇文章主要为大家详细介绍了如何基于Spring实现自定义错误信息返回效果,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录背景目标实现产出背景Spring 提供了 @RestConChina编程trollerAdvice 用来实现 HTT

SpringSecurity 认证、注销、权限控制功能(注销、记住密码、自定义登入页)

《SpringSecurity认证、注销、权限控制功能(注销、记住密码、自定义登入页)》SpringSecurity是一个强大的Java框架,用于保护应用程序的安全性,它提供了一套全面的安全解决方案... 目录简介认识Spring Security“认证”(Authentication)“授权” (Auth

Android WebView无法加载H5页面的常见问题和解决方法

《AndroidWebView无法加载H5页面的常见问题和解决方法》AndroidWebView是一种视图组件,使得Android应用能够显示网页内容,它基于Chromium,具备现代浏览器的许多功... 目录1. WebView 简介2. 常见问题3. 网络权限设置4. 启用 JavaScript5. D

SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法

《SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法》本文主要介绍了SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法,具有一定的参考价值,感兴趣的可以了解一下... 目录方法1:更改IDE配置方法2:在Eclipse中清理项目方法3:使用Maven命令行在开发Sprin

SpringBoot自定义注解如何解决公共字段填充问题

《SpringBoot自定义注解如何解决公共字段填充问题》本文介绍了在系统开发中,如何使用AOP切面编程实现公共字段自动填充的功能,从而简化代码,通过自定义注解和切面类,可以统一处理创建时间和修改时间... 目录1.1 问题分析1.2 实现思路1.3 代码开发1.3.1 步骤一1.3.2 步骤二1.3.3

dubbo3 filter(过滤器)如何自定义过滤器

《dubbo3filter(过滤器)如何自定义过滤器》dubbo3filter(过滤器)类似于javaweb中的filter和springmvc中的intercaptor,用于在请求发送前或到达前进... 目录dubbo3 filter(过滤器)简介dubbo 过滤器运行时机自定义 filter第一种 @A

spring-boot-starter-thymeleaf加载外部html文件方式

《spring-boot-starter-thymeleaf加载外部html文件方式》本文介绍了在SpringMVC中使用Thymeleaf模板引擎加载外部HTML文件的方法,以及在SpringBoo... 目录1.Thymeleaf介绍2.springboot使用thymeleaf2.1.引入spring