Android实现圆形图片
一.概述
圆形图片现在越来越多应用于Android应用中, 但是用的最多的地方当属于, 头像的显示. 比如QQ, 新浪微博,微信中很多地方都是用了圆形头像,所以有必要深究一下.
二.圆形图片的实现方式
1.使用自定义控件
2.使用第三方库
下面先说第1种, 自定义控件
package com.example.kun.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.widget.ImageView;
import com.example.kun.R;
/**
* 自定义圆形图片
*/
public class RoundAngleImageView extends ImageView {
//定义2个画笔
private Paint paint;
private Paint paint2;
private int roundWidth = 5;
private int roundHeight = 5;
//以下是必须实现的构造方法
public RoundAngleImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
public RoundAngleImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public RoundAngleImageView(Context context) {
super(context);
init(context, null);
}
private void init(Context context, AttributeSet attrs) {
if (attrs != null) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundAngleImageView);
//根据像素赋值
roundWidth = a.getDimensionPixelSize(R.styleable.RoundAngleImageView_roundWidth, roundWidth);
roundHeight = a.getDimensionPixelSize(R.styleable.RoundAngleImageView_roundHeight, roundHeight);
} else {
//根据设备密度计算
float density = context.getResources().getDisplayMetrics().density;
roundWidth = (int) (roundWidth * density);
roundHeight = (int) (roundHeight * density);
}
paint = new Paint();
paint.setColor(Color.WHITE);
paint.setAntiAlias(true);//设置图片抗锯齿,就是设置图片边缘锯齿感 不明显
//设置2张图片相交的模式, 圆形覆盖 方形
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
paint2 = new Paint();
paint2.setXfermode(null);
}
@Override
public void draw(Canvas canvas) {
Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Config.ARGB_8888);
Canvas canvas2 = new Canvas(bitmap);
super.draw(canvas2);
drawLiftUp(canvas2);
drawRightUp(canvas2);
drawLiftDown(canvas2);
drawRightDown(canvas2);
canvas.drawBitmap(bitmap, 0, 0, paint2);
bitmap.recycle();
}
private void drawLiftUp(Canvas canvas) {
Path path = new Path();
path.moveTo(0, roundHeight);
path.lineTo(0, 0);
path.lineTo(roundWidth, 0);
path.arcTo(new RectF(
0,
0,
roundWidth * 2,
roundHeight * 2),
-90,
-90);
path.close();
canvas.drawPath(path, paint);
}
private void drawLiftDown(Canvas canvas) {
Path path = new Path();
path.moveTo(0, getHeight() - roundHeight);
path.lineTo(0, getHeight());
path.lineTo(roundWidth, getHeight());
path.arcTo(new RectF(
0,
getHeight() - roundHeight * 2,
0 + roundWidth * 2,
getHeight()),
90,
90);
path.close();
canvas.drawPath(path, paint);
}
private void drawRightDown(Canvas canvas) {
Path path = new Path();
path.moveTo(getWidth() - roundWidth, getHeight());
path.lineTo(getWidth(), getHeight());
path.lineTo(getWidth(), getHeight() - roundHeight);
path.arcTo(new RectF(
getWidth() - roundWidth * 2,
getHeight() - roundHeight * 2,
getWidth(),
getHeight()), 0, 90);
path.close();
canvas.drawPath(path, paint);
}
private void drawRightUp(Canvas canvas) {
Path path = new Path();
path.moveTo(getWidth(), roundHeight);
path.lineTo(getWidth(), 0);
path.lineTo(getWidth() - roundWidth, 0);
path.arcTo(new RectF(
getWidth() - roundWidth * 2,
0,
getWidth(),
0 + roundHeight * 2),
-90,
90);
path.close();
canvas.drawPath(path, paint);
}
}
对应的attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="RoundAngleImageView">
<attr name="roundWidth" format="dimension" />
<attr name="roundHeight" format="dimension" />
</declare-styleable>
</resources>
布局文件:
<com.example.kun.widget.RoundAngleImageView
android:id="@+id/photoView"
android:src="@mipmap/temp"
app:roundHeight="100dp"
app:roundWidth="100dp"
android:scaleType="fitXY"
android:layout_width="200dp"
android:layout_height="200dp" />
布局需要注意: 自定义属性必须要有,并且宽高必须为 layout_width和layout_height的一半
还有一点注意:
android:scaleType="fitXY"这个属性必须要有,否则不会实现图片圆形
java代码如下:
public class MainActivity extends AppCompatActivity {
private RoundAngleImageView photoView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initialize();
}
private void initialize() {
photoView = (RoundAngleImageView) findViewById(R.id.photoView);
}
}
运行效果图:
以上的自定义控件多少还是有些麻烦的 ,下面搞一个稍微简单点的工具类
public class CircleTransform extends BitmapTransformation {
public CircleTransform(Context context) {
super(context);
}
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
return circleCrop(pool, toTransform);
}
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;
Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);
Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
if (result == null) {
result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(result);
Paint paint = new Paint();
paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
paint.setAntiAlias(true);
float r = size / 2f;
canvas.drawCircle(r, r, r, paint);
return result;
}
@Override
public String getId() {
return getClass().getName();
}
}
布局如下:
<?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"
android:orientation="vertical"
android:layout_width="match_parent"
android:gravity="center"
android:layout_height="match_parent">
<ImageView
android:scaleType="fitXY"
android:id="@+id/photoView"
android:layout_width="100dp"
android:layout_height="100dp" />
</LinearLayout>
java代码:
public class MainActivity extends AppCompatActivity {
private ImageView photoView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initialize();
runOnUiThread(new Runnable() {
@Override
public void run() {
Glide.with(MainActivity.this).load(Uri.parse("http://pic13.nipic.com/20110415/1347158_132411659346_2.jpg"))
.transform(new CircleTransform(MainActivity.this))
.placeholder(R.mipmap.ic_launcher)
.error(R.mipmap.ic_launcher)
.into(photoView);
}
});
}
private void initialize() {
photoView = (ImageView) findViewById(R.id.photoView);
}
}
以上代码使用GLide加载图片,需要引入glide库
运行截图:
分割线——————————————————————————————————————————————————————————-
以上方式虽然能实现图片圆形化,但是都是比较麻烦的,下面介绍一种我最常用的,也是最简单的一个方法
CircleImageView
github//github.com/hdodenhof/CircleImageView
直接上代码
<?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"
android:orientation="vertical"
android:layout_width="match_parent"
android:gravity="center"
android:layout_height="match_parent">
<!--加入了边框宽度和颜色-->
<de.hdodenhof.circleimageview.CircleImageView
app:civ_border_width="2dp"
app:civ_border_color="#FFFFFF"
android:id="@+id/photoView"
android:src="@mipmap/ic_launcher"
android:layout_width="100dp"
android:layout_height="100dp" />
</LinearLayout>
public class MainActivity extends AppCompatActivity {
private CircleImageView photoView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initialize();
Picasso.with(this).load(R.mipmap.temp).into(photoView);
}
private void initialize() {
photoView = (CircleImageView) findViewById(R.id.photoView);
}
}
引入的库文件
compile 'de.hdodenhof:circleimageview:2.0.0'
compile 'com.squareup.picasso:picasso:2.5.2'
运行截图:最外层带有一个白色边框
转载于//www.cnblogs.com/android-zcq/p/5138462.html
还没有评论,来说两句吧...