zoukankan      html  css  js  c++  java
  • Android 自定义view(二) —— attr 使用

    前言:

    attr 在前一篇文章《Android 自定义view —— attr理解》已经简单的进行了介绍和创建,那么这篇文章就来一步步说说attr的简单使用吧

    自定义view简单实现步骤

    (1)首先创建attrs自定义属性文件名称,定义属性以及相关数据类型

    (2)再次创建自定义view,然后读取相关属性完成需要的view相关布局、绘制等工作

    (3)最后在xml布局文件中引用或者直接在代码中new一个相关对象进行使用

    任务需求

    为了能够简单的练习演示attr 相关使用,我现在自己规定了如下需求

    (1)定义view,将需要的属性定义在 attr 中

    (2)在自定义view中 显示文字、文字颜色、文字背景、文字大小

    (3)在xml中引用或者在代码中new一个对象进行使用

    实现任务

    为了方便理解,我将编写顺序进行调整

    我的目录结构:

    {307E782C-32E1-203C-5024-B707D1016893}

    第一步:先来看看我们的自定义属性以及相关数据类型 attrs_ysj.xml文件

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!--name 是自定义属性名,一般采用驼峰命名,可以随意。 format 是属性的单位-->
        <attr name="viewText" format="string" />
        <attr name="viewTextColor" format="color" />
        <attr name="viewTextSize" format="dimension" />
        <!--name 是自定义控件的类名-->
        <declare-styleable name="YText">
            <attr name="viewText" />
            <attr name="viewTextColor" />
            <attr name="viewTextSize" />
            <!--注意:一般情况是按照上面这样写,把属性单独定义在上面,然后在styleable这里面引用,但是我要装一下逼,就单独混写在里面了下,取值的时候就需要单独去取名称才能取到值不然是取不到值-->
            <attr name="viewTextBg" format="color" />
        </declare-styleable>
    </resources>

    注意:关于attr里面的属性定义或者理解有疑惑请移步《Android 自定义view —— attr理解

    第二步:再次来看看XML布局文件

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 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">
        <!--引用自定义view必须是包名.类名-->
        <com.boyoi.ysj.custom.one.view.YView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            custom:viewText="这是我的自定义View"
            custom:viewTextColor="@android:color/holo_red_dark"
            custom:viewTextBg="@android:color/holo_blue_dark"
            custom:viewTextSize="18sp" />
    </LinearLayout>

    哈哈在看了xml还是先来补补点小知识点(很多时候会晕的,特别是面试这些小知识点搞不好你还真说不清楚)——命名空间中的 res/android 和 res-auto

    xmlns:android=http://schemas.android.com/apk/res/android
    xmlns:customview=http://schemas.android.com/apk/res-auto

    注意:这2个实际上前者是就是让你引用系统自带属性的,后者是让你使用lib库里自定义属性的。但是这个地方要注意,在eclipse中如果要使用你自定义的属性 是不能用res-auto的必须得替换成你自定义view所属的包名,如果你在恰好使用的自定义属性被做成了lib那就只能使用res-auto了,而在android-studio里,无论你是自己写自定义view还是引用的lib里的自定义的view 都只能使用res-auto这个写法。以前那个包名的写法在android-studio里是被废弃无法使用的。

    第三步:最后让我们来看看我们是怎么自定义view

    /**
    * Created by yishujun on 16/6/3.
    */
    public class YView extends View {
        private Context mContext;
        //文本
        private String mText;
        //文本的颜色
        private int mTextColor;
        //文本的大小
        private int mTextSize;
        //文本的背景
        private int mTextBg;
        //绘制时控制文本绘制的范围
        private Rect mBound;
        //绘制文本画笔
        private Paint mPaint;
        public YView(Context context) {
            this(context, null);
        }
        public YView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
        public YView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            this.mContext = context;
            typedYView(attrs, defStyleAttr);
        }
        /**
         * 获得我们所定义的自定义样式属性
         *
         * @param attrs
         * @param defStyleAttr
         */
        private void typedYView(AttributeSet attrs, int defStyleAttr) {
            //获得我们所定义的自定义样式属性
            //final Resources.Theme theme = mContext.getTheme();
            //TypedArray a = theme.obtainStyledAttributes(attrs,R.styleable.YText, defStyleAttr, 0);
            //获取自定义属性值的方式一般情况分为两种:styleable组 和 直接获取attr属性
            //这里获取的属性用的styleable组,同时我也建议用这种方式方便规范attrs文件,
            //另外一种获取方式如下,当然也可以一个个获取属性值,这里不再演示
            //int[] custom = {R.attr.viewText, R.attr.viewTextSize};
            //TypedArray a = mContext.obtainStyledAttributes(attrs, custom);
            TypedArray a = mContext.getTheme().obtainStyledAttributes(attrs, R.styleable.YText, defStyleAttr, 0);
            int n = a.getIndexCount();
            for (int i = 0; i <= n; i++) {
                int attr = a.getIndex(i);
                switch (attr) {
                    //注意获取属性的方式为 styleable的名称_属性名称
                    case R.styleable.YText_viewText:
                        mText = a.getString(attr);
                        break;
                    case R.styleable.YText_viewTextColor:
                        // 默认颜色设置为黑色
                        mTextColor = a.getColor(attr, Color.BLACK);
                        break;
                    case R.styleable.YText_viewTextSize:
                        // 默认设置为16sp,TypeValue也可以把sp转化为px
                        mTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
                                TypedValue.COMPLEX_UNIT_SP, 18, getResources().getDisplayMetrics()));
                        break;
                    case R.styleable.YText_viewTextBg:
                        // 默认颜色设置为黄色
                        mTextBg = a.getColor(attr, Color.YELLOW);
                        //但是在这里上面的那种取值方式就是取不到值哦,因为返回后的attr没有YText_viewTextBg,原因是因为我刚装逼了一下,所以我们要单独去取值
                        break;
                }
            }
            //记得在这里单独取出文本的背景mTextBg值哦,因为上面的mTextBg取不到值哦
            mTextBg = a.getColor(R.styleable.YText_viewTextBg, Color.YELLOW);
            //回收资源
            a.recycle();
            //新建画笔对象
            mPaint = new Paint();
            //设置画笔
            mPaint.setTextSize(mTextSize);
            mBound = new Rect();
            //设置画笔绘制文字及相关区域
            mPaint.getTextBounds(mText, 0, mText.length(), mBound);
            this.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    mText = "你摸了我一下";
                    //刷新画布
                    postInvalidate();
                }
            });
        }
        @Override
        protected void onDraw(Canvas canvas) {
            //设置画布颜色即文字背景色
            mPaint.setColor(mTextBg);
            //绘制背景,全屏
            canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);
            //设置文字颜色
            mPaint.setColor(mTextColor);
            //绘制文字
            canvas.drawText(mText, getWidth() / 2 - mBound.width() / 2, getHeight() / 2 + mBound.height() / 2, mPaint);
        }
    }

    运行效果:

    {D6C7159B-5814-C1AB-CE26-D64914D389F9}{093B4F7C-8D33-92C1-FE50-861E0A7F2C66}

    总结:

    怎样一个简单的自定义view不就完成了嘛,是不是看起来很简单,对的是很简单,但是对我来说还有很多东西是需要去深究那么

  • 相关阅读:
    代码风格
    C语言带返回值的宏
    设计模式之PIMPL模式
    打印控制之VT100
    C语言实现反射
    C语言实现函数override
    [BZOJ3669] [NOI2004] 魔法森林 LCT维护最小生成树
    [BZOJ4826] [HNOI2017] 影魔 单调栈 主席树
    [BZOJ2054]疯狂的馒头 并查集
    [BZOJ5305] [HAOI2018] 苹果树 数学 组合计数
  • 原文地址:https://www.cnblogs.com/yishujun/p/5556145.html
Copyright © 2011-2022 走看看