android仿直播圆点加载效果
作者:zhoushenxian 发布时间:2023-11-13 07:11:10
标签:android,直播,加载
今天实现一个很多app中使用到的加载进度条的效果,可能我们平时数据加载都使用到的是系统自带的,但是也有很多app加载进度条的效果实现挺好看,就是三个点不停的水平跑而且是变换颜色的,其实这个效果很简单,
分析:
第一步:
第二步:
为了圆的颜色 大小,以及移动的距离都对外开放,采用了自定义属性的方式,当然也可以进行设置,
分析了后 代码就直接上了,
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CirclePointLoadView">
<attr name="leftPointColor" format="color|reference"></attr>
<attr name="middlePointColor" format="color|reference"></attr>
<attr name="rightPointColor" format="color|reference"></attr>
<attr name="radius" format="integer|reference"></attr>
<attr name="translationDistance" format="dimension|reference"></attr>
</declare-styleable>
</resources>
这是自定义属性,左,中,右颜色,圆的半径,以及圆x轴移动的距离
CircleItemPointView.java
是每个子view的代码,很简单就是画了圆,然后设置了下paint的颜色而已
package com.circle.load;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by zhouguizhijxhz on 2018/5/29.
*/
public class CircleItemPointView extends View {
private Paint mPaint;
private int mColor;
public CircleItemPointView(Context context) {
this(context,null);
}
public CircleItemPointView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public CircleItemPointView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
}
@Override
protected void onDraw(Canvas canvas) {
int cx = getWidth()/2;
int cy = getHeight()/2;
canvas.drawCircle(cx,cy,cx,mPaint);
}
/**
* 切换颜色
*/
public void changeColor(int color){
mColor = color;
mPaint.setColor(color);
invalidate();
}
public void setColor(int color){
mColor = color;
mPaint.setColor(color);
invalidate();
}
/**
* 获取当前的颜色
*/
public int getColor() {
return mColor;
}
}
CirclePointLoadView.java
package com.circle.load;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.widget.RelativeLayout;
/**
* Created by zhouguizhijxhz on 2018/5/29.
*/
public class CirclePointLoadView extends RelativeLayout{
private int defaultLeftColor = Color.parseColor("#FF8247");
private int defaultMiddleColor = Color.parseColor("#EE4000");
private int defaultRightColor = Color.parseColor("#CD2626");
private int leftColor;
private int middleColor;
private int rightColor;
private int defaultCircleRadius = 10;
private int defaultTranslationDistance = 36;
private int translationDistance;
private static final long ANIMATION_DURATION = 400;
private int radius;
private CircleItemPointView leftView;
private CircleItemPointView middleView;
private CircleItemPointView rightView;
private AnimatorSet spreadAnimation;
private AnimatorSet closedAnimation;
public CirclePointLoadView(Context context) {
this(context,null);
}
public CirclePointLoadView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public CirclePointLoadView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
parseAttrs(context,attrs);
addViewToLayout(context);
}
private void addViewToLayout(Context context) {
if(null==context){
return;
}
leftView = createView(context);
leftView.setColor(leftColor);
middleView = createView(context);
middleView.setColor(middleColor);
rightView = createView(context);
rightView.setColor(rightColor);
addView(leftView);
addView(rightView);
addView(middleView);
}
/**
* 展开动画
*/
private void spreadAnimation() {
ObjectAnimator leftTranslationAnimator = ObjectAnimator.ofFloat(leftView,"translationX",0,-translationDistance);
ObjectAnimator rightTranslationAnimator = ObjectAnimator.ofFloat(rightView,"translationX",0,translationDistance);
spreadAnimation = new AnimatorSet();
spreadAnimation.setDuration(ANIMATION_DURATION);
spreadAnimation.playTogether(leftTranslationAnimator,rightTranslationAnimator);
spreadAnimation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
closedAnimation();
}
});
spreadAnimation.start();
}
private void closedAnimation() {
ObjectAnimator leftTranslationAnimator = ObjectAnimator.ofFloat(leftView,"translationX",-translationDistance,0);
ObjectAnimator rightTranslationAnimator = ObjectAnimator.ofFloat(rightView,"translationX",translationDistance,0);
closedAnimation = new AnimatorSet();
closedAnimation.setInterpolator(new AccelerateInterpolator());
closedAnimation.setDuration(ANIMATION_DURATION);
closedAnimation.playTogether(leftTranslationAnimator,rightTranslationAnimator);
closedAnimation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
int leftColor = leftView.getColor();
int rightColor = rightView.getColor();
int middleColor = middleView.getColor();
middleView.changeColor(leftColor);
rightView.changeColor(middleColor);
leftView.changeColor(rightColor);
spreadAnimation();
}
});
closedAnimation.start();
}
public CircleItemPointView createView(Context context) {
CircleItemPointView itemPointView = new CircleItemPointView(context);
LayoutParams params = new LayoutParams(DensityUtils.dp2px(context,radius),DensityUtils.dp2px(context,radius));
params.addRule(CENTER_IN_PARENT);
itemPointView.setLayoutParams(params);
return itemPointView;
}
private void parseAttrs(Context context, AttributeSet attrs) {
if(null==context||null==attrs){
return;
}
TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.CirclePointLoadView);
leftColor = typedArray.getColor(R.styleable.CirclePointLoadView_leftPointColor,defaultLeftColor);
middleColor = typedArray.getColor(R.styleable.CirclePointLoadView_middlePointColor,defaultMiddleColor);
rightColor = typedArray.getColor(R.styleable.CirclePointLoadView_rightPointColor,defaultRightColor);
radius = typedArray.getInteger(R.styleable.CirclePointLoadView_radius,defaultCircleRadius);
translationDistance = (int) typedArray.getDimension(R.styleable.CirclePointLoadView_translationDistance,defaultTranslationDistance);
translationDistance = DensityUtils.dp2px(context,translationDistance);
typedArray.recycle();
}
/**
* 开启动画
*/
public void startLoad(){
if(spreadAnimation==null){
spreadAnimation();
}
}
/**
* 停止动画
*/
public void stopLoad(){
clearAnimation();
leftView.setVisibility(View.GONE);
middleView.setVisibility(View.GONE);
rightView.setVisibility(View.GONE);
}
/**
* 设置左侧颜色值
* @param leftColor
*/
public void setLeftColor(int leftColor) {
this.leftColor = leftColor;
}
/**
* 设置中间颜色值
* @param middleColor
*/
public void setMiddleColor(int middleColor) {
this.middleColor = middleColor;
}
/**
* 设置右侧颜色值
* @param rightColor
*/
public void setRightColor(int rightColor) {
this.rightColor = rightColor;
}
/**
* 设置圆的半径
* @param radius
*/
public void setRadius(int radius) {
this.radius = radius;
}
/**
* 设置动画x轴方向移动的距离
* @param translationDistance
*/
public void setTranslationDistance(int translationDistance) {
translationDistance = translationDistance;
}
}
效果图:
来源:https://blog.csdn.net/coderinchina/article/details/80495350


