概述
在之前的博客Android Drawable(一)之ShapeDrawable 和 Android Drawable(二)中主要講解了Android中常見的Drawable的使用方法,今天在這裏主要講解一下如何通過自定義Drawable實現圓角和圓形圖片。
在Android開發中,我們經常通過使用自定義控件來完成一些UI效果而很少使用自定義Drawable,主要原因是自定義Drawable無法在xml文件中使用。Drawable一般都是作爲View的背景顯示出來,在View顯示Drawable時,主要就是通過調用Drawable類的draw(canvas)方法實現。
自定義Drawable
自定義圓形圖片
package com.zhangke.drawabledemo2;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
/**
* Created by zhangke on 2016/10/29.
*/
public class CircleDrawable extends Drawable {
/**
* 顯示圖片
*/
private Bitmap mBitmap;
/**
* BitmapShader
*/
private BitmapShader mBitmapShader;
/**
* 畫筆
*/
private Paint mPaint;
/**
* 圓心
*/
private float cx, cy;
/**
* 半徑
*/
private float radius;
private int size;
public CircleDrawable(Bitmap bitmap) {
this.mBitmap = bitmap;
mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setShader(mBitmapShader);
size = Math.min(bitmap.getWidth(), bitmap.getHeight());
cx = size / 2;
cy = size / 2;
radius = size / 2;
}
@Override
public void draw(Canvas canvas) {
canvas.drawCircle(cx, cy, radius, mPaint);
}
@Override
public int getIntrinsicHeight() {
return size;
}
@Override
public int getIntrinsicWidth() {
return size;
}
@Override
public void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
mPaint.setColorFilter(colorFilter);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
}
自定義圓角圖片
package com.zhangke.drawabledemo2;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
/**
* Created by zhangke on 2016/10/29.
*/
public class RoundDrawable extends Drawable {
/**
* 顯示圖片
*/
private Bitmap mBitmap;
/**
* BitmapShader
*/
private BitmapShader mBitmapShader;
/**
* 畫筆
*/
private Paint mPaint;
private RectF rectF;
public RoundDrawable(Bitmap bitmap) {
this.mBitmap = bitmap;
mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setShader(mBitmapShader);
}
@Override
public void setBounds(int left, int top, int right, int bottom) {
super.setBounds(left, top, right, bottom);
rectF = new RectF(left, top, right, bottom);
}
@Override
public void draw(Canvas canvas) {
canvas.drawRoundRect(rectF, 100, 100 ,mPaint);
}
@Override
public int getIntrinsicHeight() {
return mBitmap.getHeight();
}
@Override
public int getIntrinsicWidth() {
return mBitmap.getWidth();
}
@Override
public void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
mPaint.setColorFilter(colorFilter);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
}
在自定義Drawable時,默認需要複寫draw、setAlpha、setColorFilter、getOpacity四個方法,其中最核心的方法就是draw方法了。
在通常情況下,還需要實現getIntrinsicHeight和getIntrinsicWidth方法,這兩個方法返回的是drawable的大小,如果我們不重寫這兩個方法,drawable是不會被繪製出來,因爲這兩個方法默認的返回值是-1。
使用自定義drawable
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.zhangke.drawabledemo2.MainActivity">
<ImageView
android:id="@+id/imageview1"
android:background="#dca098"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/imageview2"
android:layout_width="wrap_content"
android:background="#98d1dc"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/imageview3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#e7b3d8"/>
</LinearLayout>
ImageView imageView1 = (ImageView) findViewById(R.id.imageview1);
Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.d1);
ImageView imageView2 = (ImageView) findViewById(R.id.imageview2);
Bitmap bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.d2);
ImageView imageView3 = (ImageView) findViewById(R.id.imageview3);
Bitmap bitmap3 = BitmapFactory.decodeResource(getResources(), R.drawable.d3);
imageView1.setImageDrawable(new CircleDrawable(bitmap1));
imageView2.setImageDrawable(new CircleDrawable(bitmap2));
imageView3.setImageDrawable(new CircleDrawable(bitmap3));
// imageView1.setImageDrawable(new RoundDrawable(bitmap1));
// imageView2.setImageDrawable(new RoundDrawable(bitmap2));
// imageView3.setImageDrawable(new RoundDrawable(bitmap3));
圓形圖片效果圖:
圓角圖片效果圖: