Android 사용자 정의 View 간단 한 원형 Progress 효과 구현

먼저 효과 도 를 보 여 드 리 겠 습 니 다.느낌 이 좋 으 면 실현 방향 을 참고 하 세 요.

우 리 는 사용자 정의 원형 에서 원호 형의 사용자 정의 View 를 그 려 야 합 니 다.생각 은 다음 과 같 습 니 다.
먼저 하나의 클래스 ProgressView 를 만 들 고 View 클래스 를 계승 한 다음 에 그 중의 두 가지 구조 방법 을 다시 써 야 합 니 다.하 나 는 하나의 매개 변수 이 고 하 나 는 두 개의 매개 변수 입 니 다.xml 파일 에서 이 사용자 정의 컨트롤 을 사용 해 야 하기 때문에 이 두 매개 변수의 구조 함 수 를 정의 해 야 합 니 다.이 종 류 를 만 든 후에 우 리 는 그것 에 관여 하지 않 고 우리 가 실현 한 이 사용자 정의 View 를 고려 합 니 다.우 리 는 그것 의 어떤 부분 을 사용자 가 스스로 지정 할 수 있 도록 하고 싶 습 니까?예 를 들 어 이 Demo 에서 우 리 는 그의 바깥쪽 원 의 외곽 테두리 색깔 과 너비,그리고 부채 형의 부분의 색깔,부채 형의 성장 속도 등 속성 을 고려 합 니 다.이 때 프로젝트 프로젝트 디 렉 터 리 의 res/values 디 렉 터 리 에 attrs 라 는 자원 파일 을 만 들 려 고 합 니 다.

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ProgressView">
<!--circleColor           sweepColor         
startAngle        sweepStep        -->
<attr name="circleColor" format="color|reference"></attr>
<attr name="sweepColor" format="color|reference"></attr>
<attr name="startAngle" format="integer"></attr>
<attr name="sweepStep" format="integer"></attr>
<attr name="padding" format="integer"></attr>
</declare-styleable>
</resources>
이 를 통 해 알 수 있 듯 이탭 의 name 속성 은 AttributeSet 을 가 져 올 때 사용 할 수 있 도록 하 는 것 이 고,탭 의 name 은 xml 파일 의 android:name="등 탭 과 같은 속성 부분 을 사용자 정의 할 수 있 기 를 바 랍 니 다.format 속성 은 이 속성 이 어떤 종류의 인 자 를 받 아들 일 수 있 는 지 설정 하 는 것 입 니 다.
사용자 정의 자원 클래스 를 정의 하고 ProgressView 의 주요 코드 를 쓰기 시작 합 니 다.

