Android实现两圆点之间来回移动加载进度

本文实例为大家分享了Android实现两圆点之间来回移动加载进度的具体代码,供大家参考,具体内容如下

一、前言

最近喜欢上自定义控件,喜欢实现一些简约有趣的控件,也好巩固下以前学得知识和不断的学习新知识,程序员嘛,活到老学到老。

这篇文章接着上一篇文章:Android_自定义控件之水平圆点加载进度条,类似的实现方式,都是些比较简单的view绘制。

二、实现

先看下实现的效果吧:

说下实现思路:圆点x轴会有个位移变化量,当位移达到圆点直径+圆点间距之和就回改变方向(改变方向就是通过变化量值不断增加和不断减少来实现),可能写的有点模糊,接下来看代码:

package com.kincai.testcustomview_dotalternatelyprogress;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

/**
 * Copyright (C) 2015 The KINCAI Open Source Project
 * .
 * Create By KINCAI
 * .
 * Time 2017-06-16 21:44
 * .
 * Desc 两个源点来回移动
 */

public class DotAlternatelyView extends View {
 private final String TAG = this.getClass().getSimpleName();
 private Paint mPaint = new Paint();
 /**
  * 可视为左边圆点颜色值
  */
 private int mLeftColor;
 /**
  * 可视为右边圆点颜色值
  */
 private int mRightColor;
 /**
  * 圆点半径
  */
 private int mDotRadius;
 /**
  * 圆点间距
  */
 private int mDotSpacing;
 /**
  * 圆点位移量
  */
 private float mMoveDistance;
 /**
  * 圆点移动率
  */
 private float mMoveRate;
 /**
  * 以刚开始左边圆点为准 向右移
  */
 private final int DOT_STATUS_RIGHT = 0X101;
 /**
  * 以刚开始左边圆点为准 圆点移动方向-向左移
  */
 private final int DOT_STATUS_LEFT = 0X102;
 /**
  * 以刚开始左边圆点为准,圆点移动方向
  */
 private int mDotChangeStatus = DOT_STATUS_RIGHT;
 /**
  * 圆点透明度变化最大(也就是透明度在255-mAlphaChangeTotal到255之间)
  */
 private int mAlphaChangeTotal = 130;
 /**
  * 透明度变化率
  */
 private float mAlphaChangeRate;
 /**
  * 透明度改变量
  */
 private float mAlphaChange;

 public DotAlternatelyView(Context context) {
  this(context, null);
 }

 public DotAlternatelyView(Context context, @Nullable AttributeSet attrs) {
  this(context, attrs, 0);
 }

