自定義圓形ImageView(仿QQ頭像)
我們可以發現,現在的app對圓形圖片的使用越來越普遍,特別是使用者的頭像等。圓形圖片外觀柔和、友好、飽滿,能大大提升使用者的視覺體驗。所以今天我們就來看看怎樣自定義圓形的ImageView(一些說明與應該注意的點就寫在註釋裡了)。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomImageView">
<!--這是一個設定原圖片的屬性-->
<attr name="src" format="reference"/>
</declare-styleable>
</resources>
<?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:background="@color/bottomTabStart"
android:gravity="center"
android:orientation="vertical"
tools:context=".activtiy.MainActivity">
<com.tangao.test.view.CustomImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:src="@drawable/panda" />
</LinearLayout>
③當然,我們還需要用程式碼來實現這個自定義的ImageView(這才是最主要的)。
public class CustomImageView extends View {
// 圖片
private Bitmap mSrc;
// 控制元件的寬度
private int mWidth;
// 控制元件的高度
private int mHeight;
/**
* 把自定義的這個CustomImageView放到佈局檔案中並設定屬性,資源解析器就會進入這個構造方法,對資源進行解析
*
* @param context
* @param attrs
*/
public CustomImageView(Context context, AttributeSet attrs)// 由資源解析程式使用
{
this(context, attrs, 0);
}
public CustomImageView(Context context)// 由程式碼使用
{
this(context, null);
}
/**
* 初始化一些自定義的引數
*
* @param context
* @param attrs
* @param defStyle
*/
public CustomImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// 屬性(id)陣列
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.CustomImageView, defStyle, 0);
//a.getIndexCount();// 獲取佈局檔案中CustomImageView設定的屬性個數
//a.getIndex(i);// 返回xml中CustomImageView設定了的各屬性的 “屬性名”(就是attrs.xml中的部分或全部屬性),取值0,1,2...
// if (a.getIndexCount() == 0) {
// try {
// throw new Exception("自定義ImageView未設定圖片資源");
// } catch (Exception e) {
// e.printStackTrace();
// } finally {
// Log.i("CustomImageViewError", "自定義ImageView未設定圖片資源");
// }
// }
//根據屬性名,獲取到對應的圖片ID,再將id對應的drawable圖片轉成點陣圖
mSrc = BitmapFactory.decodeResource(getResources(),
a.getResourceId(R.styleable.CustomImageView_src, 0));
a.recycle();// 記得最後要recycle掉
}
/**
* 計算控制元件的高度和寬度,最後重置寬高度
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
/**
* 設定寬度
*/
int specMode = MeasureSpec.getMode(widthMeasureSpec);//MeasureSpec是一個用static修飾的內部類,因此可以當做一個普通的類來使用
/**
* 當customImageView設定成match_parent或具體值時,那就是 螢幕的寬高度 或 具體值
* 當customImageView設定成wrap_content時,specsize為customImageView的最大寬高度(決定於父控制元件寬高度)
*/
int specSize = MeasureSpec.getSize(widthMeasureSpec);
if (specMode == MeasureSpec.EXACTLY)// xml中customImageView中設定的match_parent , accurate(確定的值)
{
mWidth = specSize;
} else {
// 由圖片決定的寬,padding是xml中customImageView中設定的padding
int desireByImg = getPaddingLeft() + getPaddingRight() + mSrc.getWidth();
if (specMode == MeasureSpec.AT_MOST)// wrap_content
{
/**
* 當某些圖片較大時,使用wrap_content可能超出螢幕,此時 specSize < desireByImg
* 當某些圖片較小時,沒超出螢幕,此時 specSize > desireByImg
*/
mWidth = Math.min(desireByImg, specSize);
}
}
/***
* 設定高度
*/
specMode = MeasureSpec.getMode(heightMeasureSpec);
specSize = MeasureSpec.getSize(heightMeasureSpec);
if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate
{
mHeight = specSize;
} else {
int desire = getPaddingTop() + getPaddingBottom() + mSrc.getHeight();
if (specMode == MeasureSpec.AT_MOST)// wrap_content
{
mHeight = Math.min(desire, specSize);
}
}
setMeasuredDimension(mWidth, mHeight);//自行設定XML中customImageView的寬高,必須在onMesure()中呼叫
}
/**
* 繪製
*/
@Override
protected void onDraw(Canvas canvas) {
int min = Math.min(mWidth, mHeight);
/**
* 長度如果不一致,按小的值進行壓縮
*/
mSrc = Bitmap.createScaledBitmap(mSrc, min, min, false);
canvas.drawBitmap(createCircleImage(mSrc, min), 0, 0, null);
}
/**
* 根據原圖和變長繪製圓形圖片
*
* @param source
* @param min
* @return
*/
private Bitmap createCircleImage(Bitmap source, int min) {
final Paint paint = new Paint();
paint.setAntiAlias(true);//抗鋸齒
//建立一個原圖片大小的bitmap,Config.ARGB_8888說明是32位點陣圖
Bitmap target = Bitmap.createBitmap(min, min, Config.ARGB_8888);
/**
* 產生一個同樣大小的畫布
*/
Canvas canvas = new Canvas(target);
/**
* 首先繪製圓形
*/
canvas.drawCircle(min / 2, min / 2, min / 2, paint);
/**
* 使用SRC_IN
*/
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));//取畫布繪製的圓形和圖片的交集
/**
* 繪製圖片
*/
canvas.drawBitmap(source, 0, 0, paint);
return target;//返回截出的圓形圖片
}
}
本文轉載自:http://blog.csdn.net/lmj623565791/article/details/24555655
相關文章
- 自定義ImageView完成圓形頭像自定義View
- Android 自定義圓形頭像Android
- Android自定義圓形頭像Android
- Android 自定義圓形旋轉進度條,仿微博頭像載入效果Android
- 自定義頭像圓角控制元件控制元件
- Flutter 圓形/圓角頭像Flutter
- Flutter 仿QQ討論組頭像Flutter
- Android之圓形頭像裁切Android
- 基於 GD 庫生成圓形頭像
- Android 圓形頭像 自己動手Android
- 自定義圓形進度條
- Android 圓角、圓形 ImageView 實現AndroidView
- Android自定義View之高仿QQ健康AndroidView
- CircleImageView 圓形圖片頭像實現View
- 圓形 ImageView 的實現方法View
- Android自定義圓形進度條Android
- Android自定義View–仿QQ音樂歌詞AndroidView
- 《Android開發卷——設定圓形頭像,Android擷取圓形圖片》Android
- android圓形頭像的選擇和剪下並儲存出圓形圖片Android
- Android 圓形頭像 相簿和拍照裁剪選取Android
- canvas之自定義頭像功能實現Canvas
- 自定義圓形進度條控制元件控制元件
- Android自定義View--仿QQ音樂歌詞AndroidView
- Android 高仿微信頭像擷取 打造不一樣的自定義控制元件Android控制元件
- Android圓形圖片--自定義控制元件Android控制元件
- 微信小程式獲取使用者頭像修改為圓形微信小程式
- 自定義View實現箭頭沿圓轉動View
- Android自定義圓形進度條原始碼解析Android原始碼
- 自定義View合輯(5)-仿QQ郵箱下拉重新整理View
- Kotlin 背景圓頭像圖Kotlin
- android裁剪圓型頭像Android
- Android自定義設定圓形圖片控制元件Android控制元件
- Android自定義圓形進度條實現程式碼Android
- QQ群頭像 微信群頭像 多圖合併框架實現框架
- XImageView-ShapeImageView處理ImageView形狀,原形圓角等View
- 自定義 behavior 完美仿 QQ 瀏覽器首頁,美團商家詳情頁瀏覽器
- 安卓自定義View實現圖片上傳進度顯示(仿QQ)安卓View
- 自定義圓形View:實現跟隨手指移動的小球View