重学 Android 自定义 View 系列(七):仿58同城加载动画

Android实现仿58同城进度条加载内容动画效果 设置动画的目标对象为进度条,并设置初始值为0,最终值为100。在这篇文章中,我们将介绍如何实现一个类似于58同城应用中的进度条加载内容动画效果。通过这个效果,用户可以清楚地看到页面内容的加载进度,并获得更好的用户体验。通过这个实现,我们可以在Android应用中添加一个类似于58同城的进度条加载效果,提升用户体验。这样,当应用启动时,进度条就会自动从0开始逐渐增加到100的进度,给用户展示内容加载的进度。这段代码创建了一个水平方向的进度条,最大值为100,初始进度为0。如果你有任何问题,请随时提问。 阅读详情

前言

本文将实现早期58同城一个带有弹跳效果的加载动画,且结合图形变换(圆形变正方形、正方形变三角形等)实现一种动态、富有表现力的加载效果。

最终效果如下:
在这里插入图片描述

1. 效果分析


  • 形状切换: 显示一个不断变化的形状,例如圆形、正方形、三角形之间的变换。
  • 弹跳效果: 加载图标会有上下弹跳的动画,增加动感。
  • 阴影效果: 动画中随着形状变化,添加一个阴影效果,随着形状变化而收缩或放大。

效果展示:

  1. 初始状态: 显示一个圆形图标,伴随初始弹跳。
  2. 动画过程: 随着动画的进行,圆形变为正方形,再变为三角形,每次形状变换后都会触发一次上下弹跳。
  3. 动画结束: 当动画完成时,图标将继续上下弹跳,直至用户操作或停止。

2. 结构分析


由上面GIF图可知,加载动画组合布局分为 上 中 下 三部分:分别是上面一个ShapeView 负责切换不同形状,中间一个View 用于模拟阴影效果,底部是加载文字,至于所有动效全部由各种动画实现。

为了方便控制上中下三部分内容,需要自定义一个LoadingView,用于包含这三部分View,其内部实现各个View的动画效果。

3. 技术实现


3.1 ShapeView

用于绘制三种图形:圆形、矩形、三角形。且具有形状切换功能,比如 先绘制圆形,圆形展示完绘制矩形,矩形展示完绘制三角形,三角形展示完再绘制圆,首尾相连。

首先我们要确保ShapeView 是个正方形,才能保证绘制出的三种图形都比较规则。

   protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        //确保是正方形
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);

        int size = Math.min(width, height);

        setMeasuredDimension(size, size);
    }

接着,要定义三种图形的枚举类,方便切换使用:

    public void exchangeShape(){
        switch (currentShapeType){
            case CIRCLE:
                currentShapeType = ShapeType.SQUARE;
                break;
            case SQUARE:
                currentShapeType = ShapeType.TRIANGLE;
                break;
            case TRIANGLE:
                currentShapeType = ShapeType.CIRCLE;
                break;
        }
        invalidate();
    }

    public ShapeType getCurrentShapeType() {
        return currentShapeType;
    }

    public enum ShapeType{
        CIRCLE, //圆形
        SQUARE, //正方形
        TRIANGLE //三角形
    }

然后,在onDraw中绘制三种图形,其中圆和矩形最简单,有现成的方法canvas.drawCircle 和 canvas.drawRect在此不做介绍了,三角形需要介绍一下,因为三角形要使用Path进行绘制,且为了美观要绘制一个等边三角形:
在这里插入图片描述
要绘制三角形,我们首先要知道三角形的三个顶点的坐标,才能进行绘制,由于ShapeView我们已经保证是正方形了,所以顶点坐标就是(getWidth() / 2,0),左边顶点坐标不能是(0,getHeight()) 因为这样绘制的三角形就是等边三角形了,影响美观,而要实现等边三角形的话就要重新计算Y轴坐标,由上面草图可知,大三角形分成开两个小三角形,我们知道底边和斜边是1/2的关系,由三角定理可知,一份二份根号三份,所以长的直角边就是根号三的getWidth(),此时我们就拿到了三个顶点坐标了。

  if (mPath == null) {
                    mPath = new Path();
                    mPath.moveTo(getWidth() / 2,0);
                    mPath.lineTo((float) 0, (float) ((getHeight() / 2) * Math.sqrt(3)));
                    mPath.lineTo(getWidth(),(float) ((getHeight() / 2) * Math.sqrt(3)));
                    mPath.close();
                }
                canvas.drawPath(mPath,mPaint);

