自定义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

相关文章

Java实现自定义table宽高的示例代码

《Java实现自定义table宽高的示例代码》在桌面应用、管理系统乃至报表工具中,表格(JTable)作为最常用的数据展示组件,不仅承载对数据的增删改查,还需要配合布局与视觉需求,而JavaSwing... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

一文详解Java Stream的sorted自定义排序

《一文详解JavaStream的sorted自定义排序》Javastream中的sorted方法是用于对流中的元素进行排序的方法,它可以接受一个comparator参数,用于指定排序规则,sorte... 目录一、sorted 操作的基础原理二、自定义排序的实现方式1. Comparator 接口的 Lam

Spring如何使用注解@DependsOn控制Bean加载顺序

《Spring如何使用注解@DependsOn控制Bean加载顺序》:本文主要介绍Spring如何使用注解@DependsOn控制Bean加载顺序,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录1.javascript 前言2. 代码实现总结1. 前言默认情况下,Spring加载Bean的顺

如何自定义一个log适配器starter

《如何自定义一个log适配器starter》:本文主要介绍如何自定义一个log适配器starter的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录需求Starter 项目目录结构pom.XML 配置LogInitializer实现MDCInterceptor

springboot加载不到nacos配置中心的配置问题处理

《springboot加载不到nacos配置中心的配置问题处理》:本文主要介绍springboot加载不到nacos配置中心的配置问题处理,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录springboot加载不到nacos配置中心的配置两种可能Spring Boot 版本Nacos

Druid连接池实现自定义数据库密码加解密功能

《Druid连接池实现自定义数据库密码加解密功能》在现代应用开发中,数据安全是至关重要的,本文将介绍如何在​​Druid​​连接池中实现自定义的数据库密码加解密功能,有需要的小伙伴可以参考一下... 目录1. 环境准备2. 密码加密算法的选择3. 自定义 ​​DruidDataSource​​ 的密码解密3

spring-gateway filters添加自定义过滤器实现流程分析(可插拔)

《spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔)》:本文主要介绍spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔),本文通过实例图... 目录需求背景需求拆解设计流程及作用域逻辑处理代码逻辑需求背景公司要求,通过公司网络代理访问的请求需要做请

使用Python获取JS加载的数据的多种实现方法

《使用Python获取JS加载的数据的多种实现方法》在当今的互联网时代,网页数据的动态加载已经成为一种常见的技术手段,许多现代网站通过JavaScript(JS)动态加载内容,这使得传统的静态网页爬取... 目录引言一、动态 网页与js加载数据的原理二、python爬取JS加载数据的方法(一)分析网络请求1

Kotlin Compose Button 实现长按监听并实现动画效果(完整代码)

《KotlinComposeButton实现长按监听并实现动画效果(完整代码)》想要实现长按按钮开始录音,松开发送的功能,因此为了实现这些功能就需要自己写一个Button来解决问题,下面小编给大... 目录Button 实现原理1. Surface 的作用(关键)2. InteractionSource3.

IDEA下"File is read-only"可能原因分析及"找不到或无法加载主类"的问题

《IDEA下Fileisread-only可能原因分析及找不到或无法加载主类的问题》:本文主要介绍IDEA下Fileisread-only可能原因分析及找不到或无法加载主类的问题,具有很好的参... 目录1.File is read-only”可能原因2.“找不到或无法加载主类”问题的解决总结1.File