模仿 Android支付宝咻一咻功能实现

932人阅读 评论(2) 收藏 举报
分类:

下午无聊,之前本来一直想仿写支付宝的咻一咻功能

首先上效果图


然后创建一个自定义的 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>




这样就大功告成!

我也是参考大侠写的!

咻一咻



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:263838次
    • 积分:4151
    • 等级:
    • 排名:第7434名
    • 原创:154篇
    • 转载:21篇
    • 译文:0篇
    • 评论:180条
    博客专栏
    欢迎加入QQ群