Path相关函数介绍:

moveTo(float x, float y):此方法将“画笔”移动到指定的坐标 (x, y),但是不绘制任何东西。它通常用于开始绘制路径时指定初始位置。
lineTo(float x, float y):此方法从当前路径点绘制一条直线到指定的 (x, y) 坐标。
close():此方法会连接路径的最后一个点和第一个点,形成一个封闭的路径。对于一个三角形,调用 close() 会把最后一个点与起始点连接起来,闭合三角形。

3.2 阴影效果

一个简单的椭圆背景,后期对其进行缩放实现动效。

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="#FF000000"/>
</shape>

3.3 LoadingView(组合)

LoadingView 继承自 LinearLayout,因为我们要把三部分View都放进该布局中,在layout中 写出三部分组合的xml文件:layout_loading_view

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:background="@color/white"
    android:orientation="vertical">

    <com.xaye.diyview.view.ShapeView
        android:id="@+id/shape_view"
        android:layout_width="25dp"
        android:layout_height="25dp"
        android:layout_marginBottom="82dp"/>

    <View
        android:id="@+id/shadow_view"
        android:layout_width="25dp"
        android:layout_height="3dp"
        android:background="@drawable/shadow_bg"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:text="玩命加载中..."/>

</LinearLayout>

将布局添加进LoadingView:

   private void initLayout() {
        // 添加到该View
        inflate(getContext(), R.layout.layout_loading_view, this);

        mShapeView = findViewById(R.id.shape_view);
        mShadowView = findViewById(R.id.shadow_view);

        startFalling();
    }

此处的关键技术点是inflate,现在你可能不明白其原理,但只需要记住用它就可以把布局添加进来就行了,后面再慢慢分析其原理。

这样我们就可以在LoadingView去管理ShapeView 和 ShadowView了,接下来就是加上各种动画效果:

下落动画:

    private void startFalling() {
        // 下落位移动画
        ObjectAnimator animator = ObjectAnimator.ofFloat(mShapeView, "translationY", 0, mTranslationY);
        animator.setDuration(ANIMATOR_DURATION);

        //配合中间阴影缩小
        ObjectAnimator scaleAnimator = ObjectAnimator.ofFloat(mShadowView, "scaleX", 1, 0.3f);
        scaleAnimator.setDuration(ANIMATOR_DURATION);

        // 动画集合
        AnimatorSet animatorSet = new AnimatorSet();
        // 加速
        animatorSet.setInterpolator(new AccelerateInterpolator());
        animatorSet.playTogether(animator, scaleAnimator);
        animatorSet.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                // 改变形状
                mShapeView.exchangeShape();
                // 下落完动画,开始上升动画
                startRising();
            }
        });

        // 如果已有动画在执行,取消之前的动画
        if (mCurrentAnimatorSet != null && mCurrentAnimatorSet.isRunning()) {
            mCurrentAnimatorSet.cancel();
        }
        mCurrentAnimatorSet = animatorSet;
        animatorSet.start();
    }

上升动画:

private void startRising() {
        ObjectAnimator animator = ObjectAnimator.ofFloat(mShapeView, "translationY", mTranslationY, 0);
        animator.setDuration(ANIMATOR_DURATION);

        ObjectAnimator scaleAnimator = ObjectAnimator.ofFloat(mShadowView, "scaleX", 0.3f, 1);
        scaleAnimator.setDuration(ANIMATOR_DURATION);

        AnimatorSet animatorSet = new AnimatorSet();
        // 减速
        animatorSet.setInterpolator(new DecelerateInterpolator());
        animatorSet.playTogether(animator, scaleAnimator);
        animatorSet.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                startFalling();
            }

            @Override
            public void onAnimationStart(Animator animation) {
                //开始旋转
                startRotationAnimator();
            }
        });

        // 如果已有动画在执行,取消之前的动画
        if (mCurrentAnimatorSet != null && mCurrentAnimatorSet.isRunning()) {
            mCurrentAnimatorSet.cancel();
        }

        mCurrentAnimatorSet = animatorSet;
        animatorSet.start();
    }

