欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android實現(xiàn)兩圓點之間來回移動加載進度

 更新時間:2020年06月19日 11:39:54   作者:kincai  
這篇文章主要為大家詳細介紹了Android實現(xiàn)兩圓點之間來回移動加載進度,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了Android實現(xiàn)兩圓點之間來回移動加載進度的具體代碼,供大家參考,具體內(nèi)容如下

一、前言

最近喜歡上自定義控件,喜歡實現(xiàn)一些簡約有趣的控件,也好鞏固下以前學得知識和不斷的學習新知識,程序員嘛,活到老學到老。

這篇文章接著上一篇文章:Android_自定義控件之水平圓點加載進度條,類似的實現(xiàn)方式,都是些比較簡單的view繪制。

二、實現(xiàn)

先看下實現(xiàn)的效果吧:

說下實現(xiàn)思路:圓點x軸會有個位移變化量,當位移達到圓點直徑+圓點間距之和就回改變方向(改變方向就是通過變化量值不斷增加和不斷減少來實現(xiàn)),可能寫的有點模糊,接下來看代碼:

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移動加載進度

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android中Intent傳遞對象的3種方式詳解

    Android中Intent傳遞對象的3種方式詳解

    這篇文章給大家介紹了Android中Intent傳遞對象的3種方式,分別是Serializable 方式、Parcelable 方式以及JSON 方式,有需要的朋友們可以一起參考借鑒,下面來一起看看吧。
    2016-09-09
  • Android編程實現(xiàn)的短信編輯器功能示例

    Android編程實現(xiàn)的短信編輯器功能示例

    這篇文章主要介紹了Android編程實現(xiàn)的短信編輯器功能,涉及Android權(quán)限控制、界面布局及短信功能相關(guān)操作技巧,需要的朋友可以參考下
    2017-08-08
  • android開發(fā)框架afinal使用方法小結(jié)

    android開發(fā)框架afinal使用方法小結(jié)

    這篇文章主要為大家詳細總結(jié)了android開發(fā)框架afinal使用方法,注解功能、文件上傳下載功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • Android Canvas繪制文字橫縱向?qū)R

    Android Canvas繪制文字橫縱向?qū)R

    這篇文章主要介紹了Android Canvas繪制文字橫縱向?qū)R,Align屬性決定了使用該畫筆時,相較于繪制點的水平對稱方式,分別是LEFT、CENTER、RIGHT,更多相關(guān)內(nèi)容需要的小伙伴可以參考下面文章詳細內(nèi)容
    2022-06-06
  • Android編程創(chuàng)建桌面快捷方式的常用方法小結(jié)【2種方法】

    Android編程創(chuàng)建桌面快捷方式的常用方法小結(jié)【2種方法】

    這篇文章主要介紹了Android編程創(chuàng)建桌面快捷方式的常用方法,結(jié)合實例形式總結(jié)分析了2種常見的實現(xiàn)方法與相關(guān)操作技巧,需要的朋友可以參考下
    2017-02-02
  • Android事件沖突解決懸浮窗拖拽處理方案

    Android事件沖突解決懸浮窗拖拽處理方案

    這篇文章主要為大家介紹了Android事件沖突解決懸浮窗拖拽處理方案,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • Android開發(fā)中Widget的生命周期實例分析

    Android開發(fā)中Widget的生命周期實例分析

    這篇文章主要介紹了Android開發(fā)中Widget的生命周期,結(jié)合實例形式分析了Android開發(fā)中Widget生命周期所涉及的常用方法與使用技巧,代碼備有詳盡的注釋便于理解,需要的朋友可以參考下
    2016-02-02
  • Android仿QQ分組實現(xiàn)二級菜單展示

    Android仿QQ分組實現(xiàn)二級菜單展示

    這篇文章主要為大家詳細介紹了Android仿QQ分組實現(xiàn)二級菜單展示,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • Android自定義流式布局實現(xiàn)淘寶搜索記錄

    Android自定義流式布局實現(xiàn)淘寶搜索記錄

    這篇文章主要為大家詳細介紹了Android自定義流式布局實現(xiàn)淘寶搜索記錄,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • Android創(chuàng)建懸浮窗的完整步驟

    Android創(chuàng)建懸浮窗的完整步驟

    這篇文章主要給大家介紹了關(guān)于Android創(chuàng)建懸浮窗的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-05-05

最新評論