Android 사용자 정의 View QQ 음악의 원형 회전 디스크 구현
사고 분석:
1.onMeasure 에서 전체 View 의 너비 와 높이 를 측정 한 후 너비 와 높이 를 설정 합 니 다.
2.우리 res 의 그림 자원 을 가 져 온 후 ondraw 방법 에서 원형 그림 을 그립 니 다.
3.Handler 를 통 해 Runnable 을 보 내 회전 스 레 드 를 시작 합 니 다.
4.레이아웃 에서 우리 의 View 를 사용 합 니 다.
효과 그림:
변수 정보 붙 이기:
//view
int mHeight = 0;
int mWidth = 0;
//
Bitmap bitmap = null;
//
int radius = 0;
//
Matrix matrix = new Matrix();
//
int degrees = 0;
STEP 1:전체 View 의 너비 와 높이 를 측정 한 후 너비 와 높이 를 설정 합 니 다.
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// View
mWidth = measuredWidth(widthMeasureSpec);
mHeight= measuredHeight(heightMeasureSpec);
setMeasuredDimension(mWidth, mHeight);
}
private int measuredWidth(int widthMeasureSpec) {
int Mode = MeasureSpec.getMode(widthMeasureSpec);
int Size = MeasureSpec.getSize(widthMeasureSpec);
if (Mode == MeasureSpec.EXACTLY) {
mWidth = Size;
} else {
//
int value = getPaddingLeft() + getPaddingRight() + bitmap.getWidth();
if (Mode == MeasureSpec.AT_MOST) {
// Padding , View
mWidth = Math.min(value, Size);
}
}
return mWidth;
}
private int measuredHeight(int heightMeasureSpec) {
int Mode = MeasureSpec.getMode(heightMeasureSpec);
int Size = MeasureSpec.getSize(heightMeasureSpec);
if (Mode == MeasureSpec.EXACTLY) {
mHeight = Size;
} else {
//
int value = getPaddingTop() + getPaddingBottom() + bitmap.getHeight();
if (Mode == MeasureSpec.AT_MOST) {
// Padding , View
mHeight = Math.min(value, Size);
}
}
return mHeight;
}
단계 2:우리 res 의 그림 자원 을 가 져 온 후,ondraw 방법 에서 원형 그림 을 그립 니 다.
// res
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.concat(matrix);
// View
radius = Math.min(mWidth, mHeight);
// ,
bitmap = Bitmap.createScaledBitmap(bitmap, radius, radius, false);
//
canvas.drawBitmap(createCircleImage(bitmap, radius), 0, 0, null);
matrix.reset();
}
private Bitmap createCircleImage(Bitmap source, int radius) {
Paint paint = new Paint();
paint.setAntiAlias(true);
Bitmap target = Bitmap.createBitmap(radius, radius, Bitmap.Config.ARGB_8888);
//
Canvas canvas = new Canvas(target);
//
canvas.drawCircle(radius / 2, radius / 2, radius / 2, paint);
// SRC_IN
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
// , (0,0)
canvas.drawBitmap(source, 0, 0, paint);
return target;
}
STEP 3:Handler 를 통 해 Runnable 을 보 내 회전 스 레 드 를 시작 합 니 다.
//
mHandler.post(runnable);
[java] view plain copy CODE
//----------- -----------
Handler mHandler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
matrix.postRotate(degrees++, radius / 2, radius / 2);
//
invalidate();
mHandler.postDelayed(runnable, 50);
}
};
STEP 4:레이아웃 에서 우리 의 View 사용
<com.handsome.cycle.MyCycleView
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
다음은 전체 종류의 소스 코드 입 니 다.
public class MyCycleView extends View {
//view
int mHeight = 0;
int mWidth = 0;
//
Bitmap bitmap = null;
//
int radius = 0;
//
Matrix matrix = new Matrix();
//
int degrees = 0;
//----------- -----------
Handler mHandler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
matrix.postRotate(degrees++, radius / 2, radius / 2);
//
invalidate();
mHandler.postDelayed(runnable, 50);
}
};
public MyCycleView(Context context) {
super(context);
initView();
}
public MyCycleView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public MyCycleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
public void initView() {
// res
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
//
mHandler.post(runnable);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// View
mWidth = measuredWidth(widthMeasureSpec);
mHeight = measuredHeight(heightMeasureSpec);
setMeasuredDimension(mWidth, mHeight);
}
private int measuredWidth(int widthMeasureSpec) {
int Mode = MeasureSpec.getMode(widthMeasureSpec);
int Size = MeasureSpec.getSize(widthMeasureSpec);
if (Mode == MeasureSpec.EXACTLY) {
mWidth = Size;
} else {
//
int value = getPaddingLeft() + getPaddingRight() + bitmap.getWidth();
if (Mode == MeasureSpec.AT_MOST) {
// Padding , View
mWidth = Math.min(value, Size);
}
}
return mWidth;
}
private int measuredHeight(int heightMeasureSpec) {
int Mode = MeasureSpec.getMode(heightMeasureSpec);
int Size = MeasureSpec.getSize(heightMeasureSpec);
if (Mode == MeasureSpec.EXACTLY) {
mHeight = Size;
} else {
//
int value = getPaddingTop() + getPaddingBottom() + bitmap.getHeight();
if (Mode == MeasureSpec.AT_MOST) {
// Padding , View
mHeight = Math.min(value, Size);
}
}
return mHeight;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.concat(matrix);
// View
radius = Math.min(mWidth, mHeight);
// ,
bitmap = Bitmap.createScaledBitmap(bitmap, radius, radius, false);
//
canvas.drawBitmap(createCircleImage(bitmap, radius), 0, 0, null);
matrix.reset();
}
private Bitmap createCircleImage(Bitmap source, int radius) {
Paint paint = new Paint();
paint.setAntiAlias(true);
Bitmap target = Bitmap.createBitmap(radius, radius, Bitmap.Config.ARGB_8888);
//
Canvas canvas = new Canvas(target);
//
canvas.drawCircle(radius / 2, radius / 2, radius / 2, paint);
// SRC_IN
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
// , (0,0)
canvas.drawBitmap(source, 0, 0, paint);
return target;
}
}
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 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에 따라 라이센스가 부여됩니다.