旋转动画:

    private void startRotationAnimator() {
        ObjectAnimator rotationAnimator = null;
        switch (mShapeView.getCurrentShapeType()) {
            case CIRCLE:
            case SQUARE:
                rotationAnimator = ObjectAnimator.ofFloat(mShapeView, "rotation", 0, 180);
                break;
            case TRIANGLE:
                rotationAnimator = ObjectAnimator.ofFloat(mShapeView, "rotation", 0, -60);
                break;
        }
        rotationAnimator.setDuration(ANIMATOR_DURATION);
        rotationAnimator.setInterpolator(new DecelerateInterpolator());
        rotationAnimator.start();
    }

动画分析:
上升和下落是个逆过程,主要差异点是差值器不同,为了显得更真实,上升过程使用了减速差值器DecelerateInterpolator 下落过程使用了加速差值器AccelerateInterpolator。

其中AnimatorSet 可以将多个动画组合在一起,同时执行。使用 playTogether() 方法,将多个动画传入并同时启动。这在需要同步进行的动画场景中非常有用。

补充:除了同步执行,AnimatorSet 还支持将多个动画按顺序执行,使用 playSequentially() 方法。在这种模式下,前一个动画结束后,下一个动画才会开始。

动画通过控制 ShapeView 的 translationY 属性实现,上升 和 下落动画,通过控制 ShadowView 的 scaleX 控制 X轴 的缩放效果。

接着是在上升的过程中 对图形进行不同角度的旋转,通过 mShapeView.getCurrentShapeType() 可以拿到当前绘制的图形,然后对其 rotation属性进行旋转操作。

这样所有效果就大功告成了!可以在其他布局中 直接使用 LoadingView,展示效果了。

4. 最后


一个很有意思的自定义View,在这篇文章中你可以学到到 canvas.drawPath路径使用,安卓动画组合使用等知识。再会!

源码已上传Github:DiyView

另外给喜欢记笔记的同学安利一款好用的云笔记软件,对比大部分国内的这个算还不错的,免费好用:wolai

Android自定义View:点赞动画效果实现 本文还有配套的精品资源,点击获取 简介:在Android开发中,自定义View是创建独特交互式界面的关键技能。本Demo通过自定义View展示了点赞时出现的笑脸和哭脸动画,增强了用户互动体验。开发者将学习到如何通过继承View类、重写onDraw()方法、处理触摸事件、实现动画效果以及优化性能来创建动画。同时,本Demo还包括了将自定义View应用到布局文件中的实践,为社交... 阅读详情

相关推荐

Android loading...加载动画

android loading...加载动画 很好用,我自己也在用。

Android Loading加载动画

【代码】Android Loading加载动画。

ZJQ990909的博客 1203

58同城新版加载动画的

58同城加载动画的实现,通过属性动画来实现,并定义时间插值器

Android自定义View--加载动画

背景 一直觉得Android系统自带的加载动画过于简单,看久了容易产生视觉疲劳,所以有时候有必要定义一些有趣的动画;也因为平时我们开发时多集中在业务与性能上的处理,对动画这一块使用得比较少;下面就来介绍一个加载动画代码的编写。最终效果如下: 技术介绍 目前Android里有三种动画模式,分别是property animation,view animation,drawable animatio

我想吃碗牛肉面 702

Android自定义view,动画

Android自定义view,实现动画效果

三款Android炫酷Loading动画组件推荐

最近突然心血来潮,对一些Loading感兴趣,Loading这玩意说重要也重要,说不重要也不重要,因为这是一个提升你产品体验的一个细节,如果loading做的好,对于一些耗时需要用户等待的页面来说会转移用户注意力,不会显得那么烦躁,所以你可以看到市面上各种各样好玩的Loading动画,那么这篇博客就准备收集下一些Loading动画吧,从这些实现思路上可以打开你们自己的思维,没准也会有创新好玩的Loading动画出现。 暂且先列举些最近GitHub新鲜出炉的Loading CircleProgress 一个效果很酷炫很创新的一个圆形加载动画 android-shapeLoadingView 据

【Android】App开发-动画效果篇

在我们玩手机的过程中,如果我们点击某一个页面时,会出现一个页面动画加载或者动画效果的现象。现在我们就来看看App开发中是如何实现动画效果的。

m0_61151031的博客 4594

【机器人学习】abb工业机器人运动学分析与圆弧轨迹规划(三维模型+matlab代码)

下载链接 solidworks模型 D-H建模 圆仿真过程 视频过程:

yjw0911的博客 2529

Android中的加载动画效果

在布局中加入一个ImageView控件,为其设置动画效果淡入淡出 AnimationSet animationSet = new AnimationSet(true); //0,1表示从完全透明到完全不透明 AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1); alphaAnimation.

