实现类:RippleView.class
public class RippleView extends View {
private String TAG = RippleView.this.getClass().getSimpleName();
private CircleInfo circleInfo;
private Context context;
private boolean isStartAnim = false;
private boolean isDrawSecond = false;
private float first_r,second_r;
private int first_s = 255, second_s = 255;
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
invalidate();
Log.d("xsl","invalidate()");
if (isStartAnim) {
first_r += 2;
if (first_r > circleInfo.radius * 2) {
first_r = circleInfo.radius/1.4f;
}
if (isDrawSecond) {
second_r += 2;
if (second_r > circleInfo.radius * 2) {
second_r = circleInfo.radius/1.4f;
}
}
first_s = (int) (255 * (1 - first_r / (circleInfo.radius * 2)));
second_s = (int) (255 * (1 - second_r / (circleInfo.radius * 2)));
sendEmptyMessageDelayed(0, 20);
}
}
};
public RippleView(Context context,CircleInfo circleInfo) {
super(context);
this.context = context;
this.circleInfo = circleInfo;
first_r = circleInfo.radius;
second_r = circleInfo.radius;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.TRANSPARENT);
// canvas.drawARGB(128, 255, 0, 0);
// 创建一个画实体圆的画笔
Paint paintFull = new Paint();
// 设置画笔风格
paintFull.setStyle(Paint.Style.FILL);// STROKE:线条 FILL:填充
paintFull.setColor(circleInfo.fullColor);
paintFull.setAlpha(first_s);
// 打开抗锯齿
paintFull.setAntiAlias(true);
canvas.drawCircle(circleInfo.x, circleInfo.y, first_r, paintFull);
Paint paintHollow = new Paint();
paintHollow.setStyle(Paint.Style.STROKE);
paintHollow.setStrokeWidth(circleInfo.width);
paintHollow.setColor(circleInfo.hollowColor);
paintHollow.setAlpha(first_s);
paintHollow.setAntiAlias(true);
canvas.drawCircle(circleInfo.x, circleInfo.y, first_r, paintHollow);
Log.d("xsl", "first::" + circleInfo.x + "\t" + circleInfo.y + "\t" + (first_r+circleInfo.width)+ "\t" + circleInfo.hollowColor);
if (first_r > circleInfo.radius *1.4){
isDrawSecond = true;
}
if (isDrawSecond){
Paint paintFull_2 = new Paint();
// 设置画笔风格
paintFull_2.setStyle(Paint.Style.FILL);// STROKE:线条 FILL:填充
paintFull_2.setColor(circleInfo.fullColor);
paintFull_2.setAlpha(second_s);
// 打开抗锯齿
paintFull_2.setAntiAlias(true);
canvas.drawCircle(circleInfo.x, circleInfo.y, second_r, paintFull_2);
Paint paintHollow_2 = new Paint();
paintHollow_2.setStyle(Paint.Style.STROKE);
paintHollow_2.setStrokeWidth(circleInfo.width);
paintHollow_2.setColor(circleInfo.hollowColor);
paintHollow_2.setAlpha(second_s);
paintHollow_2.setAntiAlias(true);
canvas.drawCircle(circleInfo.x, circleInfo.y, second_r, paintHollow_2);
Log.d("xsl", "second::" + circleInfo.x + "\t" + circleInfo.y + "\t" + (second_r+circleInfo.width)+ "\t" + circleInfo.hollowColor);
}
}
public void startRipple(){
// final Animation animation = AnimationUtils.loadAnimation(context,R.anim.speech_anim);
// this.startAnimation(animation);
isStartAnim = true;
handler.sendEmptyMessage(0);
}
public void stopRipple(){
this.clearAnimation();
isDrawSecond = false;
isStartAnim = false;
}
public static class CircleInfo{
private float x; // 圆心横坐标
private float y; // 圆心纵坐标
private float radius; // 半径
private int fullColor; // 实体圆颜色
private int hollowColor; // 圆圈颜色
private float width; // 边缘宽度
public float getX()
{
return x;
}
public void setX(float x)
{
this.x = x;
}
public float getY()
{
return y;
}
public void setY(float y)
{
this.y = y;
}
public float getRadius()
{
return radius;
}
public void setRadius(float radius)
{
this.radius = radius;
}
public int getFullColor()
{
return fullColor;
}
public void setFullColor(int fullColor)
{
this.fullColor = fullColor;
}
public void setHollowColor(int hollowColor){
this.hollowColor = hollowColor;
}
public int getHollowColor(){
return hollowColor;
}
public void setWidth(float width){
this.width = width;
}
public float getWidth(){
return width;
}
}
}
xml布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/rela"
tools:context="com.cc.xushuailong.mynewbutton.MainActivity">
<Button
android:background="@drawable/btn_selector"
android:layout_centerInParent="true"
android:id="@+id/btn_selecter"
android:layout_width="100dp"
android:layout_height="100dp"/>
</RelativeLayout>
selector选择器:btn_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/btn_down" android:state_pressed="true"/>
<item android:drawable="@drawable/btn_nomal"/>
</selector>
引用的主Activity:
public class MainActivity extends Activity implements View.OnTouchListener {
private RippleView rippleView;
private RelativeLayout layout;
private final RippleView.CircleInfo info = new RippleView.CircleInfo();
private Button btn_speech;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
viewEvents();
}
private void viewEvents() {
btn_speech.setOnTouchListener(this);
}
private void initViews() {
layout = (RelativeLayout) findViewById(R.id.rela);
btn_speech = (Button) findViewById(R.id.btn_selecter);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (v.getId()) {
case R.id.btn_selecter:{
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
float v_center_x = v.getWidth()/2 + v.getLeft();
float v_center_y = v.getHeight()/2 + v.getTop();
info.setX(v_center_x);
info.setY(v_center_y);
info.setRadius(v.getHeight() / 2);
info.setWidth(4);
info.setFullColor(0xffdaa520);
info.setHollowColor(0xffb8860b);
rippleView = new RippleView(MainActivity.this,info);
layout.addView(rippleView);
layout.bringChildToFront(btn_speech);
rippleView.startRipple();
Log.d("xsl", "btn_selecter: down !");
Log.d("xsl","v_x: "+v_center_x+"\tv_y: "+v_center_y);
break;
}
case MotionEvent.ACTION_MOVE: {
break;
}
case MotionEvent.ACTION_UP: {
Log.d("xsl", "btn_selecter: up !");
rippleView.stopRipple();
layout.removeView(rippleView);
break;
}
}
break;
}
}
return super.onTouchEvent(event);
}
}
实现效果:
ps:自定义view没有设置可配的attribute属性,可扩展性及重用性有待提高,另外没有上传按钮图片。。。。