自定义View之自定义属性

步骤

1.定义自己的属性

在res/values/目录下专拣attrs.xml文件如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!--format 的类型:string,color,demension,integer,enum,reference,float,boolean,fraction,flag;想要详细学习可以去Google查看-->

    <!--定义一个样式,一个样式包括多个属性-->
    <declare-styleable name="CustomView">
        <!--定义属性名字,及其类型-->
        <attr name="myText" format="string"/>
        <attr name="myTextColor" format="color"/>
        <attr name="myBackgroundColor" format="color"/>
        <attr name="myTextSize" format="dimension"/>
    </declare-styleable>

</resources>

2.定义自己的View

package netclientdemo.example.com.customview;

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.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;

/**
 * Created by liaoli on 15-11-24.
 */
public class CustomView_1 extends View {

    private int backgroundColor;
    private Rect mBound;
    private Paint mPint;
    /**
     * 要显示的文本内容
     */
    private String text;

    /**
     * 文本显示的颜色
     */
    private int textColor;

    /**
     *
     */
    private int textSize;
    private Canvas mcanvas;

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

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

    public CustomView_1(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        /**
         * 获取我们字自定义的样式属性,TypedArray可以拿到我们所有自定义的属性,并获取我们在Xml中给我们自定义属性赋的值
         */
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomView, defStyleAttr, 0);

        /**
         * 下面获取在xml中的赋值
         * <netclientdemo.example.com.customview.CustomView_1
         *  android:layout_width="wrap_content"
         *  android:layout_height="wrap_content"
         *  custom:myText="@string/hello_world"
         *  custom:myTextColor="#fbff38c1"
         *  custom:myBackgroundColor="#91ff84"
         *  android:padding="10dp"
         *  custom:myTextSize="20sp">
         * </netclientdemo.example.com.customview.CustomView_1>
         */


        /**
         * 此时我们text值为@string/hello_world指向的字符串
         */
        text = a.getString(R.styleable.CustomView_myText);

        /**
         * textColor的值为#fbff38c1对应的颜色的Int值,如果没有设置这个值则Color.BLACK作为默认值
         */
        textColor = a.getColor(R.styleable.CustomView_myTextColor, Color.BLACK);

        backgroundColor = a.getColor(R.styleable.CustomView_myBackgroundColor, Color.WHITE);

        textSize = a.getDimensionPixelSize(R.styleable.CustomView_myTextSize, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));

        //       int n = a.getIndexCount();

//        for (int i = 0; i < n; i++) {
//            int attr = a.getIndex(i);
//            switch (attr) {
//                case R.styleable.CustomView_myText:
//
//                    text = a.getString(attr);
//
//                    break;
//                case R.styleable.CustomView_myTextColor:
//
//                    textColor = a.getColor(attr, Color.BLACK);
//
//                    break;
//                case R.styleable.CustomView_myBackgroundColor:
//
//                    backgroundColor = a.getColor(attr, Color.WHITE);
//
//                    break;
//                case R.styleable.CustomView_myTextSize:
//
//                    textSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
//
//                    break;
//
//            }
//        }

        a.recycle();

        mPint = new Paint();

        mPint.setTextSize(textSize);

        mBound = new Rect();

        mPint.getTextBounds(text, 0, text.length(), mBound);


    }


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

        int widthMeasureMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthMeasureSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMeasureMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightMeasureSize = MeasureSpec.getSize(heightMeasureSpec);


        int width;
        int height;

        if (widthMeasureMode == MeasureSpec.EXACTLY) {
            width = widthMeasureSize;
        } else {
            mPint.setTextSize(textSize);
            mPint.getTextBounds(text, 0, text.length(), mBound);
            float textWidth = mBound.width();
            int wrapWidth = (int) (getPaddingLeft() + textWidth + getPaddingRight());

            width = wrapWidth;
        }

        if (heightMeasureMode == MeasureSpec.EXACTLY) {
            height = heightMeasureSize;
        } else {
            mPint.setTextSize(textSize);
            mPint.getTextBounds(text, 0, text.length(), mBound);
            float textHeight = mBound.height();
            int wrapHeight = (int) (getPaddingTop() + textHeight + getPaddingBottom());

            height = wrapHeight;
        }


        setMeasuredDimension(width, height);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        //super.onDraw(canvas);


        mPint.setColor(backgroundColor);

        canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPint);

        mPint.setColor(textColor);

        canvas.drawText(text, getMeasuredWidth() / 2 - mBound.width() / 2, getMeasuredHeight() / 2 + mBound.height() / 2, mPint);


    }
}

3.应用自定义属性

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    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">

    <netclientdemo.example.com.customview.CustomView_1

        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        custom:myText="@string/hello_world"
        custom:myTextColor="#fbff38c1"
        custom:myBackgroundColor="#91ff84"
        android:padding="10dp"
        custom:myTextSize="20sp">

    </netclientdemo.example.com.customview.CustomView_1>

</RelativeLayout>
这里要注意:

命名空间:

Android studio 为: http://schemas.android.com/apk/res-auto 后面不用加报名

Eclipse为 :http://schemas.android.com/apk/res/包名

效果:



之所以重写onMeasure方法是要测量wrap_content的宽高。

源码:http://pan.baidu.com/s/1hqJdUuw


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
TypeArray 是 Android 中的一个特殊的资源类型,用于在 XML 中声明自定义 View属性。使用 TypeArray 可以方便地在 XML 布局中指定 View属性,而不需要在 Java 代码中进行硬编码。 使用 TypeArray 的步骤如下: 1. 在 res/values/attrs.xml 文件中定义定义 View属性。 ```xml <resources> <declare-styleable name="MyCustomView"> <attr name="customAttr1" format="integer" /> <attr name="customAttr2" format="string" /> <attr name="customAttr3" format="boolean" /> </declare-styleable> </resources> ``` 2. 在自定义 View 的构造函数中获取 TypedArray 对象,并从中获取属性值。 ```java public class MyCustomView extends View { private int customAttr1; private String customAttr2; private boolean customAttr3; public MyCustomView(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView); customAttr1 = a.getInt(R.styleable.MyCustomView_customAttr1, 0); customAttr2 = a.getString(R.styleable.MyCustomView_customAttr2); customAttr3 = a.getBoolean(R.styleable.MyCustomView_customAttr3, false); a.recycle(); } } ``` 在上面的代码中,`context.obtainStyledAttributes(attrs, R.styleable.MyCustomView)` 用于获取 TypedArray 对象,`R.styleable.MyCustomView` 是在 attrs.xml 文件中定义的自定义属性集合,`a.getInt()`、`a.getString()`、`a.getBoolean()` 用于从 TypedArray 对象中获取属性值,最后需要调用 `a.recycle()` 来回收 TypedArray 对象。 3. 在 XML 布局中使用自定义 View,并设置属性值。 ```xml <com.example.MyCustomView android:layout_width="match_parent" android:layout_height="wrap_content" app:customAttr1="123" app:customAttr2="hello" app:customAttr3="true" /> ``` 在上面的代码中,`app:customAttr1`、`app:customAttr2`、`app:customAttr3` 是在 attrs.xml 文件中定义的自定义属性名,可以在 XML 布局中使用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值