 public DotAlternatelyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.DotAlternatelyView, defStyleAttr, 0);
  initAttributes(typedArray);
  typedArray.recycle();
  init();
 }

 private void initAttributes(TypedArray Attributes) {
  mLeftColor = Attributes.getColor(R.styleable.DotAlternatelyView_dot_dark_color, ContextCompat.getColor(getContext(), R.color.colorPrimary));
  mRightColor = Attributes.getColor(R.styleable.DotAlternatelyView_dot_light_color, ContextCompat.getColor(getContext(), R.color.colorAccent));
  mDotRadius = Attributes.getDimensionPixelSize(R.styleable.DotAlternatelyView_dot_radius, DensityUtils.dp2px(getContext(), 3));
  mDotSpacing = Attributes.getDimensionPixelSize(R.styleable.DotAlternatelyView_dot_spacing, DensityUtils.dp2px(getContext(), 6));
  mMoveRate = Attributes.getFloat(R.styleable.DotAlternatelyView_dot_move_rate, 1.2f);
 }

 /**
  * 初始化
  */
 private void init() {
  //移动总距离/移动率 = alpha总变化/x
  //x = 移动率 * alpha总变化 / 移动总距离
  mAlphaChangeRate = mMoveRate * mAlphaChangeTotal / (mDotRadius * 2 + mDotSpacing);
  mPaint.setColor(mLeftColor);
  mPaint.setAntiAlias(true);
  mPaint.setStyle(Paint.Style.FILL);
  Log.e(TAG, " aaaa " + mAlphaChangeRate);
 }

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  //测量宽高
  int widthMode = MeasureSpec.getMode(widthMeasureSpec);
  int widthSize = MeasureSpec.getSize(widthMeasureSpec);
  int heightMode = MeasureSpec.getMode(heightMeasureSpec);
  int heightSize = MeasureSpec.getSize(heightMeasureSpec);
  int width;
  int height;

  if (widthMode == MeasureSpec.EXACTLY) {
   width = widthSize;
   Log.e(TAG, "onMeasure MeasureSpec.EXACTLY widthSize=" + widthSize);
  } else {
   //指定最小宽度所有圆点加上间距的宽度, 以最小半径加上间距算总和再加上最左边和最右边变大后的距离
   width = (mDotRadius * 2) * 2 + mDotSpacing;
   Log.e(TAG, "onMeasure no MeasureSpec.EXACTLY widthSize=" + widthSize + " width=" + width);
   if (widthMode == MeasureSpec.AT_MOST) {
    width = Math.min(width, widthSize);
    Log.e(TAG, "onMeasure MeasureSpec.AT_MOST width=" + width);
   }

  }

  if (heightMode == MeasureSpec.EXACTLY) {
   height = heightSize;
   Log.e(TAG, "onMeasure MeasureSpec.EXACTLY heightSize=" + heightSize);
  } else {
   height = mDotRadius * 2;
   Log.e(TAG, "onMeasure no MeasureSpec.EXACTLY heightSize=" + heightSize + " height=" + height);
   if (heightMode == MeasureSpec.AT_MOST) {
    height = Math.min(height, heightSize);
    Log.e(TAG, "onMeasure MeasureSpec.AT_MOST height=" + height);
   }

  }
  setMeasuredDimension(width, height);
 }

 @Override
 protected void onDraw(Canvas canvas) {
  //左边圆点起点x轴
  int startPointX = getWidth() / 2 - (2 * mDotRadius * 2 + mDotSpacing) / 2 + mDotRadius;
  //左边圆点起点y轴
  int startPointY = getHeight() / 2;
  //向右移 位移要增加对应透明度变化量也需要增加 反之都需要减小
  if (mDotChangeStatus == DOT_STATUS_RIGHT) {
   mMoveDistance += mMoveRate;
   mAlphaChange += mAlphaChangeRate;
  } else {
   mAlphaChange -= mAlphaChangeRate;
   mMoveDistance -= mMoveRate;
  }
  Log.e(TAG, "mAlphaChange " + mAlphaChange);
  //当移动到最右 那么需要改变方向 反过来
  if (mMoveDistance >= mDotRadius * 2 + mDotSpacing && mDotChangeStatus == DOT_STATUS_RIGHT) {
   mDotChangeStatus = DOT_STATUS_LEFT;
   mMoveDistance = mDotRadius * 2 + mDotSpacing;
   mAlphaChange = mAlphaChangeTotal;
  } else if (mMoveDistance <= 0 && mDotChangeStatus == DOT_STATUS_LEFT) { //当移动到最座 那么需要改变方向 反过来
   mDotChangeStatus = DOT_STATUS_RIGHT;
   mMoveDistance = 0f;
   mAlphaChange = 0f;
  }

  //因为两个圆点可能会给定不同的颜色来显示 所以提供两种颜色设置mLeftColor和mRightColor
  mPaint.setColor(mLeftColor);
  mPaint.setAlpha((int) (255 - mAlphaChange));
  canvas.drawCircle(startPointX + mMoveDistance, startPointY, mDotRadius, mPaint);
  mPaint.setColor(mRightColor);
  mPaint.setAlpha((int) (255 - mAlphaChange));
  canvas.drawCircle(startPointX + mDotRadius * 2 - mMoveDistance + mDotSpacing, startPointY, mDotRadius, mPaint);

  invalidate();
 }
}

要是不容易理解的话,下载源码运行再对着源码看会容易理解

