自定义图形以及点击效果

本文介绍了一种通过自定义View实现在Android应用中动态改变图形颜色的方法,避免了为每种颜色状态创建单独的XML文件。自定义View支持设置文本、尺寸及颜色等属性,并能在点击时更改边框。

我们在项目中常常有使用到某个图形的点击效果,例如点击加边框,通常的做法通过自定义shape的xml 来实现效果,但是自定义的shape 无法很方便的控制图形的内部颜色,当需要动态改变改变颜色的时候,就需要定义多个shape的xml.例如:

这里写图片描述

对于这样的就只需要一个shape 就可以了,但是内部的颜色有5中呢?那就需要再写5个xml ,20中呢?50+呢,

这里写图片描述

里面唯一的不同就是颜色,代码显示很累赘。所以就想到是否有办法通过自定义的图形来控制形状和颜色。

下面是效果图:

这里写图片描述

1、自定义View的样式,首先在res/values/ style.xml

<!-- 自定义圆形的样式-->
    <declare-styleable name="CustomCircleView">
        <attr name="topText" />
        <attr name="titleTextSize" />
        <attr name="circleRadius" />
    </declare-styleable>

2、自定义View的属性,在res/values/ attrs.xml

<!--自定义圆形的属性-->
    <attr name="topText" format="string" />
    <attr name="titleTextSize" format="dimension" />
    <attr name="circleRadius" format="dimension" />

format的属性一共有:
string,color,demension,integer,enum,reference,float,boolean,fraction,flag

3、在对应的xml 下使用自定义的view

<RelativeLayout
                android:id="@+id/percent_25_layout"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content">

            <com.test.view.CustomCircleView
                    android:id="@+id/percent_25_bg"
                    android:layout_width="67dp"
                    android:layout_height="67dp"
                    app:topText="25%"
                    app:circleRadius="32dp"
                    app:titleTextSize="17sp"
                    android:layout_centerInParent="true"/>
        </RelativeLayout>

主意顶部要加上自定义的命名空间
xmlns:app=”http://schemas.android.com/apk/res-auto”
需要不同的字体,以及圆的大小都可以在xml 内部设置,当然可以增加一个rgb 颜色值得属性,在xml 中就初始化好当前的颜色值,有兴趣的可以试试.

4、下面就是自定义的view 的构造函数

/**
 * 自定义的圆形的view
 * lh on 2016/1/6.
 */
public class CustomCircleView extends View{
   .......
   .......

   public CustomCircleView(Context context, AttributeSet attrs){
        this(context, attrs, 0);
    }

    public CustomCircleView(Context context){
        this(context, null);
    }

    /
    **
     * 获得自定义的样式属性
     * @param context  上下文
     * @param attrs    属性
     * @param defStyle 默认的样式
     */
    public CustomCircleView(Context context, AttributeSet attrs, int defStyle){
        super(context, attrs, defStyle);

        //获得所定义的自定义样式属性
        TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomCircleView, defStyle, 0);
        int arrayIndexCount = array.getIndexCount();
        for(int i=0;i<arrayIndexCount;i++){
            int attr = array.getIndex(i);
            switch (attr){
                case R.styleable.CustomCircleView_topText:
                    mTopText = array.getString(attr);
                    break;
                case R.styleable.CustomCircleView_titleTextSize:
                    mTextSize = array.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
                            TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
                    break;
                case R.styleable.CustomCircleView_circleRadius:
                    mCircleRadius = array.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
                            TypedValue.COMPLEX_UNIT_DIP, 60, getResources().getDisplayMetrics()));
                    break;
            }
        }
        array.recycle();

        strokePaint = new Paint();
        strokePaint.setAntiAlias(true);

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setARGB(255,0,0,0);

        //获得绘制文本的宽和高
        mPaint.setTextSize(mTextSize);
        mBound = new Rect();
        mPaint.getTextBounds(mTopText, 0, mTopText.length(), mBound);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //画圆
        mPaint.setARGB(255, rgbColor[0], rgbColor[1], rgbColor[2]);
        canvas.drawCircle(getWidth()/2,getHeight()/2,mCircleRadius,mPaint);

        if(viewSelected){
            //边框
            strokePaint.setColor(Color.WHITE);
            if(!mDefaultStrokeColor){
                strokePaint.setColor(Color.BLACK);
            }
            strokePaint.setStrokeWidth(3);
            strokePaint.setStyle(Paint.Style.STROKE);
            canvas.drawCircle(getWidth()/2, getHeight()/2, mCircleRadius-1, strokePaint);
        }

        //绘制文本内容
        mPaint.setColor(Color.WHITE);
        if(!mDefaultStrokeColor) {
            mPaint.setColor(Color.BLACK);
        }

        mPaint.setTextSize(mTextSize);
        canvas.drawText(mTopText, getWidth()/2 - mBound.width()/2, getHeight()/2 + mBound.height()/2, mPaint);
    }

注意点:

array.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 60, getResources().getDisplayMetrics()));

array.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));

format=”dimension” 的属性是dimension,会将sp和dp 转化为具体的数值

5、然后就是控制点击变色的部分

public void setViewSelected(boolean selected){
        if(viewSelected != selected){
            postInvalidate();
        }
        viewSelected = selected;
    }

    public boolean isViewSelected() {
        return viewSelected;
    }

    public void setRGBColor(int[] rgb,boolean defaultStrokeColor) {
        rgbColor = rgb;
        mDefaultStrokeColor = defaultStrokeColor;
//        invalidate(); 两者的具体的区别
        postInvalidate();
    }

此处作为开放的端口,是得获得具体对象以后可以调用
通过 setRGBColor 这个函数设置不同的rgb 的颜色的值,传递过来,刷新绘制图形即可

6、然后就是代码段端的调用了。

根据需要动态的设置改变颜色值就好,我这里使用的是rgb ,也可以似乎#f00的形式,只要增加对应的方法即可,就不赘述了。
percent25.setRGBColor(colorResource[position], true);


以上就基本完成自定义的图形的绘制了,其实了解canvas绘制形状的方法,自定义一些简单的,不是很难。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值