Android 에서 BitmapShader 를 이용 하여 테 두 리 를 가 진 동 그 란 두상 을 만 듭 니 다.
9242 단어 androidbitmapshader원형두상
BitmapShader 의 간단 한 소개
Shader
이 무엇 인지,Shader
의 종류 가 몇 가지 가 있 는 지,그리고 어떻게 사용 하 는 지 에 대해 본 고의 범주 에 속 하지 않 는 지 에 대해 잘 모 르 는 학생 들 은 먼저Shader
의 기본 적 인 사용 을 배 워 보 는 것 을 권장 합 니 다.BitmapShader
주요 한 역할 은 Paint 대상 을 통 해 캔버스 를 지정 한Bitmap
채 워 일련의 효 과 를 실현 하 는 것 이다.다음 과 같은 세 가지 모델 로 선택 할 수 있다.1.
CLAMP
-스 트 레 칭,여기 스 트 레 칭 은 그림 의 마지막 요소 로 끊임없이 반복 된다.이 효 과 는 그림 이 비교적 작고 그 릴 면적 이 비교적 클 때 뚜렷 하 다.2.
REPEAT
-반복,가로 세로 로 계속 반복 되 며 이전 모델 과 다 릅 니 다.이런 모델 은 그림 이 비교적 작 아서 요 구 를 만족 시 키 지 못 합 니 다.가로 세로 로 계속 반복 해서 도형 을 그립 니 다.3.
MIRROR
-뒤 집기,이런 모델 은REPEAT
과 유사 하 다.다만 이곳 의 중복 은 뒤 집기 반복 이 고 종이 접 기와 효과 가 많 지 않다.그리고 우리 가 사용 하고 자 하 는 것 은
CLAMP
모델 이다.왜냐하면 우리 가 도형 의 크기 를 제어 하면 이미지 의 스 트 레 칭 을 피 할 수 있 기 때문이다.구체 적 실현 소개
그림,테두리 너비,색상 을 정의 하기 위해 서,먼저 res/values 디 렉 터 리 에 attrs.xml 파일 을 새로 만 듭 니 다.그 안에 쓸 내용 은 다음 과 같 습 니 다.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyCustomView">
<attr name="mborder_color" format="color"></attr>
<attr name="mborder_width" format="dimension"></attr>
<attr name="msrc" format="reference"></attr>
</declare-styleable>
</resources>
물론 여기에 다른 특성 도 추가 할 수 있다.우리 가 사용 하고 자 하 는 특성 을 정의 한 이상 사용자 정의View
에서 이러한 속성 을 분석 하고 이용 해 야 합 니 다.분석 과정 은 다음 과 같 습 니 다.
TypedArray type = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView);
mBorderColor = type.getColor(R.styleable.MyCustomView_mborder_color,0);
mDrawable = type.getDrawable(R.styleable.MyCustomView_msrc);
// Drawable Bitmap
BitmapDrawable bitmapDrawable = (BitmapDrawable) mDrawable;
mBitmap = bitmapDrawable.getBitmap();
mBorderWidth = type.getDimensionPixelSize(R.styleable.MyCustomView_mborder_width, 2);
주의해 야 할 것 은mSrc
속성의 해석 이다.Drawable
대상 을 얻 었 기 때문에 우 리 는 이 를Bitmap
대상 으로 전환 해 야 한다.다음은 우리 가 얻 은
Bitmap
대상 을 이용 하여 원형 두상 을 그립 니 다.BitmapShader
과Paint
의 초기 화 는 다음 과 같 습 니 다.
mSrcBitmap = Bitmap.createScaledBitmap(mBitmap, mWidth, mHeight, false);
mShader = new BitmapShader(mSrcBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint = new Paint();
mPaint.setShader(mShader);
mRadius = (mWidth - mBorderWidth * 2 - 4) / 2;
mCircleX = (mWidth) / 2;
mCircleY = (mHeight) / 2;
mSrcBitmap 는 얻 은 이미 지 를 적당 하 게 축소 하거나 확대 하여 우리 가 도형 에 대한 요구 에 적응 하 는 것 입 니 다.여기mWidth
와mHeight
는 무엇 입 니까?실제 적 으로 우 리 는 보기 가 layout_width
와layout_height
에서 전 달 된 값 을 정의 했다.그러나 여기 서 나 는 그들 에 게 처 리 를 했다.즉,최소 값 조작 을 선택 하면 너비 가 높 거나 높이 가 넓 어서 이미지 가 지정 한 구역 을 채 우지 못 하 는 현상 을 피 할 수 있다.주의해 야 할 것 은 사용자 정의 보 기 는wrap_content
를 특수 처리 해 야 하 며,그렇지 않 으 면 시스템 이 이 속성의 보 기 를 표시 하지 않 습 니 다.어떻게 처리 하 는 지 에 대해 서 는 본 사례 의 소스 코드 를 볼 수 있 고 간단 하 며 많은 사람들 이 한눈 에 알 거나 이미 알 고 있 을 것 이 라 고 믿 습 니 다.또 강조해 야 할 것 은 여기
mRadius
,즉 그 릴 원 의 반지름 인 데 왜 테두리 의 너비 곱 하기 2 를 빼 야 합 니까?우리 의 원 은 보기 가 지정 한 너비 나 높이 에 따라 그 려 진 것 임 을 알 아야 합 니 다.만약 우리 가 그린 원 이 지정 한 보기 의 내 접 원 이 라면 테 두 리 는 어디 에 두 어야 합 니까?그것 은 분명히 보기 의 바깥쪽 에 그 려 져 있 을 것 이다.그러면 우 리 는 완전한 테 두 리 를 볼 수 없 을 것 이다.그래서 이렇게 빼 는 의 미 는 테 두 리 를 위해 공간 을 비 우 는 것 이다.이상 의 조작 을 통 해 우 리 는 이미 원형 두상 을 그 렸 다.아래 에 테 두 리 를 그 렸 다.사실은 매우 간단 하 다.나 는 단지 또 하나의 정 의 를 내 렸 을 뿐이다.
Paint
대상 을 이용 하여 원 을 그 렸 을 뿐 이 고 붓 의 초기 화 작업 은 다음 과 같다.
mBorderPaint = new Paint();
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setStrokeWidth(mBorderWidth);
mBorderPaint.setColor(mBorderColor);
mBorderPaint.setStrokeCap(Paint.Cap.ROUND);
자,다음은onDraw()
함수 에서 그 릴 수 있 습 니 다.다음 과 같 습 니 다.
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(mCircleX, mCircleY, mRadius, mPaint);
canvas.drawCircle(mCircleX, mCircleY, mRadius, mBorderPaint);
}
이렇게 하면 전체 효 과 는 이 루어 진 셈 이다.다음은 어떻게 사용 하 는 지 보 겠 습 니 다.
<com.example.hwaphon.patheffecttest.MyView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginRight="8dp"
app:mborder_color="@android:color/holo_green_light"
app:mborder_width="4dp"
app:msrc="@drawable/myview_test"/>
주의 하 세 요.반드시 용기 에 이 한 마디 를 더 해 야 합 니 다.
xmlns:app=http://schemas.android.com/apk/res-auto
구체 적 으로 실 현 된 핵심 코드
package com.example.hwaphon.patheffecttest;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by Hwaphon on 2016/5/12.
*/
public class MyView extends View {
private Bitmap mBitmap;
private Drawable mDrawable;
private Bitmap mSrcBitmap;
private BitmapShader mShader;
private Paint mPaint;
private int mWidth, mHeight;
private int mRadius;
private int mCircleX, mCircleY;
private int mBorderColor;
private Paint mBorderPaint;
private int mBorderWidth;
public MyView(Context context) {
this(context, null);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray type = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView);
mBorderColor = type.getColor(R.styleable.MyCustomView_mborder_color,0);
mDrawable = type.getDrawable(R.styleable.MyCustomView_msrc);
// Drawable Bitmap
BitmapDrawable bitmapDrawable = (BitmapDrawable) mDrawable;
mBitmap = bitmapDrawable.getBitmap();
mBorderWidth = type.getDimensionPixelSize(R.styleable.MyCustomView_mborder_width, 2);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = measureWidth(widthMeasureSpec);
mHeight = measureHeight(heightMeasureSpec);
int temp = mWidth > mHeight ? mHeight : mWidth;
mWidth = mHeight = temp;
initView();
setMeasuredDimension(mWidth, mHeight);
}
private int measureHeight(int heightMeasureSpec) {
int size = MeasureSpec.getSize(heightMeasureSpec);
int sizeMode = MeasureSpec.getMode(heightMeasureSpec);
int result = 0;
if (sizeMode == MeasureSpec.EXACTLY) {
result = size;
} else {
result = 200;
if (sizeMode == MeasureSpec.AT_MOST) {
result = Math.min(result, size);
}
}
return result;
}
private int measureWidth(int widthMeasureSpec) {
int size = MeasureSpec.getSize(widthMeasureSpec);
int sizeMode = MeasureSpec.getMode(widthMeasureSpec);
int result = 0;
if (sizeMode == MeasureSpec.EXACTLY) {
result = size;
} else {
result = 200;
if (sizeMode == MeasureSpec.AT_MOST) {
result = Math.min(result, size);
}
}
return result;
}
private void initView() {
mSrcBitmap = Bitmap.createScaledBitmap(mBitmap, mWidth, mHeight, false);
mShader = new BitmapShader(mSrcBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint = new Paint();
mPaint.setShader(mShader);
mRadius = (mWidth - mBorderWidth * 2) / 2;
mCircleX = (mWidth) / 2;
mCircleY = (mHeight) / 2;
mBorderPaint = new Paint();
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setStrokeWidth(mBorderWidth);
mBorderPaint.setColor(mBorderColor);
mBorderPaint.setStrokeJoin(Paint.Join.ROUND);
mBorderPaint.setStrokeCap(Paint.Cap.ROUND);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(mCircleX, mCircleY, mRadius, mPaint);
canvas.drawCircle(mCircleX, mCircleY, mRadius, mBorderPaint);
}
}
총결산이상 은 안 드 로 이 드 가 비트 맵 셰 이 더 를 이용 해 자체 테두리 원형 얼굴 을 만 드 는 모든 콘 텐 츠 입 니 다.이 글 이 안 드 로 이 드 를 개발 할 때 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 면 댓 글로 주 고 받 으 세 요.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.