猜你喜欢
- FFmpeg是一个开源免费跨平台的视频和音频流方案,属于自由软件,采用LGPL或GPL许可证(依据你选择的组件)。它提供了录制、转换以及流化
- 分布式项目和传统项目的区别就是,分布式项目有多个服务,每一个服务仅仅只实现一套系统中一个或几个功能,所有的服务组合在一起才能实现系统的完整功
- 1.什么是结构化编程编程中只使用三大结构不能使用goto语句1972年美国科学家,发表论文证明所有的程序流程,只需要三大结构完成。2.为什么
- 获取resources文件路径背景在SpringBoot项目中,需要获取resources文件的路径,网上找了好多文章都不行,后面还是结合官
- 对于之前最火的无外乎集五福了,而五福除了加十个好友获得外,最直接的途径就是支付宝的咻一咻了。那么咻一咻具体有哪些实现方式呢?下面我们将一一介
- Android 仿微信的键盘切换(录音,表情,文字,其他),IM通讯,类似朋友圈只要涉及到文字等相关的app都会要涉及到键盘的处理,今天就给
- 本例是利用C#中的性能计数器(PerformanceCounter)监控网络的状态。并能够直观的展现出来涉及到的知识点:Performanc
- 1. this 引用1.1 为什么要有this引用先来写一个日期类的例子:public class classCode { &
- 用C#写的一个DVD管理器,供大家参考,具体内容如下(大神勿喷,初学者以借鉴为主)一共分为三个类分别是:DVD(启动类),XinXi(信息类
- 在本篇中我要介绍两个概念,我觉得这两个东西必须一起来介绍,这样才能连贯。C# 2.0里我们已经匿名方法了,现在类型也玩起匿名来了,怪不得大家
- 是否允许循环依赖和bean的命名重复取决于beanfactory的两大属性allowBeanDefinitionOverriding和all
- 1,设置预处理,设置不需要拦截的请求@Componentpublic class MyWebConfig implements WebMvc
- 1.分发对象-MotionEvent事件类型有:1.ACTION_DOWN-----手指刚接触屏幕2.ACTION_MOVE------手指
- 前言:线程池是一个非常重要的知识点,也是池化技术的一个典型应用,相信很多人都有使用线程池的经历,但是对于线程池的实现原理大家都了解吗?本篇文
- 虽然jvm可以通过GC自动回收无用的内存,但是代码不好的话仍然存在内存溢出的风险。 一、为什么要了解内存泄露和内存溢出?1、内存泄
- 堆排序基本介绍1、堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),
- 概述公司的spring boot项目不是使用默认的logback作为日志框架,而是log4j2, 主要原因是logback出现过一个生产问题
- 一,简介Feign使得 Java HTTP 客户端编写更方便。Feign 灵感来源于Retrofit、JAXRS-2.0和WebSocket
- 前言现在市面上很多应用都会有当用户按返回键的时候提示用户:再按一次将退出应用的提示,也就是双击双击返回键退出应用,接下来我们就用几种办法来实
- monaco editor创建//创建和设置值if (!this.monacoEditor) { this.monacoEdit