标签:
一.概述
圆形图片现在越来越多应用于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库
运行截图:
分割线---------------------------------------------------------------------------------------------------------------------
以上方式虽然能实现图片圆形化,但是都是比较麻烦的,下面介绍一种我最常用的,也是最简单的一个方法
标签:
原文地址:http://www.cnblogs.com/android-zcq/p/5138462.html