Android 사용자 정의 View 회전 하 는 원형 그림 구현
하지만 사용자 정의 뷰 는 또 나의 약점 이기 때문에 최근 에는 사용자 정의 뷰 를 모색 하고 연습 하고 있다.오늘 나 는 원형 그림 을 쓰 고 고 르 게 회전 하 는 Rotate Circle ImageView 를 썼 다.실현 방법 은 스스로 생각 하 는 것 이지 만,틀림없이 가장 좋 은 실현 방법 은 아 닐 것 이다.
사용자 정의 View 는 4 단계 로 나 뉜 다.
1:사용자 정의 속성;
2.사용자 정의 View 를 만 들 고 구조 방법 에서 사용자 정의 속성 을 가 져 옵 니 다.
3.onMeasure 방법 다시 쓰기;
4:onDraw 재 작성 방법
먼저 효과 도 를 보 여 드릴 게 요.
res/values/아래 새 attrs.xml
사용자 정의 속성
<declare-styleable name="RotateCircleImageView">
<attr name="image" format="reference" />
<attr name="rotate_sd" format="float" />
<attr name="rotate_fx" format="integer" />
<attr name="isRotate" format="boolean" />
<attr name="circle_back_width" format="dimension" />
<attr name="circle_back_color" format="color" />
</declare-styleable>
RotateCircleImageView 만 들 기
public RotateCircleImageView(Context context) {
this(context, null);
}
public RotateCircleImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RotateCircleImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initData();
}
View 의 세 가지 구조 함 수 를 다시 쓰 고 한 개의 인삼 으로 두 개의 인삼 을 호출 하 며 두 개의 인삼 으로 세 개의 인삼 을 호출 합 니 다.삼 삼 의 구조 에서 파 라 메 터 를 초기 화 합 니 다.
private Bitmap image;
private Bitmap tempImage;
private Paint paint;
private int bkWidth;//
private int rotate_fx=0;// 0= 1=
private float rotateSD = 0.8f;// -- 0.1f-1,
private boolean isRotate = false;//
private void initData() {
paint = new Paint();
paint.setAntiAlias(true);
paint.setDither(true);
TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.RotateCircleImageView, defStyleAttr, 0);//
paint.setColor(typedArray.getColor(R.styleable.RotateCircleImageView_circle_back_color,
Color.BLACK));
tempImage = BitmapFactory.decodeResource(getResources(), typedArray.getResourceId(
R.styleable.RotateCircleImageView_image, R.mipmap.ic_launcher));
bkWidth = typedArray.getDimensionPixelSize(R.styleable.
RotateCircleImageView_circle_back_width,
DensityUtils.dp2px(context, 100));// ,DensityUtils , dp px
rotateSD = typedArray.getFloat(R.styleable.RotateCircleImageView_rotate_sd, 0.8f);
rotate_fx = typedArray.getInt(R.styleable.RotateCircleImageView_rotate_fx, 0);
isRotate = typedArray.getBoolean(R.styleable.RotateCircleImageView_isRotate, true);
}
재 작성 측정 방법:주로 소포 내용 의 너비 와 높이 를 측정 하 는 값 입 니 다.
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);//
int mWidth;//
int mHeight;//
int yy_width = widthSize;// ,
if (widthMode == MeasureSpec.EXACTLY) {
mWidth = widthSize;// ( ),
} else {
yy_width=tempImage.getWidth();// ,
mWidth = yy_width + getPaddingLeft() + getPaddingRight();// Padding
}
if (heightMode == MeasureSpec.EXACTLY) {
mHeight = heightSize;//
} else {
mHeight = getPaddingTop() + getPaddingBottom() + yy_width;// Padding
// , Padding , padding
}
if (tempImage.getHeight() < tempImage.getWidth()) {
// Bitmap , ,
image = Bitmap.createScaledBitmap(tempImage, yy_width - bkWidth,
yy_width - bkWidth, false);
} else {
// Bitmap ( , )
// ,
image = Bitmap.createScaledBitmap(tempImage, yy_width - bkWidth,(int) (tempImage.getHeight() /
(((float) tempImage.getWidth()) / yy_width) - bkWidth), false);
}
setMeasuredDimension(mWidth, mHeight);// View ,
}
만약 너비 가 지정 한 크기 라면 높이 를 이 크기 에 따라 비례 하여 크기 를 조정 하고 싶 습 니 다.그러면 그림 의 원본 크기 를 가 져 와 야 하기 때문에 tempImage 가 필요 합 니 다.왜 임시 Bitmap 을 씁 니까?왜냐하면 제 가 테스트 를 해 봤 는데... 만약 내 가 이 이미지 로 Bitmap.createcaledBitmap(image,xx,xx,false)를 직접 사용한다 면;의 반환 값 을 image 에 부여 하면 이 코드 앞에서 image.getWidth()와 Image.getHeight()를 사용 하 더 라 도 되 돌아 오 는 값 은 원본 크기 가 아 닌 크기 로 크기 를 조정 하 는 것 이 이상 합 니 다.혹시 BItmap 의 getWidth 와 getHeight 는 비동기 인가요?아 는 사람 이 풀 어 줬 으 면 좋 겠 어 요.마지막 으로 onDraw 다시 쓰 는 방법.
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(getWidth() / 2, getWidth() / 2 , getWidth() / 2, paint);//
canvas.drawBitmap(getCircleBitmap(image, image.getWidth(), rotateSD),
getWidth() / 2 - image.getWidth() / 2,
getHeight() / 2 - image.getWidth() / 2, paint);//
if (isRotate) {
handler.postDelayed(runnable, 16);//16
}
}
getCircleBitmap 방법 과 하위 스 레 드 코드:
private Bitmap bitmap;
private boolean isCreateBitmap = false;
private Canvas canvas;
private PorterDuffXfermode pdf;
private Paint bitmapPaint;
private Bitmap getCircleBitmap(Bitmap image, int width, float rotate) {
if (!isCreateBitmap) {//
bitmapPaint = new Paint();
bitmapPaint.setAntiAlias(true);//
bitmapPaint.setDither(true);// ....
bitmap = Bitmap.createBitmap(width, width, Bitmap.Config.ARGB_8888);// bitmap
isCreateBitmap = true;
canvas = new Canvas(bitmap);// bitmap
canvas.drawCircle(width / 2, width / 2, width / 2, bitmapPaint);//
pdf = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);//
}
bitmapPaint.setXfermode(pdf);//
if (rotate_fx==0) {
canvas.rotate(rotate, width / 2, width / 2);//
} else {// :
canvas.rotate(-rotate, width / 2, width / 2);//
}
canvas.drawBitmap(image, 0, 0, bitmapPaint);// ,( )
bitmapPaint.setXfermode(null);
return bitmap;// bitmap , , bitmap
}
private Handler handler = new Handler();
private Runnable runnable = new Runnable() {
@Override
public void run() {
invalidate();//
}
};
처음 onDraw 방법 을 실 행 했 을 때 0.8 도 회전 한 bitmap 를 얻 었 습 니 다.그리고 16 밀리초 후에 하위 스 레 드 리 셋 을 시작 하고 onDraw 를 다시 실행 하여 0.8 도 회전 하 는 bitmap 를 얻 었 습 니 다.이런 식 으로 계속 회전 합 니 다.빨리 돌 고 싶 으 면 매번 회전 하 는 각 도 를 좀 높 여 라.그러나 너무 크게 돌 면 안 된다.그렇지 않 으 면 효과 가 매우 좋 지 않다.찰싹 찰싹.이렇게 해서 이 사용자 정의 view 를 완 성 했 습 니 다.매우 간단 하지만 저 는 오랫동안 괴 롭 혔 습 니 다.주로 측정 할 때 세심 하지 못 했 습 니 다.실현 방법 은 모두 스스로 만 든 것 이 니 더 좋 은 실현 방법 이 있다 면 알려 주 십시오.마지막 으로 두 가지 방법 을 외부 에 노출 시 키 겠 습 니 다.
public void startRotate() {//
if (!isRotate) {
this.isRotate = true;
invalidate();
}
}
public void stopRotate() {//
isRotate = false;
}
그리고 레이아웃 에서 해 볼 수 있 습 니 다.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">
<com.as.liji.jishiben.view.RotateCircleImageView
android:id="@+id/rcv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
app:circle_back_width="80dp"
app:image="@mipmap/sm"
app:isRotate="false"
app:rotate_fx="0"
app:rotate_sd="0.5" />
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/rcv"
android:layout_centerHorizontal="true"
android:ellipsize="marquee"
android:text=" : --Hold On" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/tv"
android:orientation="horizontal">
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="startRotate"
android:text=" " />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="stopRotate"
android:text=" " />
</LinearLayout>
</RelativeLayout>
activity 에서 컨트롤 을 받 고 두 단 추 를 다시 쓰 는 클릭 이벤트 방법:
private RotateCircleImageView rcv;
........onCreate(){
........
rcv = (RotateCircleImageView) findViewById(R.id.rcv);
}
public void startRotate(View v) {
rcv.startRotate();
}
public void stopRotate(View v) {
rcv.stopRotate();
}
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 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에 따라 라이센스가 부여됩니다.