1. 程式人生 > >自定義RelativeLayout 實現圖片圓角背景

自定義RelativeLayout 實現圖片圓角背景

公司做的應用有個需求,ListView item 的背景是一張圖片,而且還要是圓角,沒想到其他法子,只好寫自定義了。

先上圖,

實現思路,

1,繼承RelativeLayout

2,定義自定義屬性(背景圖片,圓角半徑)

3,建構函式中初始化自定義屬性

4,處理背景圖片適應控制元件寬高和圓角

5,繪製背景圖片

6,呼叫super.onDraw繪製其他內容

寫自定義控制元件,我的方法是,一開始不定義自定義屬性,需要的屬、資源性全部在構造方法裡面初始化,等實現想要的效果以後再去新增自定義屬性,初始化自定義屬性。

接下來上程式碼

/**
 * 圓角圖片背景的相對佈局
 * @author Vitor Lee
 */
public class RoundBGRelativeLayout extends RelativeLayout {
	/**預設圓角半徑*/
	private static final int DEFAULT_CORNER_RADIUS=6;
	/**背景圖片*/
	private Bitmap mBg;
	/**圓角半徑*/
	private int mCornerRadius=DEFAULT_CORNER_RADIUS;
	
	public RoundBGRelativeLayout(Context context) {
		this(context,null);
	}
	
	public RoundBGRelativeLayout(Context context, AttributeSet attrs) {
		this(context, attrs,0);
	}
	
	public RoundBGRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		setWillNotDraw(false);//設定呼叫onDraw方法
		init(context,attrs,defStyle);
	}
	
	/**
	 * 得到自定義屬性
	 * @param context
	 * @param attrs
	 * @param defStyle
	 */
	private void init(Context context, AttributeSet attrs, int defStyle) {
		TypedArray ta = context.getTheme().obtainStyledAttributes(attrs, R.styleable.RoundBGRelativeLayout,defStyle,0);
		int indexCount = ta.getIndexCount();
		for (int i = 0; i < indexCount; i++) {
			int index = ta.getIndex(i);
			switch (index) {
			case R.styleable.RoundBGRelativeLayout_custom_background://得到自定義背景圖片
				int resourceId = ta.getResourceId(index,0);
				mBg=BitmapFactory.decodeResource(getResources(), resourceId);
				break;
			case R.styleable.RoundBGRelativeLayout_corner_radius://得到自定義圓角半徑
				mCornerRadius= (int) ta.getDimension(index,DEFAULT_CORNER_RADIUS);
			}
		}
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		if (mBg!=null) {
			int width = getMeasuredWidth();//得到測量的高度
			int height = getMeasuredHeight();//得到測量的寬度
			mBg=Bitmap.createScaledBitmap(mBg, width,height	,false);//建立一個縮放到指定大小的bitmap
			canvas.drawBitmap(createRoundImage(mBg,width,height), 0,0,null);//繪製圓角背景
		}
		super.onDraw(canvas);//讓RelativeLayout繪製自己
	}

	/**
	 * 建立圓角圖片
	 * @param bitmap 源圖片
	 * @param width 高度
	 * @param height 寬度
	 * @return 圓角圖片
	 */
	private Bitmap createRoundImage(Bitmap bitmap,int width,int height) {
		Paint paint=new Paint(Paint.ANTI_ALIAS_FLAG);//抗鋸齒畫筆
		Bitmap target = Bitmap.createBitmap(width,height,Config.ARGB_8888);//建立一個bigmap
		Canvas canvas=new Canvas(target);//建立一個畫布
		RectF rectF=new RectF(0, 0,width,height);//矩形
		//繪製圓角矩形
		canvas.drawRoundRect(rectF,mCornerRadius,mCornerRadius,paint);
		paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));//畫筆模式
		canvas.drawBitmap(bitmap,0,0, paint);//將畫筆
		return target;
	}

	/**
	 * 設定背景圖片
	 * @param r 資源ID
	 */
	public void setBGResource(int r){
		this.mBg=BitmapFactory.decodeResource(getResources(),r);
		invalidate();
	}
	
	/**
	 * 設定背景圖片
	 * @param b bitmap
	 */
	public void setBGBitmap(Bitmap b){
		this.mBg=b;
		invalidate();
	}
	
}

註釋寫得很詳細,我就不贅述了,需要的注意的是畫圓角的原理,這裡請參考Android 完美實現圖片圓角和圓形(對實現進行分析)
接下自定義屬性res/values/attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="RoundBGRelativeLayout">
        <attr name="custom_background" format="reference"></attr>
        <attr name="corner_radius" format="dimension"></attr>
    </declare-styleable>
</resources>

接下來佈局檔案

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:lwd="http://schemas.android.com/apk/res/com.example.background"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >

	<com.example.background.RoundBGRelativeLayout 
	    android:id="@+id/container"
	    android:layout_width="fill_parent"
	    android:layout_height="300dp"
	   	lwd:custom_background="@drawable/bg"
	   	lwd:corner_radius="16dp"
	    >
	    <TextView 
			android:layout_marginLeft="10dp"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:text="hahahaha"
	        />
	</com.example.background.RoundBGRelativeLayout>
</RelativeLayout>

在程式碼中使用

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		RoundBGRelativeLayout container=(RoundBGRelativeLayout) this.findViewById(R.id.container);
//		container.setBGResource(R.drawable.bg);
	}
}

好了,自定義RelativeLayout的圖片圓角背景完成了。