下午无聊,之前本来一直想仿写支付宝的咻一咻功能
首先上效果图
然后创建一个自定义的 RounImageView 继承ImageView
package com.android.xiong.gridlayoutTest.customeview;
import com.android.xiong.gridlayoutTest.R;
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.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.util.AttributeSet;
import android.widget.ImageView;
public class RounImageView extends ImageView {
private int mBorderThickness = 0;
private int defaultColor = 0xFFFFFFFF;
// 如果只有其中一个有值,则只画一个圆形边框
private int mBorderOutsideColor = 0;
private int mBorderInsideColor = 0;
// 控件默认长、宽
private int defaultWidth = 0;
private int defaultHeight = 0;
private Context mContext;
public RounImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// 初始化View
mContext = context;
setCustomeAttributes(attrs);
}
public RounImageView(Context context, AttributeSet attrs) {
super(context, attrs);
//初始化View
mContext = context;
setCustomeAttributes(attrs);
}
public RounImageView(Context context) {
super(context);
mContext = context;
// TODO Auto-generated constructor stub
}
private void setCustomeAttributes(AttributeSet attrs) {
// 自定义属性
TypedArray mArray = mContext.obtainStyledAttributes(attrs,
R.styleable.roundedimageview);
mBorderThickness = mArray.getDimensionPixelSize(
R.styleable.roundedimageview_border_thickness, 0);
mBorderOutsideColor = mArray
.getColor(R.styleable.roundedimageview_border_outside_color,
defaultColor);
mBorderInsideColor = mArray.getColor(
R.styleable.roundedimageview_border_inside_color, defaultColor);
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
Drawable drawable=getDrawable();
if(drawable==null){
return;
}
if(getWidth()==0||getHeight()==0){
return ;
}
this.measure(0, 0);
if(drawable.getClass()==NinePatchDrawable.class){
return;
}
Bitmap bitmap=((BitmapDrawable)drawable).getBitmap();
Bitmap bitmap2=bitmap.copy(Config.ARGB_8888, true);
if(defaultWidth==0){
defaultWidth=getWidth();
}
if(defaultHeight==0){
defaultHeight=getHeight();
}
int radius=0;
if(mBorderInsideColor!=defaultColor&&mBorderOutsideColor!=defaultColor){
radius=(defaultWidth<defaultHeight?defaultWidth:defaultHeight)/2-2*mBorderThickness;
//画内圆
drawCircelBorder(canvas,radius+mBorderThickness/2,mBorderInsideColor);
//画外圆
drawCircelBorder(canvas,radius+mBorderThickness+mBorderOutsideColor/2,mBorderOutsideColor);
}else if(mBorderInsideColor!=defaultColor&&mBorderOutsideColor==defaultColor){
//定义一个画框
radius=(defaultWidth<defaultHeight?defaultWidth:defaultHeight)/2-mBorderThickness;
drawCircelBorder(canvas,radius+mBorderThickness/2,mBorderOutsideColor);
}else{
//没有边框
radius=(defaultWidth>defaultHeight?defaultWidth:defaultHeight)/2;
Bitmap boundBitmap=getCroppedRoundBitmap(bitmap2,radius);
canvas.drawBitmap(boundBitmap, defaultWidth/2-radius, defaultHeight/2-radius, null);
}
}
/**
* 裁剪后的圆形图片
* @param bitmap2
* @param radius
* @return
*/
private Bitmap getCroppedRoundBitmap(Bitmap bitmap2, int radius) {
// TODO Auto-generated method stub
Bitmap scaledSrcmp;
//直径
int diameter=radius*2;
//为了防止不等高,图片变形截取长方形中间位置的最的正方形图片
int bitWidth=bitmap2.getWidth();
int bitHeight=bitmap2.getHeight();
int squareWidth=0,squareHeight=0;
int a,b=0;
Bitmap squareBitmap;
//如果高大于宽最多等于宽
if(bitHeight>bitWidth){
squareWidth=squareHeight=bitWidth;
a=0;
b=(bitHeight-bitWidth)/2;
//截取正方形图片
squareBitmap=Bitmap.createBitmap(bitmap2, a, b, squareWidth, squareHeight);
//否则宽小于高最多等于高
}else if(bitHeight<bitWidth){
squareWidth=squareHeight=bitHeight;
a=(bitWidth-bitHeight)/2;
b=0;
squareBitmap=Bitmap.createBitmap(bitmap2, a, b, squareWidth, squareHeight);
}else{
squareBitmap=bitmap2;
}
if(squareBitmap.getWidth()!=diameter||squareBitmap.getHeight()!=diameter){
scaledSrcmp=Bitmap.createScaledBitmap(squareBitmap, diameter, diameter, true);
}else{
scaledSrcmp=squareBitmap;
}
Bitmap output=Bitmap.createBitmap(scaledSrcmp.getWidth(), scaledSrcmp.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas=new Canvas(output);
Paint paint=new Paint();
Rect rect=new Rect(0,0,scaledSrcmp.getWidth(), scaledSrcmp.getHeight());
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
canvas.drawCircle(scaledSrcmp.getWidth()/2, scaledSrcmp.getHeight()/2, scaledSrcmp.getWidth()/2, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(scaledSrcmp, rect, rect, paint);
bitmap2=null;
squareBitmap=null;
scaledSrcmp=null;
return output;
}
/**
* 边缘画圆
* @param canvas
* @param i
* @param mBorderOutsideColor2
*/
private void drawCircelBorder(Canvas canvas, int i, int mBorderOutsideColor2) {
// TODO Auto-generated method stub
Paint paint=new Paint();
/**去锯齿**/
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
paint.setColor(mBorderOutsideColor2);
/*设置paint为空心*/
paint.setStyle(Paint.Style.STROKE);
/*设置paint外框宽度*/
paint.setStrokeWidth(mBorderThickness);
canvas.drawCircle(defaultWidth/2, defaultHeight/2, i, paint);
}
}
然后创建自定义的水波纹效果
package com.android.xiong.gridlayoutTest.customeview;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
public class WhewView extends View {
private Paint paint;
private int maxWidth = 255;
// 是否运行
private boolean isStarting = false;
private List<String> alphaList = new ArrayList<String>();
private List<String> startWidthList = new ArrayList<String>();
public WhewView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// TODO Auto-generated constructor stub
init();
}
public WhewView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
init();
}点击打开链接
public WhewView(Context context) {
super(context);
// TODO Auto-generated constructor stub
init();
}
private void init() {
paint = new Paint();
// 设置博文的颜色
paint.setColor(0x0059ccf5);
alphaList.add("255");// 圆心的不透明度
startWidthList.add("0");
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
setBackgroundColor(Color.TRANSPARENT);// 颜色:完全透明
// 依次绘制 同心圆
for (int i = 0; i < alphaList.size(); i++) {
int alpha = Integer.parseInt(alphaList.get(i));
// 圆半径
int startWidth = Integer.parseInt(startWidthList.get(i));
paint.setAlpha(alpha);
// 这个半径决定你想要多大的扩散面积
canvas.drawCircle(getWidth() / 2, getHeight() / 2, startWidth + 50,
paint);
// 同心圆扩散
if (isStarting && alpha > 0 && startWidth < maxWidth) {
alphaList.set(i, (alpha - 1) + "");
startWidthList.set(i, (startWidth + 1) + "");
}
}
if (isStarting
&& Integer
.parseInt(startWidthList.get(startWidthList.size() - 1)) == maxWidth / 5) {
alphaList.add("255");
startWidthList.add("0");
}
// 同心圆数量达到10个,删除最外层圆
if (isStarting && startWidthList.size() == 10) {
startWidthList.remove(0);
alphaList.remove(0);
}
// 刷新界面
invalidate();
}
// 执行动画
public void start() {
isStarting = true;
}
// 停止动画
public void stop() {
isStarting = false;
}
// 判断是都在不在执行
public boolean isStarting() {
return isStarting;
}
}
然后创建布局文件
activity_
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:imagecontrol="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<!--这里改成你自己的包名-->
<com.android.xiong.gridlayoutTest.customeview.WhewView
android:id="@+id/wv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.android.xiong.gridlayoutTest.customeview.RounImageView
android:id="@+id/my_photo"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerInParent="true"
android:src="@drawable/myphoto"
imagecontrol:border_inside_color="#bc0978"
imagecontrol:border_outside_color="#ba3456"
imagecontrol:border_thickness="1dp" />
</RelativeLayout>
</LinearLayout>
最后创建一个活动窗口TestXActivity
package com.android.xiong.gridlayoutTest;
import com.android.xiong.gridlayoutTest.customeview.RounImageView;
import com.android.xiong.gridlayoutTest.customeview.WhewView;
import android.app.Activity;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
public class TestXActivity extends Activity {
private WhewView wv;
private RounImageView my_photo;
private static final int Nou = 1;
// 声明一个SoundPool
private SoundPool sp;
// 定义一个整型用load();来设置suondIDf
private int music;
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == Nou) {
// 每隔10s响一次
handler.sendEmptyMessageDelayed(Nou, 5000);
sp.play(music, 1, 1, 0, 0, 1);
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_roundimageview);
initView();
}
private void initView() {
// 第一个参数为同时播放数据流的最大个数,第二数据流类型,第三为声音质量
sp = new SoundPool(10, AudioManager.STREAM_SYSTEM, 5);
// 把你的声音素材放到res/raw里,第2个参数即为资源文件,第3个为音乐的优先级
music = sp.load(this, R.raw.hongbao_gq, 1);
wv = (WhewView) findViewById(R.id.wv);
my_photo = (RounImageView) findViewById(R.id.my_photo);
my_photo.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(wv.isStarting()){
//如果动画正在运行就停止,否则就继续执行
wv.stop();
//结束进程
handler.removeMessages(Nou);
}else{
// 执行动画
wv.start();
handler.sendEmptyMessage(Nou);
}
}
});
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
handler.removeMessages(Nou);
}
}
最后在values下面atts.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="roundedimageview">
<attr name="border_thickness" format="dimension" />
<attr name="border_inside_color" format="color" />
<attr name="border_outside_color" format="color"></attr>
</declare-styleable>
</resources>
这样就大功告成!
我也是参考大侠写的!