啦啦啦啦 la 3420

Fluent温度超限调试:从能量方程到网格优化的实战指南

本文深入解析Fluent中温度超限问题的诊断与解决方法,从能量方程机制到网格优化策略,提供实战指南。通过分析温度与焓的换算关系,探讨典型场景如能量方程发散、局部网格质量差等,并给出五步调试法及高级命令应用,帮助工程师有效解决温度计算异常问题。

weixin_29045585的博客 530

BurpSuite实战:5分钟搞定DVWA的CSRF漏洞测试(附详细截图)

本文详细介绍了如何使用BurpSuite在DVWA靶场中进行CSRF漏洞测试,包括环境配置、攻击原理剖析、分步攻击演示及企业级防御方案。通过实战案例,帮助读者深入理解CSRF漏洞的危害与防护措施,提升Web应用安全防护能力。

weixin_30879169的博客 493

Android实战页面内容加载动画

前言文章开头来看一下本篇文章要实现的效果,如图左边是慕课网APP中的效果,右边是58同城APP中的加载动画。实现第一种动画之前用图形的混合模式和贝塞尔曲线实现过慕课网的下拉刷新的加载动画。见链接慕课网app下拉刷新图标填充效果的实现,而这种动画效果在app中其实也很常见,之前的那篇文章是自定义View绘制出来的,其实这个也可以用DrawableAnimation实现,这里,我们来实现一下,看看有多简

区长的专栏 6078

ESP32-P4 GPIO双域架构:HP/LP分离、寄存器级控制与低功耗工程实践

GPIO(通用输入输出)是嵌入式系统中最基础且高频使用的硬件接口,其性能、灵活性与功耗特性直接影响产品实时性与续航能力。现代高性能MCU如ESP32-P4通过HP/LP双电源域分离、可编程IO复用(IO MUX)、信号交换矩阵及硬件自动化机制(如ETM事件、Sigma-Delta调制),将传统GPIO升级为兼具模拟能力、亚微秒响应与微安级待机的智能外设子系统。其核心价值在于实现引脚功能动态重构、中断零延迟处理、Deep-sleep期间自主唤醒与多核安全操作。典型应用场景涵盖工业PLC信号采集、电池供电传感器

weixin_35949153的博客 95

Android 自定义数据加载动画

Android自定义数据加载动画

故不积跬步无以至千里 863

LLM大模型-vLLM本地部署全流程:Windows WSL2环境安装、HuggingFace与Modelscope模型加载与本地运行、Docker化部署与镜像分发

vLLM本地部署大模型方案 vLLM是一款高性能大模型推理引擎,通过PagedAttention技术显著提升吞吐量和内存效率,支持低成本、高并发的本地部署。 核心优势: 性能卓越:吞吐量远超同类方案,支持连续批处理等高级功能 成本优化:减少GPU服务器需求 兼容性强:提供类OpenAI的简洁API 部署步骤: 硬件准备:需NVIDIA GPU(如A100/3090),显存≥模型参数量×2(7B模型需14GB) 软件环境: Linux系统或Windows WSL2 安装CUDA 12.1+和Python 3.

2202_75674969的博客 4565

python基础:工作会用到的95%的基础python代码都在这了(万字详解!)

本文是一份Python编程语言的快速参考备忘单,涵盖了Python基础语法和常用数据类型。主要内容包括:Python入门指南(打印、变量声明)、内置数据类型(字符串、数值、列表、元组、集合、字典等)、控制结构(判断、循环)、函数定义、文件处理操作以及字符串操作方法(切片、循环遍历等)。这个备忘单特别适合初学者快速查阅Python基础语法,同时也提供了数据类型转换、f-string格式化字符串等实用技巧。通过简洁的代码示例展示了Python的基本语法规则和典型用法。

数据知道的博客 8158

Android 简单又炫酷的帧动画(加载动画)

博主声明: 转载请在开头附加本文链接及作者信息,并标记为转载。本文由博主威威喵原创,请多支持与指教。 本文首发于此 博主:威威喵|博客主页:https://blog.youkuaiyun.com/smile_running Android 提供了一种简单而好用的帧动画,所谓帧动画,就是一帧一帧的播放,你可以想象一下民国时期那种电影片的效果,它用的就是一帧一帧的播放,说白了就是...

你若盛开,蜜蜂自来 7739

深度学习流体力学:基于PyTorch的物理信息神经网络(PINN)完整实现

