Android 는 원 각 사각형 과 원형 ImageView 방식 을 실현 합 니 다.

Android 에서 원 각 사각형 과 원형 을 실현 하 는 방법 은 여러 가지 가 있 는데 그 중에서 가장 흔히 볼 수 있 는 방법 은 ImageLoader 설정 Option 과 사용자 정의 View 입 니 다.
1.ImageLoader 그림 불 러 오기

public static DisplayImageOptions getRoundOptions() {
 DisplayImageOptions options = new DisplayImageOptions.Builder()
 //        ,     ,    90        
 .displayer(new RoundedBitmapDisplayer(30))
 .build();
 return options;
 }

ImageLoader.getInstance().displayImage(imageURL, imageView, Options.getRoundOptions());
2.사용자 정의 뷰 구현
사용자 정의 View 가 원 각 사각형 과 원형 을 실현 하 는 데 도 여러 가지 방법 이 있 는데 그 중에서 가장 흔히 볼 수 있 는 것 은 Xfermode,Shader 를 이용 하 는 것 이다.본 고 는 BitmapShader 를 사용 하여 원 각 을 그립 니 다.
사용자 정의 CircleImageView
 •BitmapShader 에 대한 간단 한 이야기
BitmapShader 는 Shader 의 하위 클래스 로 Paint.setShader(Shader shader)를 통 해 설정 할 수 있 습 니 다.여기 서 저 희 는 BitmapShader,구조 방법 에 만 관심 을 가지 고 있 습 니 다.
mBitmapShader = new BitmapShader(bitmap,TileMode.CLAMP, TileMode.CLAMP);
매개 변수 1:bitmap
매개 변수 2,매개 변수 3:TileMode;
TileMode 의 수 치 는 세 가지 가 있 습 니 다.
CLAMP 스 트 레 칭
반복 반복
MIRROR 미 러 
반복:가로,세로 로 이 bitmap 를 계속 반복 하 는 것 입 니 다.
미 러:가로 가 계속 뒤 집 히 고 세로 가 계속 뒤 집 히 며 반복 합 니 다.
스 트 레 칭:그림 의 마지막 픽 셀 을 반복 합 니 다.가로의 마지막 가로 픽 셀,끊임없이 반복,세로 항목 의 픽 셀,끊임없이 반복;
비트 맵 셰 이 더 는 mPaint 에 설정 한 다음 이 mPaint 로 그림 을 그 릴 때 당신 이 설정 한 TileMode 에 따라 그리 기 영역 을 착색 한 다 는 것 을 대충 알 았 습 니 다.
우리 의 원 각 과 원형 에 대해 우리 가 설정 한 모델 은 모두 CLAMP 입 니 다.그러나 당신 은 의문 이 있 습 니까?
view 의 너비 나 높이 가 우리 의 bitmap 보다 넓 거나 높 으 면 늘 어 나 지 않 습 니까?
네,저 희 는 BitmapShader 에 matrix 를 설정 하여 그림 을 적당 하 게 확대 하거나 축소 할 것 입 니 다.'view 의 너비 나 높이 가 우리 의 bitmap 너비 나 높이 보다 크 지 않 습 니 다'라 는 조건 이 성립 되 지 않 습 니 다.
 •사용자 정의 속성 

<?xml version="1.0" encoding="utf-8"?>
<resources> 
 <declare-styleable name="CircleImageView">
 <attr name="type" format="enum">
 <enum name="circle" value="0"/>
 <enum name="round" value="1"/>
 </attr>
 <attr name="round_Radius" format="dimension" /> 
 <attr name="border_width" format="dimension" />
 <attr name="border_color" format="color" />
 </declare-styleable>
</resources>
 •사용자 정의 속성 가 져 오기

 public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
 super(context, attrs, defStyle);

 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);
 //     
 type = a.getInt(R.styleable.CircleImageView_type, TYPE_CIRCLE);
 //       
 mRoundRadius = a.getDimensionPixelSize(R.styleable.CircleImageView_round_Radius, DEFAULT_ROUND_RADIUS);
 //        
 mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_border_width, DEFAULT_BORDER_WIDTH);
 //        
 mBorderColor = a.getColor(R.styleable.CircleImageView_border_color,DEFAULT_BORDER_COLOR);
 //   recycle()   TypedArray,      
 a.recycle();

 init();
 }

 •onMeasure

@Override 
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
 /** 
 *        ,     view     ,      
 */ 
 if (type == TYPE_CIRCLE) { 
 mWidth = Math.min(getMeasuredWidth(), getMeasuredHeight()); 
 setMeasuredDimension(mWidth, mWidth); 
 }
 }
 •초기 화 매개 변수 설정

