Android學習之 圓角邊框的幾種實現方式

小呂-ICE發表於2014-09-21

首先我將貼出幾種實現圓角邊框的dmeo程式效果圖:



方式一:使用shape元素填充背景,設定圓角/帶弧度的角

       1、首先在 \res\drawable下新建Shape為根元素的資原始檔:corners_bg.xml, 程式碼如下:

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 設定填充顏色 為白色 -->
    <solid android:color="#FFFFFF" />

    <!-- 設定幾何圖形四個角的弧度 -->
    <corners android:radius="10dp"/>

    <!-- 設定幾何形狀繪製邊框 紅色邊框 -->
    <stroke android:color="#CD2626"
        android:width="2dp"/>

</shape>

       2、在layout佈局檔案中對需要圓角的控制元件引用第一步的xml檔案作為背景即可。 如圖

       

       3、效果顯示為 demo程式效果圖中的 圖一 效果


方式二:使用.9<九妹>帶圓角圖片設為背景

       

       如圖mm_title_act_btn_normal.9.png 是一張帶圓角的圖片,只需引用它作為控制元件[這裡是Button]背景資源即可。顯示效果為 demo程式效果圖中的 圖二 效果


方式三:重寫控制元件的draw方法[這裡我以繼承ImageView為例]:重新draw方法,繪製控制元件的圓角效果

      1、CornersImageView.java為自定義的圓角ImageView   程式碼如下:

package com.ice.cornersdemo;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;

/**
 * 自定義帶圓角的ImageView
 * Created by ice on 14-8-6.
 */
public class CornersImageView extends ImageView{

    private Bitmap mBitmap;
    private BitmapShader mBitmapShader;

    private final Matrix mShaderMatrix = new Matrix();
    private final Paint mBitmapPaint = new Paint();
    private final RectF mDrawableRect = new RectF();

    private float mDrawableRadius;
    private int mBitmapWidth;
    private int mBitmapHeight;

    private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
    private static final int COLORDRAWABLE_DIMENSION = 1;

    public CornersImageView(Context context)
    {
        super(context);
    }

    public CornersImageView(Context context, AttributeSet attrs)
    {
        this(context, attrs, 0);
    }

    public CornersImageView(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        if (mBitmap == null)
        {
            return;
        }

        mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        // 設定抗鋸齒
        mBitmapPaint.setAntiAlias(true);
        // 使用點陣圖平鋪的渲染效果
        mBitmapPaint.setShader(mBitmapShader);

        mBitmapWidth = mBitmap.getWidth();
        mBitmapHeight = mBitmap.getHeight();
        mDrawableRect.set(0, 0, mBitmapWidth, mBitmapHeight);
        // 獲取圖片展示的圓形半徑
        mDrawableRadius = Math.min(mDrawableRect.width()/2, mDrawableRect.height()/2);

        invalidate();
    }

    @Override
    public void draw(Canvas canvas)
    {
        if (getDrawable() ==  null)
        {
            return;
        }
        canvas.drawCircle(getWidth()/2, getHeight()/2, mDrawableRadius, mBitmapPaint);
    }


    @Override
    public void setImageBitmap(Bitmap bm) {
        super.setImageBitmap(bm);
        mBitmap = bm;
        init();
    }


    @Override
    public void setImageDrawable(Drawable drawable) {
        super.setImageDrawable(drawable);
        mBitmap = getBitmapFromDrawable(drawable);
        init();
    }

    @Override
    public void setImageResource(int resId) {
        super.setImageResource(resId);
        mBitmap = getBitmapFromDrawable(getDrawable());
        init();
    }


    /**
     * 將Drawable轉換成Bitmap物件
     * @param drawable
     * @return
     */
    private Bitmap getBitmapFromDrawable(Drawable drawable) {
        if (drawable == null) {
            return null;
        }

        if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) drawable).getBitmap();
        }

        try {
            Bitmap bitmap;

            if (drawable instanceof ColorDrawable) {
                bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION,
                        BITMAP_CONFIG);
            } else {
                bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(),
                        BITMAP_CONFIG);
            }

            Canvas canvas = new Canvas(bitmap);
            drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
            drawable.draw(canvas);
            return bitmap;
        } catch (OutOfMemoryError e) {
            return null;
        }
    }
    
}
     2、在佈局檔案中使用自定義控制元件CornersImageView  如下圖:

           

      3、顯示效果為 demo程式效果圖中的 圖三 效果


其他:其實對於實現圖片圓形顯示前面介紹的重寫ImageView的draw方法是在控制元件本身上做處理,還有一種更簡單的方式就是在要顯示的圖片身上做處理,及對圖片本身進行圓形剪下,剪下後顯示在控制元件ImageView上。
圖片圓形剪下的方法如下:

	/**
	 * 將方形圖片剪下成圓圖
	 * @param bitmap
	 * @return
	 */
	public static Bitmap getCircleBitmap(Bitmap bitmap) {
		Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
		Canvas canvas = new Canvas(output);
		
		Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
		RectF rectF = new RectF(rect);
		
		Paint paint = new Paint();
		paint.setAntiAlias(true);   // 防止邊緣的鋸齒
		paint.setFilterBitmap(true);  // 對點陣圖進行濾波處理
		
		canvas.drawOval(rectF, paint);  // 根據rectF 繪製一個橢圓/圓形
		// 設定兩張圖片相交時的顯示模式為 SRC_IN
		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		canvas.drawBitmap(bitmap, rect, rectF, paint);
		
		return output;
	}
	

在程式碼上  我們只要獲取到待顯示圖片的Bitmap物件,然後呼叫上面的方法

getCircleBitmap(Bitmap bitmap) 進行圓形剪下後得到新的Bitmap物件,然後呼叫ImageView的方法 setImageBitma(Bitmapbitmap) 顯示在控制元件上。顯示效果為 demo程式效果圖中的 圖四 效果  [和圖三效果一樣] 。




相關文章