Android自定義View圓形圖片控件代碼詳解
前言
在日常開發(fā)中,圓形的圖片效果還是很常見的。可以通過(guò)給Paint設(shè)置Xfermode來(lái)實(shí)現(xiàn),這里簡(jiǎn)單記錄如下。
實(shí)現(xiàn)
實(shí)現(xiàn)圓形效果的核心是PorterDuffXfermode,對(duì)于PorterDuffXfermode,這里不展開,可以查詢相關(guān)資料。
核心代碼
//繪制背景
canvas.drawCircle(mSize / 2, mSize / 2, mSize / 2, mPaint);
//設(shè)置模式為:顯示背景層和上層的交集,且顯示上層圖像
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
//繪制要顯示的圖像
canvas.drawBitmap(mSrcBitmap, 0, 0, mPaint);
//重置Xfermode
mPaint.setXfermode(null);
自定義屬性
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CircleView">
<!--定義資源-->
<attr name="src" format="reference" />
<!--定義類型-->
<attr name="type" format="enum">
<!--圓形-->
<enum name="round" value="1" />
<!--矩形-->
<enum name="rect" value="2" />
</attr>
</declare-styleable>
</resources>
自定義控件
public class CircleView extends View {
private static final int DEFAULT_SIZE = 200;
private static final int DEFAULT_RADIUS = 20;
private static final int TYPE_ROUND = 1;
private static final int TYPE_RECT = 2;
private int mSize;
private int mResourceId;
private int mType;
private Paint mPaint;
private Bitmap mSrcBitmap;
public CircleView(Context context) {
this(context, null);
}
public CircleView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CircleView);
mResourceId = ta.getResourceId(R.styleable.CircleView_src, R.mipmap.ic_launcher);
mType = ta.getInt(R.styleable.CircleView_type, TYPE_ROUND);
ta.recycle();
init();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = getMeasureSize(widthMeasureSpec);
int height = getMeasureSize(heightMeasureSpec);
mSize = Math.min(width, height);
setMeasuredDimension(mSize, mSize);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//繪制背景
if (mSrcBitmap == null) {
mSrcBitmap = getScaleBitmap();
}
if (mType == TYPE_ROUND) {
canvas.drawCircle(mSize / 2, mSize / 2, mSize / 2, mPaint);
} else if (mType == TYPE_RECT) {
canvas.drawRoundRect(0, 0, mSize, mSize, DEFAULT_RADIUS, DEFAULT_RADIUS, mPaint);
}
//設(shè)置模式為:顯示背景層和上層的交集,且顯示上層圖像
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
//繪制要顯示的圖像
canvas.drawBitmap(mSrcBitmap, 0, 0, mPaint);
//重置Xfermode
mPaint.setXfermode(null);
}
private void init() {
//禁用硬件加速,否則可能無(wú)法繪制圓形
setLayerType(LAYER_TYPE_HARDWARE, null);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL);
}
private int getMeasureSize(int measureSpec) {
int mode = MeasureSpec.getMode(measureSpec);
int size = MeasureSpec.getSize(measureSpec);
return mode == MeasureSpec.EXACTLY ? size : DEFAULT_SIZE;
}
/**
* 獲取縮放后的Bitmap
*
* @return
*/
private Bitmap getScaleBitmap() {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), mResourceId, options);
options.inSampleSize = calcSampleSize(options, mSize, mSize);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(getResources(), mResourceId, options);
}
/**
* 計(jì)算縮放比例
*
* @param option
* @param width
* @param height
* @return
*/
private int calcSampleSize(BitmapFactory.Options option, int width, int height) {
int originWidth = option.outWidth;
int originHeight = option.outHeight;
int sampleSize = 1;
while ((originWidth = originWidth >> 1) > width && (originHeight = originHeight >> 1) > height) {
sampleSize = sampleSize << 1;
}
return sampleSize;
}
}
注意:如果沒(méi)有圓形的效果,那么可能需要禁用硬件加速:setLayerType(LAYER_TYPE_HARDWARE, null)
布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
tools:context=".MainActivity">
<com.wangyz.custom.CircleView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
app:src="@drawable/image" />
<com.wangyz.custom.CircleView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_margin="10dp"
app:src="@drawable/image" />
<com.wangyz.custom.CircleView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_margin="10dp"
app:src="@drawable/image"
app:type="rect" />
</LinearLayout>
效果

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- canvas雪花效果核心代碼分享
- Canvas實(shí)現(xiàn)動(dòng)態(tài)的雪花效果
- jquery實(shí)現(xiàn)漫天雪花飛舞的圣誕祝福雪花效果代碼分享
- android自定義view實(shí)現(xiàn)圓周運(yùn)動(dòng)
- Android自定義view實(shí)現(xiàn)輸入框效果
- Android自定義View實(shí)現(xiàn)雪花特效
- Android自定義view之太極圖的實(shí)現(xiàn)教程
- Android自定義View實(shí)現(xiàn)分段選擇按鈕的實(shí)現(xiàn)代碼
- Android自定義View實(shí)現(xiàn)跟隨手指移動(dòng)的小兔子
- Android自定義view實(shí)現(xiàn)倒計(jì)時(shí)控件
- Android如何用自定義View實(shí)現(xiàn)雪花效果
相關(guān)文章
Android實(shí)現(xiàn)類似網(wǎng)易新聞選項(xiàng)卡動(dòng)態(tài)滑動(dòng)效果
這篇文章主要介紹了Android實(shí)現(xiàn)類似網(wǎng)易新聞選項(xiàng)卡動(dòng)態(tài)滑動(dòng)效果的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11
Android上傳文件到Web服務(wù)器 PHP接收文件
這篇文章主要為大家詳細(xì)介紹了Android上傳文件到Web服務(wù)器,PHP接收文件的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03
ViewPager實(shí)現(xiàn)帶引導(dǎo)小圓點(diǎn)與自動(dòng)跳轉(zhuǎn)的引導(dǎo)界面
這篇文章主要為大家詳細(xì)介紹了ViewPager實(shí)現(xiàn)帶引導(dǎo)小圓點(diǎn)與自動(dòng)跳轉(zhuǎn)的引導(dǎo)界面,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11
Android studio制作簡(jiǎn)易計(jì)算器功能
這篇文章主要為大家詳細(xì)介紹了Android studio制作簡(jiǎn)易計(jì)算器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
Android開發(fā)環(huán)境搭建過(guò)程圖文詳解
這篇文章主要介紹了Android開發(fā)環(huán)境搭建過(guò)程圖文詳解,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10
Android中檢查網(wǎng)絡(luò)連接狀態(tài)的變化無(wú)網(wǎng)絡(luò)時(shí)跳轉(zhuǎn)到設(shè)置界面
這篇文章主要介紹了Android中檢查網(wǎng)絡(luò)連接狀態(tài)的變化無(wú)網(wǎng)絡(luò)時(shí)跳轉(zhuǎn)到設(shè)置界面,需要的朋友可以參考下2017-06-06
一文帶你深入理解Android Window系統(tǒng)
Android中的窗口系統(tǒng)是應(yīng)用程序用戶界面的核心組件之一,它負(fù)責(zé)管理可視化區(qū)域、處理用戶輸入事件以及與系統(tǒng)UI交互,本文將深入介紹與Android窗口系統(tǒng)相關(guān)的重要概念,需要的朋友可以參考下2023-10-10
Android仿美團(tuán)網(wǎng)、大眾點(diǎn)評(píng)購(gòu)買框懸浮效果修改版
這篇文章主要為大家詳細(xì)介紹了Android仿美團(tuán)網(wǎng)、大眾點(diǎn)評(píng)購(gòu)買框懸浮效果的修改版,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02

