Android 사용자 정의 진도 바 의 원 각 가로 진도 바 인 스 턴 스 상세 설명
invalidate()방법
RectF 방법의 응용
onMeasure 방법의 응용
2.원리
3 층 의 원 각 사각형 을 그 리 며 밑 층 은 검은색 이 고 2 층 은 회색 이 며 맨 윗 층 은 진도 색 이다.예시 도 는 다음 과 같다.
3.효과 도
원 각 진 도 를 실현 하 는 데 는 또 다른 방법 이 많다.예 를 들 어 Progress 컨트롤 에 원 각 그림 을 채 우 고 스 트 레 칭 그림 을 통 해 예상 한 효 과 를 얻 는 것 은 간단 하 게 들 리 지만 실현 하기 에는 좀 번거롭다.
4.해설 법
(1)invalidate()방법
invalidate()는 View 를 새로 고 치 는 데 사 용 됩 니 다.UI 스 레 드 에서 작업 해 야 합 니 다.예 를 들 어 어떤 view 의 디 스 플레이 를 수정 할 때 invalidate()를 호출 해 야 다시 그 려 진 화면 을 볼 수 있 습 니 다.invalidate()호출 은 이전의 오래된 view 를 주 UI 스 레 드 대기 열 에서 pop 으로 떨 어 뜨리 는 것 입 니 다.일반적으로 사용자 정의 컨트롤 에서 이 방법 을 사용 합 니 다.
(2)RectF 방법의 응용
RectF 는 직사각형 을 그 리 는 방법 이다.
RectF(left,top,right,bottom),네 가지 매개 변수의 의 미 는 각각 부모 컨트롤 거리 사각형 왼쪽 위 오른쪽 아래 여백 의 거리 이 고 다음은 그림 으로 설명 한다.
drawRoundRect 방법 은 원 각 사각형 을 그 리 는 데 사 용 됩 니 다.매개 변 수 는 다음 과 같 습 니 다.
매개 변수 설명
rect:RectF 대상.
rx:x 방향의 원 각 반경.
y:y 방향의 원 각 반경.
paint:그림 을 그 릴 때 사용 하 는 붓.
(3)onMeasure 방법
사용자 정의 컨트롤 이 화면 에 있 는 크기 를 지정 합 니 다.onMeasure 방법의 두 매개 변 수 는 이전 컨트롤 에서 들 어 오 는 크기 이 고 패턴 과 크기 가 혼 합 된 수치 입 니 다.Measure Spec.getMode(width Measure Spec)가 모드 를 얻 고 Measure Spec.getSize(width Measure Spec)가 사 이 즈 를 얻 을 수 있 습 니 다.
onMeasure 의 몇 가지 모델 은 각각 EXACTLY,AT 이다.MOST,UNSPECIFIED。
[1]MeasureSpec.EXACTLY
Measure Spec.EXACTLY 는 정확 한 사이즈 입 니 다.컨트롤 의 layotwidth 또는 layotheight 가 구체 적 인 수치 로 지정 되 었 을 때,예 를 들 어 andorid:layotwidth="50dip"또는 FILLPARENT 는 모두 컨트롤 크기 가 확 정 된 경우 이 며 정확 한 사이즈 입 니 다.
[2]MeasureSpec.AT_MOST
MeasureSpec.AT_MOST 는 최대 사이즈 입 니 다.컨트롤 의 layotwidth 또는 layotheight 는 WRAP 로 지정CONTENT 시 컨트롤 크기 는 일반적으로 컨트롤 의 하위 공간 이나 내용 에 따라 달라 집 니 다.이때 컨트롤 사 이 즈 는 부모 컨트롤 이 허용 하 는 최대 사 이 즈 를 초과 하지 않 으 면 됩 니 다.그래서 이때 mode 는 AT 입 니 다.MOST,size 는 부모 컨트롤 이 허용 하 는 최대 사 이 즈 를 보 여 줍 니 다.
[3]MeasureSpec.UNSPECIFIED
Measure Spec.UNSPECIFIED 는 사 이 즈 를 지정 하지 않 은 경우 가 많 지 않 습 니 다.보통 부모 컨트롤 은 AdapterView 이 고 measure 방법 으로 들 어 오 는 모드 입 니 다.
5.activity_main.xml 파일:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.progresstest.MainActivity"
tools:ignore="MergeRootFrame" >
<com.example.progresstest.ProgressViewTest
android:id="@+id/progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
6.ProgressViewTest.java 파일
package com.example.progresstest;
import android.content.Context;
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 ProgressViewTest extends View {
/** */
private float maxCount;
/** */
private float currentCount;
/** */
private Paint mPaint;
private int mWidth,mHeight;
public ProgressViewTest(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
public ProgressViewTest(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public ProgressViewTest(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
/***
*
* @param maxCount
*/
public void setMaxCount(float maxCount) {
this.maxCount = maxCount;
}
/**
*
*/
public double getMaxCount(){
return maxCount;
}
/***
*
* @param currentCount
*/
public void setCurrentCount(float currentCount) {
this.currentCount = currentCount > maxCount ? maxCount : currentCount;
/**
* invalidate() View , UI 。 view ,
* invalidate() 。invalidate() view UI
* pop 。
*/
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
mPaint = new Paint();
//
mPaint.setAntiAlias(true);
//
mPaint.setColor(Color.BLACK);
int round = mHeight/2;
/**
* RectF: , left,top,right,bottom
*
*/
RectF rf = new RectF(0, 0, mWidth, mHeight);
/* , */
canvas.drawRoundRect(rf, round, round, mPaint);
/* progress */
mPaint.setColor(Color.rgb(211, 211, 211));
RectF rectBlackBg = new RectF(2, 2, mWidth-2, mHeight-2);
canvas.drawRoundRect(rectBlackBg, round, round, mPaint);
//
float section = currentCount/maxCount;
RectF rectProgressBg = new RectF(3, 3, (mWidth-3)*section, mHeight-3);
if(section!=0.0f){
mPaint.setColor(Color.GREEN);
}else{
mPaint.setColor(Color.TRANSPARENT);
}
canvas.drawRoundRect(rectProgressBg, round, round, mPaint);
}
//dip * scale + 0.5f * (dip >= 0 ? 1 : -1)
private int dipToPx(int dip){
float scale = getContext().getResources().getDisplayMetrics().density;
return (int) (dip * scale + 0.5f * (dip >= 0 ? 1 : -1));// 0.5
}
/** ,onMeasure
* , , MeasureSpec.getMode(widthMeasureSpec)
* ,MeasureSpec.getSize(widthMeasureSpec)
*
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
//MeasureSpec.EXACTLY,
if (widthSpecMode == MeasureSpec.EXACTLY || widthSpecMode == MeasureSpec.AT_MOST) {
mWidth = widthSpecSize;
} else {
mWidth = 0;
}
//MeasureSpec.AT_MOST, , ,MeasureSpec.UNSPECIFIED
if (heightSpecMode == MeasureSpec.AT_MOST || heightSpecMode == MeasureSpec.UNSPECIFIED) {
mHeight = dipToPx(20);
} else {
mHeight = heightSpecSize;
}
//
setMeasuredDimension(mWidth, mHeight);
}
}
MainActivity.java 파일
package com.example.progresstest;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
public class MainActivity extends ActionBarActivity {
private ProgressViewTest progress;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progress = (ProgressViewTest) findViewById(R.id.progressbar);
progress.setMaxCount(100);
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i <=progress.getMaxCount(); i++) {
Message msg = new Message();
msg.arg1 = i;
msg.what = 0x01;
handler.sendMessage(msg);
try {
// 0.1 1
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
}
Handler handler = new Handler(){
public void handleMessage(Message msg) {
if(msg.what==0x01){
progress.setCurrentCount(msg.arg1);
}
};
};
}
위 에서 말 한 것 은 소 편 이 여러분 에 게 소개 한 안 드 로 이 드 사용자 정의 진도 바 의 원 각 수평 진도 바 인 스 턴 스 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.소 편 은 제때에 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.