Android 사용자 정의 컨트롤 의 원형 진행 막대 애니메이션

13879 단어 Android진도 표
본 논문 의 사례 는 안 드 로 이 드 가 원형 진도 애니메이션 을 실현 하 는 구체 적 인 코드 를 공유 하여 여러분 께 참고 하 시기 바 랍 니 다.구체 적 인 내용 은 다음 과 같 습 니 다.
먼저 그림 을 붙 입 니 다.

어,괜 찮 은 것 같 지?그냥 진도 표 색깔 이 좀 못 생 겼 어.그런데 우 리 는 프로그래머 야.미 공 이 아니 야.배색 이라는 문 제 는 당연히 고려 범위 안에 있 지 않 아.
이러한 사용자 정의 컨트롤 을 어떻게 쓰 느 냐 에 중점 을 두 겠 습 니 다.
우선,채 워 지지 않 은 진도 로 회색 밑그림 이 필요 합 니 다.
그 다음 에 들 어 오 는 현재 진도 값 에 따라 채 울 때의 진도 원 호 를 그립 니 다.이 원호 에 대응 하 는 원심 각 은 현재 진도 와 진도 의 최대 치(보통 100)의 비례 로 계산 합 니 다.
그 다음 에 진도 값 에 따라 문자 알림 을 그립 니 다.
마지막 으로 컨트롤 을 다시 그리고 애니메이션 을 추가 하여 진 도 를 표시 하 는 효 과 를 얻 을 수 있 습 니 다.
코드 는 다음 과 같 습 니 다:
1、attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
 
  <declare-styleable name="circleProgressBar">
    <attr name="circleWidth" format="dimension" />
    <attr name="betaAngle" format="integer" />
    <attr name="firstColor" format="color" />
    <attr name="secondColor" format="color" />
  </declare-styleable>
 
</resources>
2、CircleProgressBar.java

package com.ctgu.circleprogressbar;
 
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Paint.FontMetricsInt;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.animation.OvershootInterpolator;
 
public class CircleProgressBar extends View
{
 /**
 *       ,   100
 */
 private int maxValue = 100;
 
 /**
 *      
 */
 private int currentValue = 0;
 
 /**
 *        ,                ,alphaAngle=(currentValue/maxValue)*360
 */
 private float alphaAngle;
 
 /**
 *        ,   Color.LTGRAY
 */
 private int firstColor;
 
 /**
 *          
 */
 private int secondColor;
 
 /**
 *      
 */
 private int circleWidth;
 
 /**
 *       
 */
 private Paint circlePaint;
 
 /**
 *       
 */
 private Paint textPaint;
 
 /**
 *         
 */
 private int[] colorArray = new int[] { Color.parseColor("#27B197"), Color.parseColor("#00A6D5") };//
 
 /**
 *           
 * 
 * @param context
 */
 public CircleProgressBar(Context context)
 {
 this(context, null);
 }
 
 /**
 *   xml   view   ,          。                。
 * 
 * @param context
 *         
 * @param attrs
 *           
 */
 public CircleProgressBar(Context context, AttributeSet attrs)
 {
 this(context, attrs, 0);
 }
 
