android實現圓角
1. Android如何設置圓角按鈕
可以通過shape設置圓角
<!-- 設置圓角 -->
<corners android:radius="2dp" >
</corners>
擴展:
<?xml version="1.0" encoding="utf-8"?>
<!-- shape如果不聲明形狀默認是正方形 -->
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 設置填充色 -->
<solid android:color="#4285f4" >
</solid>
<!-- 設置邊框的顏色和寬度 -->
<stroke
android:width="1dp"
android:color="#4285f4" >
</stroke>
</shape>
通過selector設置點擊效果
button_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- 這個是用於控制按鈕組背景的文件 -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- **點擊時效果**********背景引用的資源*************************是否獲得焦點*********************是否按下******* -->
<item android:drawable="@drawable/button_p" android:state_focused="true" android:state_pressed="false"/>
<item android:drawable="@drawable/button_p" android:state_focused="true" android:state_pressed="true"/>
<item android:drawable="@drawable/button_p" android:state_focused="false" android:state_pressed="true"/>
<!-- **************沒有任何操作時顯示的背景************** -->
<item android:drawable="@drawable/button_n"></item>
</selector>
在xml文件中設置button的background屬性。
android:background="@drawable/button_bg"
2. Android 圓角、圓形 ImageView 實現
我們要實現的圖片控制項繼承自 AppCompatImageView ,它是 ImageView 的子類,但提供了更好的兼容性,我們在此基礎上添加了若干自定義的屬性和方法以實現最終的 NiceImageView :
要實圓角或者圓形的顯示效果,就是對圖片顯示的內容區域進行「裁剪」,只顯示指定的區域即可。如何做呢?
一種比較直接的辦法是這樣的,由於圖片是被繪制在畫布上的,所以用 canvas 的 clipPath() 方法先將畫布裁剪成指定形狀,這樣就能讓圖片按指定形狀顯示了,重新 draw() 方法即可:
這樣使用 src 、 background 屬性給ImageView設置顯示的圖片都能達到預期的顯示效果。但是由於 clipPath() 方法不支持抗鋸齒,圖片邊緣會有明顯的毛糙感,體驗並不理想,所以需要尋找其它方法。
另一種方法是使用圖像的 Alpha 合成模式 ,即
PorterDuff 來實現, 官方文檔 。這里我們使用其中的 DST_IN 模式。整個過程就是先繪制目標圖像,也就是圖片;再繪制原圖像,即一個圓角矩形或者圓形,這樣最終目標圖像只顯示和原圖像重合的區域。
到這里就實現了顯示為圓角或者圓形了。但是需要通過 src 屬性或者對應的方法來設置圖片,否則不能達到預期效果。
繪制邊框就相對容易理解了,只需要繪制一個指定樣式的圓角矩形或者圓形即可:
當圖片顯示為圓形時,還可以繪制一個內邊框,但圓角矩形的話由於圓角大小的問題,目前只能設置一個邊框咯。
但是有個問題,繪制的邊框會覆蓋在圖片上,如果邊框太寬會導致圖片的可見區域變小了,影像顯示效果,像這樣,左下角的花盆不見了:
那麼如何讓邊框不覆蓋在圖片上呢?可以在 Alpha 合成繪制前先將畫布縮小一定比例,最後再繪制邊框,這樣問題就解決了。
縮放後的ImageView顯示區域的寬高就是原寬、高分別減去2倍的邊框寬度,這樣縮小的比例也就顯而易見了。效果如下,左下角的花盆出來了:
遮罩可以理解為一層帶透明度的顏色,遮罩默認不繪制,當制定了遮罩顏色時才會繪制,實現很簡單:
例如加一個透明度30%的紅色遮罩後的效果:
核心的實現邏輯就這些了,剩下的就是自定義屬性和方法了,有興趣的可以看源碼,都很簡單,希望對你有所幫助吧!
更多細節及用法見GitHub: https://github.com/SheHuan/NiceImageView
如果你需要實現類似釘釘的圓形組合頭像,例如:
3. android設置控制項樣式(邊框顏色,圓角)和圖片樣式(圓角)
本文鏈接:https://blog.csdn.net/weixin_37577039/article/details/79090433
```
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/colorAccent" />
<!-- 這里是設置為四周 也可以單獨設置某個位置為圓角-->
<corners android:topLeftRadius="5dp"
android:topRightRadius="5dp"
android:bottomRightRadius="5dp"
android:bottomLeftRadius="5dp"/>
<stroke android:width="1dp" android:color="#000000" />
</shape
```
```
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 邊框顏色值 -->
<item>
<shape>
<solid android:color="#3bbaff" />
</shape>
</item>
<!--這個是按鈕邊框設置為四周 並且寬度為1-->
<item
android:right="1dp"
android:left="1dp"
android:top="1dp"
android:bottom="1dp">
<shape>
<!--這個是背景顏色-->
<solid android:color="#ffffff" />
<!--這個是按鈕中的字體與按鈕內的四周邊距-->
<padding android:bottom="10dp"
android:left="10dp"
android:right="10dp"
android:top="10dp" />
</shape>
</item>
</layer-list>
```
使用:
```android:background="@drawable/button_edge"```
```
<?xml version="1.0" encoding="UTF-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- 填充的顏色 -->
<solid android:color="#FFFFFF" />
<!-- android:radius 弧形的半徑 -->
<!-- 設置按鈕的四個角為弧形 -->
<corners
android:radius="5dip" />
<!--也可單獨設置-->
<!-- <corners -->
<!-- android:topLeftRadius="10dp"-->
<!-- android:topRightRadius="10dp"-->
<!-- android:bottomRightRadius="10dp"-->
<!-- android:bottomLeftRadius="10dp"-->
<!-- /> -->
**設置文字padding**
<!-- padding:Button裡面的文字與Button邊界的間隔 -->
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp"
/>
</shape>
```
```
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF" />
<corners android:topLeftRadius="10dp"
android:topRightRadius="10dp"
android:bottomRightRadius="10dp"
android:bottomLeftRadius="10dp"/>
</shape>
```
使用:
```
android:background="@drawable/image_circle"
```
```
Glide.with(MainActivity.this).load(croppedUri)
.transform(new GlideRectRound(MainActivity.this,6)).into(headIcon);
```
```
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.Log;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
/**
* Created by SiHao on 2018/3/3.
* Glide 的 圓角 圖片 工具類
*/
public class GlideRectRound extends BitmapTransformation {
private static float radius = 0f;
// 構造方法1 無傳入圓角度數 設置默認值為5
public GlideRectRound(Context context) {
this(context, 5);
}
// 構造方法2 傳入圓角度數
public GlideRectRound(Context context, int dp) {
super(context);
// 設置圓角度數
radius = Resources.getSystem().getDisplayMetrics().density * dp;
}
// 重寫該方法 返回修改後的Bitmap
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
return rectRoundCrop(pool,toTransform);
}
@Override
public String getId() {
Log.e("getID",getClass().getName() + Math.round(radius));
return getClass().getName() + Math.round(radius); // 四捨五入
}
private Bitmap rectRoundCrop(BitmapPool pool, Bitmap source){
if (source == null) return null;
Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888); // ARGB_4444——代表4x4位ARGB點陣圖,ARGB_8888——代表4x8位ARGB點陣圖
if (result == null) {
result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(result);
Paint paint = new Paint();
// setShader 對圖像進行渲染
// 子類之一 BitmapShader設置Bitmap的變換 TileMode 有CLAMP (取bitmap邊緣的最後一個像素進行擴展),REPEAT(水平地重復整張bitmap)
//MIRROR(和REPEAT類似,但是每次重復的時候,將bitmap進行翻轉)
paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
paint.setAntiAlias(true); // 抗鋸齒
RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());
canvas.drawRoundRect(rectF, radius, radius, paint);
return result;
}
}
```
圓角:
```
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
/**
* Created by SiHao on 2018/3/3.
* Glide圓形圖片工具類
*/
public class GlideCircleBitmap extends BitmapTransformation{
public GlideCircleBitmap(Context context) {
super(context);
}
// 重寫該方法 返回修改後的Bitmap
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
return circleCrop(pool, toTransform);
}
@Override
public String getId() {
return getClass().getName();
}
private static Bitmap circleCrop(BitmapPool pool, Bitmap source) {
if (source == null) return null;
// 邊長取長寬最小值
int size = Math.min(source.getWidth(), source.getHeight());
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;
// TODO this could be acquired from the pool too
Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);
Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);// ARGB_4444——代表4x4位ARGB點陣圖,ARGB_8888——代表4x8位ARGB點陣圖
if (result == null) {
result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(result);
Paint paint = new Paint();
// setShader 對圖像進行渲染
// 子類之一 BitmapShader設置Bitmap的變換 TileMode 有CLAMP (取bitmap邊緣的最後一個像素進行擴展),REPEAT(水平地重復整張bitmap)
//MIRROR(和REPEAT類似,但是每次重復的時候,將bitmap進行翻轉)
paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
paint.setAntiAlias(true);// 抗鋸齒
// 半徑取 size的一半
float r = size / 2f;
canvas.drawCircle(r, r, r, paint);
return result;
}
}
```
```
URL url = new URL(String類型的字元串); //將String類型的字元串轉換為URL格式
holder.UserImage.setImageBitmap(BitmapFactory.decodeStream(url.openStream()));
```
```
//得到資源文件的BitMap
Bitmap image= BitmapFactory.decodeResource(getResources(),R.drawable.dog);
//創建RoundedBitmapDrawable對象
RoundedBitmapDrawable roundImg =RoundedBitmapDrawableFactory.create(getResources(),image);
//抗鋸齒
roundImg.setAntiAlias(true);
//設置圓角半徑
roundImg.setCornerRadius(30);
//設置顯示圖片
imageView.setImageDrawable(roundImg);
```
```
//如果是圓的時候,我們應該把bitmap圖片進行剪切成正方形, 然後再設置圓角半徑為正方形邊長的一半即可
Bitmap image = BitmapFactory.decodeResource(getResources(), R.drawable.dog);
Bitmap bitmap = null;
//將長方形圖片裁剪成正方形圖片
if (image.getWidth() == image.getHeight()) {
bitmap = Bitmap.createBitmap(image, image.getWidth() / 2 - image.getHeight() / 2, 0, image.getHeight(), image.getHeight());
} else {
bitmap = Bitmap.createBitmap(image, 0, image.getHeight() / 2 - image.getWidth() / 2, image.getWidth(), image.getWidth());
}
RoundedBitmapDrawable roundedBitmapDrawable = RoundedBitmapDrawableFactory.create(getResources(), bitmap);
//圓角半徑為正方形邊長的一半
roundedBitmapDrawable.setCornerRadius(bitmap.getWidth() / 2);
//抗鋸齒
roundedBitmapDrawable.setAntiAlias(true);
imageView.setImageDrawable(roundedBitmapDrawable);
```
4. Android圓角背景設置
使用databinding設置圓角背景,代替drawable方式
注意:這個只是設置一個背景,所有圖片的圓角不能使用它,只能是viewGroup或者TextView。
提示:圖片可以使用QMUIRadiusImageView
1、支持view和viewGroup的圓角,邊框、和單個圓角等;
2、app:bgRadius:圓角大小,必須用"@{R.dimen.ui_dp8}"賦值;
3、app:bgSolidColor:設置背景色;
4、app:bgStrokeColor:設置邊框顏色;
5、bgTopLeftRadius:設置左上的圓角;
5. android如何設置Button為圓角
這里為大家介紹如果通過簡單的設置,使界面上的Button圓角
在您的android工程的res目錄下的drawable建立xml配置文件button_shape.xml
在button_shape.xml按照您自己的需求寫入如圖所示的屬性
在button按鈕的屬性中,設置android:background="@drawable/button_shape",這樣就使用了剛剛我們自定義的button_shape.xml資源
6. android 如何重寫imageview 讓圖片有圓角效果
android 自定義圓角ImageView以及鋸齒的處理
看到很多人開發過程中要使用圓角圖片時,解決方法有:
1.重新繪制一張圖片
2.通過布局來配置
3.通過重寫View來實現
其中1,2在這里就不講了,重點講講方法三的實現。
實現一:通過截取畫布一個圓形區域與圖片的相交部分進行繪制,缺點:鋸齒明顯,設置Paint,Canvas抗鋸齒無效。
package com.open.circleimageview.widget;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.Region;
import android.util.AttributeSet;
import android.view.View;
public class CircleImageViewA extends View {
public CircleImageViewA(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public CircleImageViewA(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CircleImageViewA(Context context) {
super(context);
}
private Bitmap bitmap;
private Rect bitmapRect=new Rect();
private PaintFlagsDrawFilter pdf=new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);
private Paint paint = new Paint();
{
paint.setStyle(Paint.Style.STROKE);
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
paint.setAntiAlias(true);// 設置畫筆的鋸齒效果。 true是去除,大家一看效果就明白了
}
private Path mPath=new Path();
public void setImageBitmap(Bitmap bitmap)
{
this.bitmap=bitmap;
}
@Override
protected void onDraw(Canvas canvas) {
if(null==bitmap)
{
return;
}
bitmapRect.set(0, 0, getWidth(), getHeight());
canvas.save();
canvas.setDrawFilter(pdf);
mPath.reset();
canvas.clipPath(mPath); // makes the clip empty
mPath.addCircle(getWidth()/2, getWidth()/2, getHeight()/2, Path.Direction.CCW);
canvas.clipPath(mPath, Region.Op.REPLACE);
canvas.drawBitmap(bitmap, null, bitmapRect, paint);
canvas.restore();
}
}
實現二:通過PorterDuffXfermode 方式(注意要設置硬體加速,否則部分機子無效),優點:鋸齒基本沒有
package com.open.circleimageview.widget;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
public class CircleImageViewB extends View {
public CircleImageViewB(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public CircleImageViewB(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CircleImageViewB(Context context) {
super(context);
init();
}
private Bitmap bitmap;
private Rect bitmapRect=new Rect();
private PaintFlagsDrawFilter pdf=new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);
private Paint paint = new Paint();
{
paint.setStyle(Paint.Style.STROKE);
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
paint.setAntiAlias(true);// 設置畫筆的鋸齒效果。 true是去除,大家一看效果就明白了
}
private Bitmap mDstB=null;
private PorterDuffXfermode xfermode=new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY);
private void init()
{
try {
if(android.os.Build.VERSION.SDK_INT>=11)
{
setLayerType(LAYER_TYPE_SOFTWARE, null);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void setImageBitmap(Bitmap bitmap)
{
this.bitmap=bitmap;
}
private Bitmap makeDst(int w, int h)
{
Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bm);
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
p.setColor(Color.parseColor("#ffffffff"));
c.drawOval(new RectF(0, 0, w, h), p);
return bm;
}
@Override
protected void onDraw(Canvas canvas) {
if(null==bitmap)
{
return;
}
if(null==mDstB)
{
mDstB=makeDst(getWidth(), getHeight());
}
bitmapRect.set(0, 0, getWidth(), getHeight());
canvas.save();
canvas.setDrawFilter(pdf);
canvas.drawBitmap(mDstB, 0, 0, paint);
paint.setXfermode(xfermode);
canvas.drawBitmap(bitmap, null, bitmapRect, paint);
paint.setXfermode(null);
canvas.restore();
}
}
7. android怎麼畫圓角的矩形
如果你是在自定義view的onDraw方法中:
java">RectFrectF=newRectF(100,100,500,500);//先畫一個矩形
Paintpaint=newPaint(Paint.ANTI_ALIAS_FLAG);//創建畫筆
paint.setColor(R.color.colorAccent);//添加畫筆顏色
canvas.drawRoundRect(rectF,30,30,paint);//根據提供的矩形為四個角畫弧線,(其中的數字:第一個表示X軸方向大小,第二個Y軸方向大小。可以改成其他的,你可以自己體驗),最後添加畫筆。
如果你是在布局中直接添加,樓上已經做出方法,我就不舉例了。