Android 사용자 정의 View 원형 진행 막대 구현
효 과 는 다음 과 같 습 니 다:
주 코드
CircularProgressView.java
public class CircularProgressView extends View {
private Paint mBackPaint, mProgPaint; //
private RectF mRectF; //
private int[] mColorArray; //
private int mProgress; // (0-100)
/**
*
*/
private Paint progressPaint;
/**
*
*/
private int centerX, centerY;
/**
*
*/
private int circleRadius;
public CircularProgressView(Context context) {
this(context, null);
}
public CircularProgressView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public CircularProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
@SuppressLint("Recycle")
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircularProgressView);
//
mBackPaint = new Paint();
mBackPaint.setStyle(Paint.Style.STROKE); // ,
mBackPaint.setStrokeCap(Paint.Cap.ROUND); //
mBackPaint.setAntiAlias(true); //
mBackPaint.setDither(true); //
mBackPaint.setStrokeWidth(typedArray.getDimension(R.styleable.CircularProgressView_backWidth, 5));
mBackPaint.setColor(typedArray.getColor(R.styleable.CircularProgressView_progbgColor, Color.LTGRAY));
//
mProgPaint = new Paint();
mProgPaint.setStyle(Paint.Style.STROKE); // ,
mProgPaint.setStrokeCap(Paint.Cap.ROUND); //
mProgPaint.setAntiAlias(true); //
mProgPaint.setDither(true); //
mProgPaint.setStrokeWidth(typedArray.getDimension(R.styleable.CircularProgressView_progWidth, 10));
mProgPaint.setColor(typedArray.getColor(R.styleable.CircularProgressView_progColor, Color.BLUE));
//
progressPaint = new Paint();
progressPaint.setStyle(Paint.Style.FILL); //
progressPaint.setStrokeCap(Paint.Cap.ROUND); //
progressPaint.setAntiAlias(true); //
progressPaint.setDither(true); //
progressPaint.setStrokeWidth(typedArray.getDimension(R.styleable.CircularProgressView_progWidth, 10));
progressPaint.setColor(Color.WHITE);
//
int startColor = typedArray.getColor(R.styleable.CircularProgressView_progStartColor, -1);
int firstColor = typedArray.getColor(R.styleable.CircularProgressView_progFirstColor, -1);
if (startColor != -1 && firstColor != -1) mColorArray = new int[]{startColor, firstColor};
else mColorArray = null;
//
mProgress = typedArray.getInteger(R.styleable.CircularProgressView_progress, 0);
typedArray.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int viewWide = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
int viewHigh = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
int mRectLength = (int) ((viewWide > viewHigh ? viewHigh : viewWide) - (mBackPaint.getStrokeWidth() > mProgPaint.getStrokeWidth() ? mBackPaint.getStrokeWidth() : mProgPaint.getStrokeWidth()));
int mRectL = getPaddingLeft() + (viewWide - mRectLength) / 2;
int mRectT = getPaddingTop() + (viewHigh - mRectLength) / 2;
mRectF = new RectF(mRectL, mRectT, mRectL + mRectLength, mRectT + mRectLength);
centerX = getMeasuredWidth() / 2;
centerY = getMeasuredHeight() / 2;
//
circleRadius = Math.min(getMeasuredWidth(), getMeasuredHeight()) / 2;
circleRadius-=8;
//
if (mColorArray != null && mColorArray.length > 1)
mProgPaint.setShader(new LinearGradient(0, 0, 0, getMeasuredWidth(), mColorArray, null, Shader.TileMode.MIRROR));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawArc(mRectF, 0, 360, false, mBackPaint);
canvas.drawArc(mRectF, 270, 360 * mProgress / 100, false, mProgPaint);
//
progressPaint.setStrokeWidth(10);
progressPaint.setStyle(Paint.Style.FILL);
float swipe = 360 * mProgress / 100;
Log.d("=================", swipe + " mProgress");
float radians = (float) (((swipe - 90) / 2) / 180 * 2 * Math.PI);
float endX;
float endY;
endX = centerX + circleRadius * (float) Math.cos(radians);
endY = centerY + circleRadius * (float) Math.sin(radians);
if (mProgress!=0) {
canvas.drawCircle(endX, endY, 8, progressPaint);
}
}
/**
*
*
* @return (0-100)
*/
public int getProgress() {
return mProgress;
}
/**
*
*
* @param progress (0-100)
*/
public void setProgress(int progress) {
this.mProgress = progress;
invalidate();
}
/**
* , 。 0,
*
* @param progress (0-100)
* @param animTime ( )
*/
public void setProgress(int progress, long animTime) {
if (animTime <= 0) setProgress(progress);
else {
ValueAnimator animator = ValueAnimator.ofInt(mProgress, progress);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mProgress = (int) animation.getAnimatedValue();
invalidate();
}
});
animator.setInterpolator(new OvershootInterpolator());
animator.setDuration(animTime);
animator.start();
}
}
/**
*
*
* @param width
*/
public void setBackWidth(int width) {
mBackPaint.setStrokeWidth(width);
invalidate();
}
/**
*
*
* @param color
*/
public void setBackColor(/*@ColorRes int color*/String color) {
mBackPaint.setColor(Color.parseColor(color)); //
invalidate();
}
/**
*
*
* @param width
*/
public void setProgWidth(int width) {
mProgPaint.setStrokeWidth(width);
invalidate();
}
/**
*
*
* @param color
*/
public void setProgColor(/*@ColorRes int color*/String color) {
mProgPaint.setColor(Color.parseColor(color)); //
mProgPaint.setShader(null);
invalidate();
}
/**
* ( )
*
* @param startColor
* @param firstColor
*/
public void setProgColor(@ColorRes int startColor, @ColorRes int firstColor) {
mColorArray = new int[]{ContextCompat.getColor(getContext(), startColor), ContextCompat.getColor(getContext(), firstColor)};
mProgPaint.setShader(new LinearGradient(0, 0, 0, getMeasuredWidth(), mColorArray, null, Shader.TileMode.MIRROR));
invalidate();
}
/**
* ( )
*
* @param colorArray
*/
public void setProgColor(@ColorRes int[] colorArray) {
if (colorArray == null || colorArray.length < 2) return;
mColorArray = new int[colorArray.length];
for (int index = 0; index < colorArray.length; index++)
mColorArray[index] = ContextCompat.getColor(getContext(), colorArray[index]);
mProgPaint.setShader(new LinearGradient(0, 0, 0, getMeasuredWidth(), mColorArray, null, Shader.TileMode.MIRROR));
invalidate();
}
}
attrs.xml
<declare-styleable name="CircularProgressView">
<attr name="backWidth" format="dimension" /> <!-- -->
<attr name="progWidth" format="dimension" /> <!-- -->
<attr name="progbgColor" format="color" /> <!-- -->
<attr name="progColor" format="color" /> <!-- -->
<attr name="progStartColor" format="color" /> <!-- -->
<attr name="progFirstColor" format="color" /> <!-- -->
<attr name="progress" format="integer" /> <!-- -->
</declare-styleable>
사용 방법
<com.view.CircularProgressView
android:layout_width="170dp"
android:layout_height="170dp"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
app:backWidth="5dp"
app:progWidth="5dp"
app:progbgColor="#4C5098"
app:progress="50"
android:layout_marginTop="500dp"
/>
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.