package com.yztc.customprogressview;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
*     
*/
public class ProgressView extends View {
private int sweepStep = 10;//       (    )
private int padding = 40;//             
private int circleColor = Color.GRAY;//     
private int sweepColor = Color.BLUE;//    
private int startAngle = 90;//    
//           
private int storke = 20;
private int sweepAngle = 0;//     
private static final int DEFAULT_WIDTH = 200;
private static final int DEFAULT_HEIGHT = 200;
public ProgressView(Context context) {
super(context);
}
//    xml           ,              
//               ,         AttributeSet  
public ProgressView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ProgressView);
if (array != null) {
//     xml           
sweepStep = array.getInteger(R.styleable.ProgressView_sweepStep, sweepStep);
padding = array.getInteger(R.styleable.ProgressView_padding, padding);
circleColor = array.getColor(R.styleable.ProgressView_circleColor, circleColor);
sweepColor = array.getColor(R.styleable.ProgressView_sweepColor, sweepColor);
startAngle = array.getInteger(R.styleable.ProgressView_startAngle, startAngle);
//  TypeArray  
array.recycle();
}
}
/**
*        --    
*
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
Paint mPaint = new Paint();
mPaint.setAntiAlias(true); //     
//       
mPaint.setColor(circleColor);
mPaint.setStrokeWidth(storke);
mPaint.setStyle(Paint.Style.STROKE);//         
//         Height Width,  Heigh Width        ,      
canvas.drawCircle(getWidth() / 2, getWidth() / 2, getWidth() / 2 - storke / 2, mPaint);
// Log.d("tag", "onDraw: "+getWidth());
invalidate();//      view
//       
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setColor(sweepColor);
/*
drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,Paint paint)
RectF oval                        
float startAngle          
float sweepAngle                  
boolean useCenter      true              ,               (  ),
     false,        
Paint paint         
public RectF(float left, float top, float right, float bottom)
float left       (   ) x  
float top      (   ) y   
float right,       (   ) x  
float bottom       (   ) y  
*/
//RectF      ,                
RectF rectF = new RectF(padding + storke, padding + storke, getWidth() - padding - storke, getWidth() - padding - storke);
canvas.drawArc(rectF, startAngle, sweepAngle, true, mPaint);
sweepAngle += sweepStep;//           
sweepAngle = sweepAngle > 360 ? 0 : sweepAngle;
invalidate();//  view
}
//        View     View,  onMeasure()     
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int wMode = MeasureSpec.getMode(widthMeasureSpec);
int hMode = MeasureSpec.getMode(heightMeasureSpec);
int wSize = MeasureSpec.getSize(widthMeasureSpec);
int hSize = MeasureSpec.getSize(heightMeasureSpec);
//       ,                   。
switch (wMode) {
case MeasureSpec.AT_MOST://android:layout_width="warp_content"
//      
float density = getResources().getDisplayMetrics().density;
wSize = (int) (DEFAULT_WIDTH * density);
hSize = (int) (DEFAULT_HEIGHT * density);
break;
//  xml         match_parent          ,      
case MeasureSpec.EXACTLY://android:layout_width="match_parent" android:layout_width="40dp"
wSize = hSize = Math.min(wSize, hSize);
break;
}
//    onMeasure()  ,         ,     
setMeasuredDimension(wSize, hSize);
}
}
우 리 는 먼저 외부 원 을 그립 니 다.즉,drawCircle()방법 을 사용 합 니 다.여기 서 getWidth(),getHeight()를 호출 하여 레이아웃 에 설 치 된 컨트롤 의 사 이 즈 를 표시 합 니 다.원 이기 때문에 getWidth()/2 를 사용 하여 원심 위 치 를 표시 할 수 있 습 니 다.한편,내부 원호 형 을 그 릴 때 원심 의 위 치 를 확인한다.왼쪽 점 의 좌 표 는 바깥 원 의 테두리 에 원호 형 과 원래 의 간격 padding 을 더 해서 확인한다.오른쪽 점 의 x 좌 표 는 getWidth()로 전체 길 이 를 얻 고 테두리 의 너 비 를 빼 고 padding 을 빼 면 위의 거리 와 아래 의 거리 가 똑 같 아서 모 르 는 그림 을 그 리 는 것 이 바로 알 수 있다.대부분 이해 하기 어 려 운 부분 에 주석 이 달 려 있어 서 잘 보면 모 르 겠 어 요~
그리고 레이아웃 에 사용자 정의 View 를 도입 합 니 다.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.yztc.customprogressview.MainActivity">
<com.yztc.customprogressview.ProgressView
android:id="@+id/pv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0000ff"
app:padding="20"
app:circleColor="#aa0000"
app:sweepColor="#00aa00"
app:sweepStep="1"
app:startAngle="180"
/>
</RelativeLayout>
주의해 야 할 것 은 레이아웃 과 탭 에 다음 코드 를 추가 해 야 한 다 는 것 입 니 다:xmlns:app="http://schemas.android.com/apk/res-auto"
우리 가 사용 할 수 있 는 재 attrs 에서 사용자 정의 속성 을 지정 합 니 다~사용 하 는 형식 은 app:당신 이 정의 하 는 속성 입 니 다.물론 이 app 도 고정된 쓰기 가 아 닙 니 다.위 에 추 가 된 코드 의 xmlns 뒤의 필드 와 일치 하면 됩 니 다~
그리고 주의해 야 할 것 은:
기본적으로 Canvas 류 의 drawCircle()방법 을 사용 하여 원 을 그 릴 때 원 의 반지름 은 당신 이 지정 한 반지름 이 고,게다가 절반 의 가장자리 길 이 를 더 합 니 다.예 를 들 어 당신 의 테두리 size=10,radius=50 은 실제 중 공 부분의 반지름 이 55 입 니 다.이 점 을 주의 하 십시오.그렇지 않 으 면 그 려 진 원 의 네 개의 절 점 위 치 는 다른 위치 와 약간 다 르 고 톱니 효과 가 나타 나 는 것 과 유사 합 니 다.구체 적 으로 drawCircle()의 Rect 테두리 문 제 를 보십시오.

위 에서 말씀 드 린 것 은 편집장 님 께 서 소개 해 주신 안 드 로 이 드 사용자 정의 View 로 간단 한 원형 Progress 효 과 를 얻 었 습 니 다.여러분 께 도움 이 되 셨 으 면 좋 겠 습 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주세요.편집장 님 께 서 바로 답 해 드 리 겠 습 니 다!

좋은 웹페이지 즐겨찾기