【Android】丸いImageViewをカスタマイズしました.


最近は、ファントムQのUIでよく使われるのが、円形の画像です. Androidの中で円形のピクチャーのいくつかの方法をかきます. この文章では、このような顔写真を作る原理が分かりました.しかし、この中で提供された方法はもう一つ足りないところがあります.つまり、実際の必要に応じて画像の大きさを変えられないということです.つまり、提供された原図は大きいサイズで、変換された後の画像も大きいサイズです.これは私達の実際のプロジェクトのニーズに合わないです.そこで、中で紹介された最初の方法を改善しました.XMLで画像のサイズを直接指定できるようにします.
大体のステップ
  • 元の図を中央に切断し、正方形
  • にする.
  • 指定された幅に基づいて正方形をスケーリングする
  • .
  • 円形に裁断されました.
    効果
    コードの実装
    package com.demos.tencent_qq_ui.CustomerView;
    
    import android.content.Context; 
    import android.graphics.Bitmap; 
    import android.graphics.Canvas;
    import android.graphics.Matrix;
    import android.graphics.Paint;
    import android.graphics.PorterDuff;
    import android.graphics.PorterDuffXfermode;
    import android.graphics.Rect;
    import android.graphics.drawable.BitmapDrawable;
    import android.graphics.drawable.Drawable;
    import android.util.AttributeSet; 
    import android.widget.ImageView;
     
    
    /**
     * Created by mummyding on 15-8-7.
     */
    public class AvatarImageView extends ImageView {
        private Paint paint = new Paint();
    
        public AvatarImageView(Context context) {
            super(context);
        }
    
        public AvatarImageView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public AvatarImageView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        //        
        private Bitmap scaleBitmap(Bitmap bitmap){
            int width = getWidth();
            //      float                scale 0    
            float scale = (float)width/(float)bitmap.getWidth();
            Matrix matrix = new Matrix();
            matrix.postScale(scale, scale);
            return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
    
        }
        //           
        private Bitmap dealRawBitmap(Bitmap bitmap){
            int width = bitmap.getWidth();
            int height = bitmap.getHeight();
            //    
            int minWidth = width > height ?  height:width ;
            //        
            int leftTopX = (width - minWidth)/2;
            int leftTopY = (height - minWidth)/2;
            //      
            Bitmap newBitmap = Bitmap.createBitmap(bitmap,leftTopX,leftTopY,minWidth,minWidth,null,false);
            return  scaleBitmap(newBitmap);
        }
        @Override
        protected void onDraw(Canvas canvas) {
            Drawable drawable = getDrawable();
            if (null != drawable) {
                Bitmap rawBitmap =((BitmapDrawable)drawable).getBitmap();
    
                //  Bitmap      
                Bitmap newBitmap = dealRawBitmap(rawBitmap);
                // newBitmap      
                Bitmap circleBitmap = toRoundCorner(newBitmap, 14);
    
                final Rect rect = new Rect(0, 0, circleBitmap.getWidth(), circleBitmap.getHeight());
                paint.reset();
                //      
                canvas.drawBitmap(circleBitmap, rect, rect, paint);
            } else {
                super.onDraw(canvas);
            }
        }
    
        private Bitmap toRoundCorner(Bitmap bitmap, int pixels) {
    
            //    ARGB_4444         
            Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_4444);
            Canvas canvas = new Canvas(output);
    
            final int color = 0xff424242;
            final Rect rect = new Rect(0, 0,bitmap.getWidth(), bitmap.getHeight());
            paint.setAntiAlias(true);
            canvas.drawARGB(0, 0, 0, 0);
            paint.setColor(color);
            int x = bitmap.getWidth();
            canvas.drawCircle(x / 2, x / 2, x / 2, paint);
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
            canvas.drawBitmap(bitmap, rect, rect, paint);
            return output;
        }
    }
    
    そして直接に他のViewのようにXMLで使えます.
    例えば
     <com.demos.tencent_qq_ui.CustomerView.AvatarImageView
           android:layout_width="96dip"  <!--       -->
           android:layout_height="96dip"
           android:layout_centerHorizontal="true"
           android:src="@drawable/avatar"  <!--     -->
           />
    このように、画面に表示される画像は円形になります.
           しかし、ここで足りないところがあります.元の画像の大きさをチェックしていません.もしハイビジョンの写真を置いたら、crashが落ちてしまう可能性があります.これに対して、私の現在の解決方法はGoogle公式教程のものです. 
    Loading Large Bitmaps Efficiently   
    しかし、その原理としては、まず画像を読み込まずに、原図の大きさに基づいてスケーリング値を計算してから、スケーリング値に基づいて画像を読み取ります.しかし、この方法はビューIDを提供する必要があります.つまり、Avatarimage ViewにIDを指定して、AvatarimageViewに対応するビューを指定します.これではAvatarimage Viewは再利用できなくなります.プロジェクトの中でこれを多く使うと大変です.そのためにstackoverflowで質問しましたが、まだ答えがありません.T 
    How to make bitmap(set in src)copress?
    【転載は出典を明記してください】
    Author:MmmyDing
    出典:http://blog.csdn.net/u012560612/article/category/5651761