自定義RelativeLayout 實現圖片圓角背景
阿新 • • 發佈:2019-01-26
公司做的應用有個需求,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的圖片圓角背景完成了。