 /**
 *  xml               。       ,   theme   ,   style   。    
 *              : defStyle - The default style to apply to this view. If 0,
 * no style will be applied (beyond what is included in the theme). This may
 * either be an attribute resource, whose value will be retrieved from the
 * current theme, or an explicit style resource.
 *             view 。   0,         
 * (         )。            ,             ,            。
 * 
 * @param context
 *         
 * @param attrs
 *            
 * @param defStyleAttr
 *           
 */
 public CircleProgressBar(Context context, AttributeSet attrs, int defStyleAttr)
 {
 super(context, attrs, defStyleAttr);
 
 TypedArray ta = context.getTheme().obtainStyledAttributes(attrs, R.styleable.circleProgressBar,
  defStyleAttr, 0);
 int n = ta.getIndexCount();
 
 for (int i = 0; i < n; i++)
 {
  int attr = ta.getIndex(i);
  switch (attr)
  {
  case R.styleable.circleProgressBar_firstColor:
   firstColor = ta.getColor(attr, Color.LTGRAY); //         
   break;
  case R.styleable.circleProgressBar_secondColor:
   secondColor = ta.getColor(attr, Color.BLUE); //           
   break;
  case R.styleable.circleProgressBar_circleWidth:
   circleWidth = ta.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
    TypedValue.COMPLEX_UNIT_DIP, 6, getResources().getDisplayMetrics())); //        6dp
   break;
  default:
   break;
  }
 }
 ta.recycle();
 
 circlePaint = new Paint();
 circlePaint.setAntiAlias(true); //    
 circlePaint.setDither(true); //    
 circlePaint.setStrokeWidth(circleWidth);
 
 textPaint = new Paint();
 textPaint.setAntiAlias(true);
 textPaint.setDither(true);
 }
 
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
 {//             ,                  
 int measureWidth = MeasureSpec.getSize(widthMeasureSpec);
 int measureHeight = MeasureSpec.getSize(heightMeasureSpec);
 setMeasuredDimension(Math.min(measureWidth, measureHeight), Math.min(measureWidth, measureHeight));
 }
 
 @Override
 protected void onDraw(Canvas canvas)
 {
 int center = this.getWidth() / 2;
 int radius = center - circleWidth / 2;
 
 drawCircle(canvas, center, radius); //       
 drawText(canvas, center, radius);
 }
 
 /**
 *       
 * 
 * @param canvas
 *          
 * @param center
 *         x y  
 * @param radius
 *          
 */
 private void drawCircle(Canvas canvas, int center, int radius)
 {
 circlePaint.setShader(null); //       shader
 circlePaint.setColor(firstColor); //          ,         
 circlePaint.setStyle(Paint.Style.STROKE); //          
 canvas.drawCircle(center, center, radius, circlePaint); //        
 RectF oval = new RectF(center - radius, center - radius, center + radius, center + radius); //        
 
 //         
 // shader  Android              。Shader              ,          。
 LinearGradient linearGradient = new LinearGradient(circleWidth, circleWidth, getMeasuredWidth()
  - circleWidth, getMeasuredHeight() - circleWidth, colorArray, null, Shader.TileMode.MIRROR);
 circlePaint.setShader(linearGradient);
 circlePaint.setShadowLayer(10, 10, 10, Color.RED);
 circlePaint.setColor(secondColor); //        
 circlePaint.setStrokeCap(Paint.Cap.ROUND); //           
 
 alphaAngle = currentValue * 360.0f / maxValue * 1.0f; //              ,            float  ,  alphaAngle   0
 canvas.drawArc(oval, -90, alphaAngle, false, circlePaint);
 }
 
 /**
 *     
 * 
 * @param canvas
 *          
 * @param center
 *         x y  
 * @param radius
 *          
 */
 private void drawText(Canvas canvas, int center, int radius)
 {
 float result = (currentValue * 100.0f / maxValue * 1.0f); //     
 String percent = String.format("%.1f", result) + "%";
 
 textPaint.setTextAlign(Paint.Align.CENTER); //       ,   x     
 textPaint.setColor(Color.BLACK); //       
 textPaint.setTextSize(40); //           
 textPaint.setStrokeWidth(0); //               0,          
 Rect bounds = new Rect(); //     
 textPaint.getTextBounds(percent, 0, percent.length(), bounds); //            
 FontMetricsInt fontMetrics = textPaint.getFontMetricsInt(); //     Text     
 int baseline = center + (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom; //        ,   http://blog.csdn.net/harvic880925/article/details/50423762
 canvas.drawText(percent, center, baseline, textPaint); //          
 }
 
 /**
 *        
 * 
 * @param width
 */
 public void setCircleWidth(int width)
 {
 this.circleWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, width, getResources()
  .getDisplayMetrics());
 circlePaint.setStrokeWidth(circleWidth);
 invalidate();
 }
 
 /**
 *        ,      LTGRAY
 * 
 * @param color
 */
 public void setFirstColor(int color)
 {
 this.firstColor = color;
 circlePaint.setColor(firstColor);
 invalidate();
 }
 
 /**
 *         ,     <br>
 * 
 * @param color
 */
 public void setSecondColor(int color)
 {
 this.secondColor = color;
 circlePaint.setColor(secondColor);
 invalidate();
 }
 
 /**
 *             
 * 
 * @param colors
 *          ,   int[]
 */
 public void setColorArray(int[] colors)
 {
 this.colorArray = colors;
 invalidate();
 }
 
 /**
 *         
 * 
 * @param progress
 *        ,    0 100
 */
 public void setProgress(int progress)
 {
 int percent = progress * maxValue / 100;
 if (percent < 0)
 {
  percent = 0;
 }
 if (percent > 100)
 {
  percent = 100;
 }
 this.currentValue = percent;
 invalidate();
 }
 
 /**
 *         ,           
 * 
 * @param progress
 *        ,    0 100
 * @param useAnimation
 *            ,true   
 */
 public void setProgress(int progress, boolean useAnimation)
 {
 int percent = progress * maxValue / 100;
 if (percent < 0)
 {
  percent = 0;
 }
 if (percent > 100)
 {
  percent = 100;
 }
 if (useAnimation) //     
 {
  ValueAnimator animator = ValueAnimator.ofInt(0, percent);
  animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
  {
  @Override
  public void onAnimationUpdate(ValueAnimator animation)
  {
   currentValue = (int) animation.getAnimatedValue();
   invalidate();
  }
  });
  animator.setInterpolator(new OvershootInterpolator());
  animator.setDuration(1000);
  animator.start();
 }
 else
 {
  setProgress(progress);
 }
 }
}
3、activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  xmlns:lh2="http://schemas.android.com/apk/res/com.ctgu.circleprogressbar"
  android:layout_width="match_parent"
  android:layout_height="match_parent" >
 
  <com.ctgu.circleprogressbar.CircleProgressBar
    android:id="@+id/circleProgressBar"
    android:layout_width="150dp"
    android:layout_height="150dp"
    android:layout_centerHorizontal="true"
    android:layout_gravity="center"
    android:layout_marginTop="20dp"
    lh2:circleWidth="6dp"
    lh2:firstColor="#d3d3d3"
    lh2:secondColor="#3B95C8" />
 
  <SeekBar
    android:id="@+id/seekbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_marginBottom="40dp"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    android:background="#778899" />
 
