点击按钮的动画,点击出现阴影,松开后逐渐扩散到整个按钮

直接继承View实现,属性全部自定义

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!-- 按钮的背景色 -->
    <attr name="back_ground_color" format="color" />
    <!-- 点击的阴影颜色 -->
    <attr name="click_color" format="color" />
    <!-- 文本 -->
    <attr name="text" format="string" />
    <!-- 文本的位置 -->
    <attr name="text_position" format="enum">
        <enum name="left" value="0" />
        <enum name="center" value="1" />
        <enum name="right" value="2" />
    </attr>
    <!-- 文字的大小 -->
    <attr name="text_size" format="dimension" />
    <!-- 文字的颜色 -->
    <attr name="text_color" format="color" />

    <declare-styleable name="click_view">
        <attr name="back_ground_color" />
        <attr name="click_color" />
        <attr name="text" />
        <attr name="text_position" />
        <attr name="text_size" />
        <attr name="text_color" />
    </declare-styleable>

</resources>

具体实现类

package com.sunrui.mysport.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.sunrui.mysport.R;

/**
 * Created by sunrui on 15/9/9.
 * 点击扩散效果的View
 */
public class ClickView extends View {

    /**
     * 背景颜色
     */
    private int background_color;

    /**
     * 点击时的颜色
     */
    private int click_color;

    /**
     * 显示的文本
     */
    private String text;

    /**
     * 文本颜色
     */
    private int text_color;

    /**
     * 文本位置
     * 0 左侧
     * 1 居中
     * 2 右侧
     */
    private int text_position;

    /**
     * 文本大小
     */
    private float text_size;

    /**
     * 控件的宽
     */
    private int width;

    /**
     * 控件的高
     */
    private int height;

    /**
     * 文本区域大小
     */
    private Rect text_area;

    /**
     * 文本画笔
     */
    private Paint text_p;

    /**
     * 背景画笔
     */
    private Paint background_p;

    /**
     * 点击效果的画笔
     */
    private Paint click_p;

    /**
     * 点击阴影的半径
     */
    private float radius;

    /**
     * 阴影部分区域
     */
    private RectF shadow_area;

    public ClickView(Context context) {
        super(context);
    }

    public ClickView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public ClickView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.click_view, 0, 0);
        int n = typedArray.getIndexCount();
        for (int i = 0; i < n; i++) {
            int attr = typedArray.getIndex(i);
            switch (attr) {
                case R.styleable.click_view_back_ground_color:
                    background_color = typedArray.getColor(attr, Color.WHITE);
                    break;
                case R.styleable.click_view_click_color:
                    click_color = typedArray.getColor(attr, Color.GRAY);
                    break;
                case R.styleable.click_view_text:
                    text_area = new Rect();
                    text = typedArray.getString(attr);
                    break;
                case R.styleable.click_view_text_color:
                    text_color = typedArray.getColor(attr, Color.BLACK);
                    break;
                case R.styleable.click_view_text_position:
                    text_position = typedArray.getInt(attr, 1);
                    break;
                case R.styleable.click_view_text_size:
                    text_size = typedArray.getDimension(attr, 32.0f);
                    break;
                default:
                    break;
            }
        }
        background_p = new Paint();
        text_p = new Paint();
        click_p = new Paint();
        shadow_area = new RectF(0, 0, 0, 0);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        width = 0;
        height = 0;
        int specMode = MeasureSpec.getMode(widthMeasureSpec);
        int specSize = MeasureSpec.getSize(widthMeasureSpec);
        switch (specMode) {
            case MeasureSpec.EXACTLY:
                width = getPaddingLeft() + getPaddingRight() + specSize;
                break;
            case MeasureSpec.AT_MOST:
                if (text_area != null) {
                    width = getPaddingLeft() + getPaddingRight() + text_area.width();
                } else {
                    width = getPaddingLeft() + getPaddingRight();
                }
                break;
            default:
                break;
        }
        specMode = MeasureSpec.getMode(heightMeasureSpec);
        specSize = MeasureSpec.getSize(heightMeasureSpec);

        switch (specMode) {
            case MeasureSpec.EXACTLY:
                height = getPaddingTop() + getPaddingBottom() + specSize;
                break;
            case MeasureSpec.AT_MOST:
                if (text_area != null) {
                    height = getPaddingTop() + getPaddingBottom() + text_area.height();
                } else {
                    height = getPaddingTop() + getPaddingBottom();
                }
                break;
            default:
                break;
        }
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {

        //绘制背景
        background_p.setColor(background_color);
        canvas.drawRect(0, 0, width, height, background_p);

        //绘制文字
        text_p.setColor(text_color);
        text_p.setTextSize(text_size);
        float text_x = 0f;
        text_p.getTextBounds(text, 0, text.length(), text_area);
        float text_y = (height + text_area.height()) / 2;
        Log.v("sss", text_y + "===" + height + "===" + text_area.height());
        if (text_position == 0) {
            text_x = 0f;
        } else if (text_position == 1) {
            text_x = (width - text_area.width()) / 2;
            Log.v("sss", width + "===" + text_area.width() + text_area.height());
        } else if (text_position == 2) {
            text_x = width - text_area.width();
        }
        canvas.drawText(text, text_x, text_y, text_p);

        //绘制阴影
        click_p.setColor(click_color);
        canvas.drawArc(shadow_area, 0, 360, false, click_p);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        int action = event.getAction();

        final float click_x = event.getX();

        switch (action) {
            case MotionEvent.ACTION_DOWN:
                radius = height * 1.5f;
                shadow_area = new RectF(click_x - radius / 2, (height - radius) / 2, click_x + radius / 2, (height + radius) / 2);
                postInvalidate();
                break;
            case MotionEvent.ACTION_UP:
                new Thread() {
                    @Override
                    public void run() {
                        while (true) {
                            if (radius > width * 2.0f) {
                                break;
                            }
                            radius += width / 18;
                            shadow_area = new RectF(click_x - radius / 2, (height - radius) / 2, click_x + radius / 2, (height + radius) / 2);
                            try {
                                Thread.sleep(300/18);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            postInvalidate();
                        }
                        shadow_area = new RectF(0, 0, 0, 0);
                    }
                }.start();

                break;
            default:
                break;
        }

        return true;
    }

}

布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.sunrui.mysport.ui.AddSportItemActivity">

    <com.sunrui.mysport.widget.ClickView
        android:layout_width="match_parent"
        android:layout_height="48dp"
        custom:back_ground_color="#ffffff"
        custom:click_color="#33000000"
        custom:text="点击测试"
        custom:text_position="center"
        custom:text_size="32px"
        custom:text_color="#00ff00"/>

</RelativeLayout>

如果不是在Android studio中,将第二行的res-auto改成包名

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值