android開發萬能圓角ImageView
轉載請註明出處:http://blog.csdn.net/sw950729/article/details/52037798
本文出自:馬雲飛的部落格
本篇文章已授權微信公眾號 guolin_blog (郭霖)獨家釋出
最近一兩個月沒事做,然後就開始封裝一些東西,昨天上司讓我幫他做的圓角圖片。思路自然是和網上的demo不一樣的。
網上demo的效果:
差不多應該是這樣的,但是容易出一些問題,比如你的圖片本身就是個圓角?又或者圖片太大,你想縮小顯示,但出現顯示內容不全?
我想實現的效果是這樣的:
圖畫的較醜,見諒。
意思就是以他的寬高的最小值,為正方形的寬給他做圓角,當然長方形也可以的,因為我試了效果,沒有問題,你們到時候可以自己嘗試。
參考文章:
這是翔神的文章,不過他的效果,並不是我想要的,因為,他的繪圖是從(0,0)點然後擷取寬高繪圖,並不是我想要的重中間擷取,然後繪圖。
大體程式碼和他的差不多。不過依舊刪除了一些無用的程式碼(哈哈,這個我抄程式碼的特性,沒用放著幹嘛,礙眼。)
好了下面上程式碼:
初始化:
private void inital(Context context, AttributeSet attrs) {
matrix = new Matrix();
paint = new Paint();
//無鋸齒
paint.setAntiAlias(true);
TypedArray array = context.obtainStyledAttributes(attrs,
R.styleable.RoundAngelImageView);
//如果沒設定圓角的預設值,在這設定預設值為10dp
BorderRadius=dp2px(BODER_RADIUS_DEFAULT);
// 預設為Circle
type = array.getInt(R. styleable.RoundAngelImageView_type, TYPE_CIRCLE);
array.recycle();
}
這邊我用到了dp2px。這個就是將dp轉換成px。網上程式碼一堆~~~~:
public int dp2px(int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dp, getResources().getDisplayMetrics());
}
既然繼承了ImageView,少不了的自然是onmeusre方法:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//如果型別是圓形,則強制改變view的寬高一致,以小值為準
if (type == TYPE_CIRCLE) {
width = Math.min(getMeasuredWidth(), getMeasuredHeight());
radius = width / 2;
setMeasuredDimension(width, width);
}
}
設定bitmapshader的程式碼如下:
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
//將drawable轉化成bitmap物件
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
if (bitmap == null) {
return;
}
// 將bmp作為著色器,就是在指定區域內繪製bmp
BitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
float scale = 1.0f;
int viewwidth = getWidth();
int viewheight = getHeight();
int drawablewidth = bitmap.getWidth();
int drawableheight = bitmap.getHeight();
float dx = 0, dy = 0;
if (type == TYPE_CIRCLE) {
// 拿到bitmap寬或高的小值
int size = Math.min(bitmap.getWidth(), bitmap.getHeight());
scale = width * 1.0f / size;
} else if (type == TYPE_ROUND) {
// 如果圖片的寬或者高與view的寬高不匹配,計算出需要縮放的比例
// 縮放後的圖片的寬高,一定要大於我們view的寬高;所以我們這裡取大值
scale = Math.max(getWidth() * 1.0f / bitmap.getWidth(), getHeight()
* 1.0f / bitmap.getHeight());
}
if (drawablewidth * viewheight > viewwidth * drawableheight) {
dx = (viewwidth - drawablewidth * scale) * 0.5f;
} else {
dy = (viewheight - drawableheight * scale) * 0.5f;
}
// shader的變換矩陣,我們這裡主要用於放大或者縮小
matrix.setScale(scale, scale);
matrix.postTranslate((int) (dx + 0.5f), (int) (dy + 0.5f));
// 設定變換矩陣
BitmapShader.setLocalMatrix(matrix);
// 設定shader
paint.setShader(BitmapShader);
如果有人看了前面我給的參考文章,那麼,你可以發現,我把這個類的程式碼進行了改動,差不多就是把圖片的起點座標從(0,0)移動到了我想要的起點。
至於為什麼,我們開啟ImageView的原始碼,找到Center_Crop。這快程式碼的意思差不多是將圖片居中把。
來,我們上原始碼:
if (ScaleType.CENTER_CROP == mScaleType) {
mDrawMatrix = mMatrix;
float scale;
float dx = 0, dy = 0;
if (dwidth * vheight > vwidth * dheight) {
scale = (float) vheight / (float) dheight;
dx = (vwidth - dwidth * scale) * 0.5f;
} else {
scale = (float) vwidth / (float) dwidth;
dy = (vheight - dheight * scale) * 0.5f;
}
mDrawMatrix.setScale(scale, scale);
mDrawMatrix.postTranslate((int) (dx + 0.5f), (int) (dy + 0.5f));
他怎麼計算的scale我們別管它,重點是如何計算他的dx和dy。
這裡我就舉個例子來計算。drawable的寬和高是(300,200)。我要繪製的view的寬高是(200,200)。按照 我的思路繪圖是從(50,0)到(250,250),而不是(0,0)到(200,200)。
話不多說。我們看原始碼的計算:
dw*vh=300*200;
dh*vw=200*200;
/*
此時我們需要得到dx的值,dy預設為0,我的起點是(50,0),似乎是對的?我們接著計算
*/
scale = Math.max(getWidth() * 1.0f / bitmap.getWidth(), getHeight()* 1.0f / bitmap.getHeight());
/**
那麼我們的scale=math.max(200/300,200/200)=1
*/
dx = (vwidth - dwidth * scale) * 0.5f;
/**
那麼dx=(200-300*1)*05=-50,和我想要的50越來越近的,那麼為什麼他postTranslate的時候是(-50,0)而不是(50,0)?
*/
我們畫圖,來說明這一切,看完圖,你或許就懂了。
紅色框是我們之後的,那這樣,1這塊區域可以理解成沒了。銷燬了。但是實際的效果是這樣:
圓形好像看似沒什麼問題,那你們自己看圓角圖片左邊是不是被拉伸,這個拉伸距離應該剛好是我們之前計算得到的50dp。因為上圖的1那塊已經不存在了,所以你畫圖的時候那快距離就是拉伸的距離。現在我們看看-50dp的圖。
1的部分被移出去了。但他依然是存在的,所以繪製的圖是不會出現任何拉伸的。perfect~~~。
屬性配置完了,剩下的就是ondraw方法咯。很簡單,程式碼如下:
protected void onDraw(Canvas canvas) {
if (getDrawable() == null) {
return;
}
setBitmapShader();
if (type == TYPE_ROUND) {
canvas.drawRoundRect(rectF, BorderRadius, BorderRadius,
paint);
} else {
canvas.drawCircle(radius, radius, radius, paint);
}
}
當然你也得考慮到onsizechanged的時候,程式碼也不多:
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// 圓角圖片的範圍
if (type == TYPE_ROUND)
rectF = new RectF(0, 0, getWidth(), getHeight());
}
好了。在這邊我補上attrs屬性:
<attr name="borderRadius" format="dimension" />
<attr name="type">
<enum name="circle" value="0" />
<enum name="round" value="1" />
</attr>
<declare-styleable name="RoundAngelImageView">
<attr name="borderRadius" />
<attr name="type" />
</declare-styleable>
現在。一個完美的,萬能的圓角ImageVIew就解決了。不過好像還缺點什麼,對了。自行修改圓角,自行修改型別,加上這個才算完美。
附上程式碼:
//修改圓角大小
public void setBorderRadius(int borderRadius) {
int px = dp2px(borderRadius);
if (this.BorderRadius != px) {
this.BorderRadius = px;
invalidate();
}
}
//修改type
public void setType(int type) {
if (this.type != type) {
this.type = type;
if (this.type != TYPE_ROUND && this.type != TYPE_CIRCLE) {
this.type = TYPE_CIRCLE;
}
requestLayout();
}
}
現在我們新建個xml。放2張圖片。一個圓角,一個圓形,先看看效果如何:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<sw.angel.roundangelimageview.RoundAngelImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginTop="30dp"
android:layout_gravity="center"
android:src="@drawable/myimage" />
<sw.angel.roundangelimageview.RoundAngelImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginTop="30dp"
android:layout_gravity="center"
android:src="@drawable/mine"
sw:type="round" />
</LinearLayout>
多張圖片在外層加一個scrollview。好了。我們來看一下效果:
完美~~
圓角大小自行修改。型別自行修改。好了。今天主要內容就這麼多把。
整理了2個多小時~也是夠夠的。
感覺還有一些常用的控制元件,帶刪除鍵的edittext。以及可見不可見的edittext。似乎不難。(有空在研究)。
最後,問你們個問題,忙活了一天沒解決。你們用android.suport.design包是怎麼用的。為什麼我rebuild之後是這樣。
這是什麼鬼。不懂。
好了,今天就說到這邊把,能解決我問題的請留言,謝謝。我的android交流群:232748032。歡迎加入。
相關推薦
android開發萬能圓角ImageView
轉載請註明出處:http://blog.csdn.net/sw950729/article/details/52037798 本文出自:馬雲飛的部落格 本篇文章已授權微信公眾號 guolin_blog (郭霖)獨家釋出 最近一兩個月沒事做,然後就開始封裝一
Android自己定義圓角ImageView
play setfill recycle fig wid art app util clear 我們常常看到一些app中能夠顯示圓角圖片。比方qq的聯系人圖標等等,實現圓角圖片一種辦法是直接使用圓角圖片資源,當然假設沒有圓角圖片資源。我們也能夠自己通過程序實現的,以下介
Android開發萬能Utils(工具大全)
AndroidUtils Android開發不得不收藏的Utils 之前寫這篇文章主要是專案應用到的Utils,發現已經有一個更全面的開源庫總結,所以還是非常震驚可以總結的這麼全面,在此我準備重新梳理一遍~(一共兩個庫) 第一個庫: Gradle: impleme
Android開發——Java更改ImageView控制元件src屬性
Android開發——Java更改ImageView控制元件src屬性 一、ImageView控制元件 1、先在drawable資料夾中放置一個名叫icon的圖片,再在xml檔案中建立一個ImageView <ImageView android:id="@+
這才是真正的萬能圓角ImageView
本文已授權我的公眾號:我就是馬雲飛 獨家釋出 不知道有沒有人記得我去年寫過一個圓角的imageview。不知道的可以先去看看:萬能圓角imagview,本文是基於上一篇的內容進行新增以及修改的。不然直接看這篇可能會有點懵。 前言 我為什麼要二次封裝?最
Android開發學習之ImageView手勢拖拽、縮放、旋轉
在Android應用中,圖片隨手勢的拖拽、縮放、旋轉在很多場景中都會用到,今天我們要做的就是在ImageView的基礎上實現一個可以拖拽、縮放、轉轉的TouchView。 一、實現原理 OnTouc
Android自定義圓角ImageView 支援網路圖片
先看下效果圖 我們再來看一張CSDN的圓角圖片 從佈局可以看出csdn app 的頭像也是圓角的Image,但可以看到,有明顯的毛刺感,不知道是csdn
Android開發教程--設定ImageView圖片的顯示比例
為適應不同螢幕的手機,ImageView圖片的顯示比例,可以使用android:scaleType屬性來處理,處理方式的有以下幾種: 1、在xml配置中使用:android:scaleType="centerCrop" 2、在程式碼中使用: imageView.setS
android 自定義圓角ImageView以及鋸齒的處理
看到很多人開發過程中要使用圓角圖片時,解決方法有: 1.重新繪製一張圖片 2.通過佈局來配置 3.通過重寫View來實現 其中1,2在這裡就不講了,重點講講方法三的實現。實現一:通過擷取畫布一個圓形區域與圖片的相交部分進行繪製,缺點:鋸齒明顯,設定Paint,Canvas抗
Android自定義圓角ImageView
我們經常看到一些app中可以顯示圓角圖片,比如qq的聯絡人圖示等等,實現圓角圖片一種辦法是直接使用圓角圖片資源,當然如果沒有圓角圖片資源,我們也可以自己通過程式實現的,下面介紹一個自定義圓角ImageView的方法: package com.yulongfei.imagev
Android開發之自定義圓角矩形圖片ImageView
android中的ImageView只能顯示矩形的圖片,這樣一來不能滿足我們其他的需求,比如要顯示圓角矩形的圖片,這個時候,我們就需要自定義ImageView了,其原理就是首先獲取到圖片的Bitmap,然後進行裁剪對應的圓角矩形的bitmap,然後在onDraw()進行繪製
Android開發控制元件-VarietyImageView(百變ImageView,可以根據要求指定哪個角是圓角,哪個角是直角)
ImageView相信是Android開發人員再熟悉不過的一個控制元件了,在一般情況下基本的ImageView也都能滿足我們的開發需求,但相信大家也都遇到過ImageView無法滿足實際需求的情況,這次我就遇到了,先來看下需求: 1)可以設定成圓形ImageView
Android開發圓形ImageView實現
radi appcompat con code roi contex draw ttr extends 1、自定義屬性,在value文件夾下新建attrs文件,聲明如下屬性 <declare-styleable name="CircleImageView">
Android開發 - ImageView加載Base64編碼的圖片
base64編碼 [] 地址 加載本地 .cn ... ear 情況 ring 在我們開發應用的過程中,並不是所有情況下都請求圖片的URL或者加載本地圖片,有時我們需要加載Base64編碼的圖片。這種情況出現在服務端需要動態生成的圖片,比如: 二維碼 圖形驗證碼 ...
Android 開發:(四)Button圓角實現
本節學習button的圓角實現: 利用上節登入button示例: 1.效果對比: <Button android:layout_width="match_parent" android:layout_height="45dp
android開發:如何動態設定ImageView和button的背景
改變ImageView的背景 Drawable drawable = ResourcesCompat.getDrawable(getResources(), R.drawable.has_authorization, null); imv_authorization.setBac
Android開發 ImageView上繪製旋轉圓環(透明度不同的旋轉圓環,利用canvas drawArc實現)
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
Android開發 - ImageView載入Base64編碼的圖片
在我們開發應用的過程中,並不是所有情況下都請求圖片的URL或者載入本地圖片,有時我們需要載入Base64編碼的圖片。這種情況出現在服務端需要動態生成的圖片,比如: 二維碼 圖形驗證碼 ... 這些應用場景有個共同點就是,這些圖片都是由伺服器動態生成,並不需要生成後儲存成檔案再返回給客戶端
Android開發--圓角按鈕和繪製直線的實現
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
Android開發學習筆記(十二)基礎UI控制元件之ImageView、CheckBox、RadioButton
一、ImageView:直接繼承自View,它的作用是在介面上顯示Drawable物件。 ImageView在佈局檔案(如main_activity.xml)中常用的屬性 有 scaleType ,s