</RelativeLayout>
4、MainActivity.java

package com.ctgu.circleprogressbar;
 
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.widget.SeekBar;
 
public class MainActivity extends Activity
{
 private CircleProgressBar circleProgressBar; //        
 private SeekBar seekbar; //    
 
 private int[] colors = new int[] { Color.parseColor("#27B197"), Color.parseColor("#00A6D5") };
 
 @Override
 protected void onCreate(Bundle savedInstanceState)
 {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 
 circleProgressBar = (CircleProgressBar) findViewById(R.id.circleProgressBar);
// circleProgressBar.setFirstColor(Color.LTGRAY);
// circleProgressBar.setColorArray(colors); //         ,                。
// circleProgressBar.setCircleWidth(6);
 
 seekbar = (SeekBar) findViewById(R.id.seekbar);
 seekbar.setMax(100);
 seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
 {
  @Override
  public void onStopTrackingTouch(SeekBar seekBar)
  {
 
  }
 
  @Override
  public void onStartTrackingTouch(SeekBar seekBar)
  {
 
  }
 
  @Override
  public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
  {
  if (fromUser)
  {
   // circleProgressBar.setProgress(progress); //     
   circleProgressBar.setProgress(progress, true); //         
  }
  }
 });
 }
}
코드 설명 이 상세 해서 기본적으로 사용자 정의 컨트롤 을 알 아 보 는 사람 은 모두 알 아 볼 수 있 습 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기