本文介绍了基于物理信息神经网络(PINN)的深度学习流体力学求解器实现。首先阐述了Navier-Stokes方程的理论基础,包括连续性方程和动量守恒方程,并解释了PINN的核心原理:将物理方程作为约束条件嵌入神经网络损失函数。以经典的lid-driven cavity流动为例,详细展示了使用PyTorch实现的全流程,包括神经网络架构设计、自动微分求解Navier-Stokes方程、多约束条件优化训练等关键环节。该求解器通过将物理方程、边界条件和初始条件整合到损失函数中,实现了对流体力学问题的端到端求解,为

源代码杀手的博客 9832

Android开发——自定义加载动画

本文中的动画,类属于Tween动画。 首先,看效果图。 ![动画效果图](http://img.blog.youkuaiyun.com/20170220142129435?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDMyNTEyNQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gr

豫州 477

Agent智能体:核心概念与架构——建立系统认知

本文摘要介绍了Agent智能体的核心概念与架构设计。主要内容包括: Agent定义与分类:阐述了Agent作为能够感知环境、决策执行的智能实体,重点分析了现代基于大语言模型(LLM)的Agent架构。 核心模块组成:详细说明了Agent的五大核心模块(感知、规划、记忆、工具和执行)及其交互流程。 UML建模展示:通过类图和序列图,清晰呈现了Agent系统的静态结构和动态执行过程。 项目结构设计:给出了模块化的代码目录结构,为实际开发提供参考框架。

lza_csdn2019的博客 633

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Android 自定义加载动画Dialog弹窗

自定义loading dialog通过这个的值改变不同的弹窗背景。然后就是一个动画文件这个文件一定要放在anim文件夹下(PS:什么?你说你没有这个文件夹?没有你就创建一个啊,我的天!loading_animation.xml代码如下:

2401_87033955的博客 694

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

android 蒙层动画,Android酷炫加载进度动画

一、概述本自定义动画进度酷炫View,是加载进度动画的自定义View,继承于ImageView来实现,主要实现蒙层加载进度的加载进度效果。支持水平左右加载和垂直上下加载四个方向,同时也支持自定义蒙层进度颜色。直接看下面的效果图吧。二、效果图废话不说,先来看看效果图吧~~三、实现原理方案1、自定义View-XCLoadingImageView,继承ImageVIew来实现,这样就不用自己再处理dra...

weixin_39858298的博客 423

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Android实现加载动画(附带源码)

Android实现加载动画(附带源码)

欢迎来到我的博客!这里是一个专注于计算机技术的分享平台,涵盖编程开发、算法研究、系统架构、软件工程等多个领域。无论你是初学者还是资深开发者,都能在这里找到有价值的内容。 511

Android加载中动画AVLoadingIndicatorView的使用封装

最近在逛Github的时候发现了一个安卓加载中的动画框架AVLoadingIndicatorView,这个框架非常的不错,里面集合了各种各样的加载框架,有很多的样式可以选择。种类虽然比较多,但不是我想要的样式,此篇文章主要讲的是在其基础上封装一个自己想要的样式。    废话不多说,直接上图:  本来就是站在巨人的肩膀上的,至于其具体的用法我就不详细阐述了,给上大家github的地址,大家可

engineer_zh的博客 1万+

android应用启动加载动画页面

1、当你打开一个应用程序时,会看到前面有一个加载动画页面,看看怎么来实现  2、新建一个.xml 文件,添加一个ImageView 组件 RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"       xmlns:tools="http://schemas.android.co

建大灰太狼的专栏 1396

android 自定义加载动画效果,Android自定义加载动画-舞动阶梯

Android自定义动画系列十四,今天来分享第14个自定义动画,一个递增的楼梯动画(STAIRS_CIRCLE),此动画灵感来自于评论区,很感谢。原文链接:查看原文介绍废话不多说,先看看效果吧,如下:系列十四.gif正文今天在简书收到了一个评论,内容大致如下:可不可以来一个自增的阶梯动画?看到这条评论后,我很激动,突然又有了当年写Android代码的热情了。虽然我已经一年多不在开发Android应...

weixin_42213784的博客 320
上一篇: 重学 Android 自定义 View 系列(六):环形进度条
下一篇: 分析android :The binary version of its metadata is 1.8.0, expected version is 1.5.1.等系列问题
_蓝橙
博客等级 码龄7年 1179粉丝 174原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值