/**
 *            setup                     
 */
 private void init() {
 //   ScaleType      CENTER_CROP,           ,    
 super.setScaleType(SCALE_TYPE);
 mReady = true;
 if (mSetupPending) {
 setup();
 mSetupPending = false;
 }
 }

 /**
 *        ,           (Paint)         :
 *      BitmapShader Bitmap       ,              ,    updateShaderMatrix()    invalidate()  ;
 */
 private void setup() {
 //  mReady    false,             if          
 //  mSetupPending true      ,          。
 if (!mReady) {
 mSetupPending = true;
 return;
 }
 //       
 if (mBitmap == null) {
 return;
 }
 //      , mBitmap        ,                   
 mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
 //          
 mBitmapPaint.setAntiAlias(true);
 //          
 mBitmapPaint.setShader(mBitmapShader);
 //         
 mBorderPaint.setStyle(Paint.Style.STROKE);
 mBorderPaint.setAntiAlias(true);
 mBorderPaint.setColor(mBorderColor);
 mBorderPaint.setStrokeWidth(mBorderWidth);
 //             
 mBitmapHeight = mBitmap.getHeight();
 mBitmapWidth = mBitmap.getWidth();
 //         ,   CircleImageView       
 mBorderRect.set(0, 0, getWidth(), getHeight());
 //         mBorderRect      
 mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width() - mBorderWidth, mBorderRect.height() - mBorderWidth);

 //         onDraw      
 if (type == TYPE_CIRCLE) {
 //          (  )   , mBorderRect                  
 mBorderRadius = (mBorderRect.width() - mBorderWidth)/2;
 //           ,           
 mDrawableRadius = mDrawableRect.width()/2;
 } else if (type == TYPE_ROUND) {
 //       ,        ,        
 mBorderRect.set(mBorderWidth/2, mBorderWidth/2, getWidth() - mBorderWidth/2, getHeight() - mBorderWidth/2);
 }

 //             mBitmap         
 updateShaderMatrix();
 //    ondraw()          
 invalidate();
 }

 •렌 더러 의 변환 행렬 설정

/**
 *        BitmapShader Matrix  ,        ,    。
 *   :                       
 */
 private void updateShaderMatrix() {
 float scaleX = 1.0f;
 float scaleY = 1.0f;
 float scale = 1.0f;
 float dx = 0;
 float dy = 0;
 //           view      ,          ;         ,       view   ;         
 if (type == TYPE_CIRCLE) {
 scaleX = mWidth * 1.0f / mBitmapWidth;
 scaleY = mWidth * 1.0f / mBitmapHeight;
 scale = Math.max(scaleX, scaleY);
 } else if (type == TYPE_ROUND) {
 scaleX = getWidth() * 1.0f / mBitmapWidth;
 scaleY = getHeight() * 1.0f / mBitmapHeight;
 scale = Math.max(scaleX, scaleY);
 } 
 if (scaleX > scaleY) {
 // x    y         x                 (mDrawableRect)  )
 dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;
 } else {
 // y    x         y                 (mDrawableRect)  )
 dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
 }

 mShaderMatrix.set(null);
 //  
 mShaderMatrix.setScale(scale, scale);
 //   
 mShaderMatrix.postTranslate((int) (dx + 0.5f) + mBorderWidth, (int) (dy + 0.5f) + mBorderWidth);
 //       
 mBitmapShader.setLocalMatrix(mShaderMatrix);
 }

 •onDraw

@Override
 protected void onDraw(Canvas canvas) {
 //          
 if (getDrawable() == null)
 return;

 if (type == TYPE_ROUND) {
 //       ,      ,    ,     mBitmapPaint
 canvas.drawRoundRect(mDrawableRect, mRoundRadius, mRoundRadius, mBitmapPaint);
 if (mBorderWidth != 0) {
 //           0                       ,    ,     mBorderPaint
 canvas.drawRoundRect(mBorderRect , mRoundRadius + mBorderWidth / 2, mRoundRadius + mBorderWidth / 2, mBorderPaint);
 }
 } else if (type == TYPE_CIRCLE) {
 //     ,      ,    ,     mBitmapPaint
 canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius, mBitmapPaint);
 //           0                     ,    ,     mBorderPaint
 if (mBorderWidth != 0) {
 canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius, mBorderPaint);
 } 
 } 
 }

그리고 저 희 는 사용자 정의 View 에 몇 개의 인 터 페 이 스 를 추가 하여 유형,가장자리 색상,가장자리 너비 와 이미지 정보 등 을 직접 설정 할 수 있 습 니 다.
CircleImageView 사용 하기
레이아웃 파일:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 xmlns:attr="http://schemas.android.com/apk/res/com.hx.circleimageview"
 android:id="@+id/container"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:background="#CDCDC1"
 android:orientation="vertical" >

 <com.hx.circleimageview.CircleImageView
 android:id="@+id/image1"
 android:layout_width="150dp"
 android:layout_height="150dp"
 android:layout_margin="10dp"
 android:src="@drawable/crazy_1"
 attr:type="circle"
 attr:border_color="#FFffffff"
 attr:border_width="2dp" />

 <com.hx.circleimageview.CircleImageView
 android:id="@+id/image2"
 android:layout_width="150dp"
 android:layout_height="150dp"
 android:layout_margin="10dp"
 android:src="@drawable/crazy_2"
 attr:type="round"
 attr:border_width="2dp" />

 <com.hx.circleimageview.CircleImageView
 android:id="@+id/image3"
 android:layout_width="250dp"
 android:layout_height="150dp"
 android:layout_margin="10dp"
 android:src="@drawable/crazy_3"
 attr:type="round"
 attr:round_Radius="20dp"
 attr:border_color="#9400D3"
 attr:border_width="5dp" />
</LinearLayout>

저 희 는 JAVA 에서 ImageView 3 개 에 클릭 이 벤트 를 추가 합 니 다.

 @Override
 public void onClick(View v) {
 switch (v.getId()) {
 case R.id.image1:
 image1.setBorderColor(Color.BLACK);
 break;
 case R.id.image2:
 image2.setImageResource(R.drawable.crazy_3);
 break;
 case R.id.image3:
 int type = image3.getType() == CircleImageView.TYPE_CIRCLE ? CircleImageView.TYPE_ROUND : CircleImageView.TYPE_CIRCLE;
 image3.setType(type);
 break;
 }

실행 후 효과 그림 은 다음 과 같 습 니 다:

원본 다운로드:http://xiazai.jb51.net/201609/yuanma/Android-ImageView(jb51.net).rar
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기