源码下载github:Android移动加载进度

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android自定义View基础开发之图片加载进度条

    学会了Paint,Canvas的基本用法之后,我们就可以动手开始实践了,先写个简单的图片加载进度条看看. 按照惯例,先看效果图,再决定要不要往下看: 既然看到这里了,应该是想了解这个图片加载进度条了,我们先看具体用法,再看自定义View的实现: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.co

  • Android基于Glide v4.x的图片加载进度监听

    Glide是一款优秀的图片加载框架,简单的配置便可以使用起来,为开发者省下了很多的功夫.不过,它没有提供其加载图片进度的api,对于这样的需求,实现起来还真颇费一番周折. 尝试 遇到这个需求,第一反应是网上肯定有人实现过,不妨借鉴一下别人的经验. Glide加载图片实现进度条效果 可惜,这个实现是基于3.7版本的,4.0版本以上的glide改动比较大,using函数已经被移除了 using() The using() API was removed in Glide 4 to encourage

  • Android自定义View仿华为圆形加载进度条

    View仿华为圆形加载进度条效果图 实现思路 可以看出该View可分为三个部分来实现 最外围的圆,该部分需要区分进度圆和底部的刻度圆,进度部分的刻度需要和底色刻度区分开来 中间显示的文字进度,需要让文字在View中居中显示 旋转的小圆点,小圆点需要模拟小球下落运动时的加速度效果,开始下落的时候慢,到最底部时最快,上来时速度再逐渐减慢 具体实现 先具体细分讲解,博客最后面给出全部源码 (1)首先为View创建自定义的xml属性 在工程的values目录下新建attrs.xml文件 <resourc

  • Android Webview添加网页加载进度条实例详解

    推荐阅读:Android WebView线性进度条实例详解 最近在android项目中使用webview嵌套了一个抽奖活动网页,活动上线,运行良好(改了N次需求和突发bug),还好这种模式的活动,只需要修改网页,不需要重新打包发布市场,这也是这种模式开发的优势之一.后来据产品哥反馈说加载网页无进度提示,好吧,这个当时真没考虑这么多,这个要加加..想当然以为轻松搞定之....其实还是比轻松要复杂点... 1.首先自定义一个WebView控件 /** * 带进度条的Webivew * @author

  • Android仿微信公众号文章页面加载进度条

    前言: 微信公众号文章详情页面加载的时候,WebView会在头部显示一个进度条,这样做的好处就是用户可以一边加载网页内容的同时也可浏览网页内容,不需要等完全加载完之后才全部显示出来.如何实现呢? 其实很简单,自定义一个WebView就可以实现了. 详细实现步骤如下 : 1.自定义一个ProgressWebView 继续 Webview @SuppressWarnings("deprecation") public class ProgressWebView extends WebVie

  • Android 进度条 ProgressBar的实现代码(隐藏、出现、加载进度)

    初识进度条ProgressBar 软件:Android Studio 实现: 1.点击按钮,进度条隐藏:再次点击,进度条出现.循环 2.点击按钮,水平进度条进度呈现并+10,此处进度条max为100.循环 1.圆形进度条 练习 <ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/progress_b

  • Android自定义View实现加载进度条效果

    上一篇文章总结了下自定义View的几个步骤,如果还有不清楚的同学可以先去看看Android自定义View(一),这篇文章和大家分享一下自定义加载进度条,效果如下 下面就以水平的进度条为列进行讲解: 1.首先还是在attrs.xml文件中自定义我们需要的属性: <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="GradientP

  • Android实现图片加载进度提示

    本文实例为大家分享了Android实现图片加载进度提示的具体代码,供大家参考,具体内容如下 先上图: 实现原理: 第一个控件的实现原理是重写ImageView的onDraw()方法,利用Canvas的clipRect()方法控制图片的显示区域,主键扩大图片的显示区域,从而实现逐渐增加的效果 关键代码: public class LoadingImageView extends ImageView { /*** 背景图片 */ private Drawable bgDrawable; /**前景图

  • Android Material加载进度条制作代码

    最近看了几款APP的加载进度都是这种风格,感觉还不错,在网上找了一些资料,自己小练兵了一把: 主要运用的开源框架: /ViewPagerIndicator_library  主要就是tab页切换指示器 /ptr-lib 进度条 下载地址:https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh 一.使用方法 布局文件 <?xml version="1.0" encoding="utf-8"?>

  • Android实现圆形渐变加载进度条

    最近设计要求要一个圆形进度条渐变的需求: 1.画圆形进度条 2.解决渐变 最终实现效果代码 package com.view; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graph

随机推荐