原因是由于接触安卓也这么久了,但是自定义view这方面一直没怎么了解, 尤其是对于自定义属性的使用。

由于最近app上需要用到自定义View,于是决定把自定义View的坑填上(毕竟安卓中自定义View是重点也是难点),

可是没想到第一步就遇到了问题。写这博文主要是为了记录错误,也可以为同样遇到这问题的童鞋提供一个解决办法。


首先给出鸿洋大神此博文的传送门传送门。你们可以先过去看看。

由于要用到部分大神的文字才方便解释(不知算不算那啥,有问题联系我,立马删除)

1、自定义View的属性,首先在res/values/  下建立一个attrs.xml , 在里面定义我们的属性和声明我们的整个样式。[html] view plain copy 在CODE上查看代码片派生到我的代码片<?xml version="1.0" encoding="utf-8"?>                                                                        我们定义了字体,字体颜色,字体大小3个属性,format是值该属性的取值类型:一共有:string,color,demension,integer,enum,reference,float,boolean,fraction,flag;不清楚的可以google一把。然后在布局中声明我们的自定义View[objc] view plain copy 在CODE上查看代码片派生到我的代码片              一定要引入 xmlns:custom="http://schemas.android.com/apk/res/com.example.customview01"我们的命名空间,后面的包路径指的是项目的package2、在View的构造方法中,获得我们的自定义的样式[java] view plain copy 在CODE上查看代码片派生到我的代码片/**      * 文本      */      private String mTitleText;      /**      * 文本的颜色      */      private int mTitleTextColor;      /**      * 文本的大小      */      private int mTitleTextSize;        /**      * 绘制时控制文本绘制的范围      */      private Rect mBound;      private Paint mPaint;        public CustomTitleView(Context context, AttributeSet attrs)      {          this(context, attrs, 0);      }        public CustomTitleView(Context context)      {          this(context, null);      }        /**      * 获得我自定义的样式属性      *       * @param context      * @param attrs      * @param defStyle      */      public CustomTitleView(Context context, AttributeSet attrs, int defStyle)      {          super(context, attrs, defStyle);          /**          * 获得我们所定义的自定义样式属性          */          TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTitleView, defStyle, 0);          int n = a.getIndexCount();          for (int i = 0; i < n; i++)          {              int attr = a.getIndex(i);              switch (attr)              {              case R.styleable.CustomTitleView_titleText:                  mTitleText = a.getString(attr);                  break;              case R.styleable.CustomTitleView_titleTextColor:                  // 默认颜色设置为黑色                  mTitleTextColor = a.getColor(attr, Color.BLACK);                  break;              case R.styleable.CustomTitleView_titleTextSize:                  // 默认设置为16sp,TypeValue也可以把sp转化为px                  mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(                          TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));                  break;                }            }          a.recycle();            /**          * 获得绘制文本的宽和高          */          mPaint = new Paint();          mPaint.setTextSize(mTitleTextSize);          // mPaint.setColor(mTitleTextColor);          mBound = new Rect();          mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);        }  



我们可以看到,步骤我们做的都是一样的。但是在获取自定义属性值得时候就不一样了。

上文是这样的:

/**          * 获得我们所定义的自定义样式属性          */          TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTitleView, defStyle, 0);          int n = a.getIndexCount();          for (int i = 0; i < n; i++)          {              int attr = a.getIndex(i);              switch (attr)              {              case R.styleable.CustomTitleView_titleText:                  mTitleText = a.getString(attr);                  break;              case R.styleable.CustomTitleView_titleTextColor:                  // 默认颜色设置为黑色                  mTitleTextColor = a.getColor(attr, Color.BLACK);                  break;              case R.styleable.CustomTitleView_titleTextSize:                  // 默认设置为16sp,TypeValue也可以把sp转化为px                  mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(                          TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));                  break;                }            }          a.recycle();  

也就是先获取了自定义属性的目录索引值,然后通过switch进行与我们的attrs.xml相匹配,最后进行取值。

这样咋看没有什么问题,在这篇博文也没什么问题,

但是如果我们想偷点懒,不在xml中写出任何我们的自定义属性,这时会发生什么?

你肯定会说当然是取代码中你写的默认值啊,非也,非也。照这种写法是不能取到任何默认值!

为什么?看看变色的那句,理解到了吗?

context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTitleView, defStyle, 0);是通过查询我们使用自定义View的时候里面所写出的值,准确的说是保存所有我们写出的值,

比如上文中的:

android:layout_width="200dp"          android:layout_height="100dp"          custom:titleText="3712"          custom:titleTextColor="#ff0000"          custom:titleTextSize="40sp"

它就会找到,android:layout_width,android:layout_height,custom:titleText,custom:titleTextColor,custom:titleTextSize。这几组值,

但是如果我们自定义的属性不写上去呢?只是想控制个控件的大小(事实证明很多情况下你的确不太会去改变控件的其他属性,除非你需要),就会变成只找到android:layout_width,android:layout_height。这时候如果你再通过Switch()去匹配的话,除了android:layout_width,android:layout_height两个分支,其他的都不会被执行,既然没有执行,那么默认值如何取得出?


找到了问题所在,我们就要解决了,解决也很简单,去掉获取目录,不使用switch()语句

每个属性都这样获取:

TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTitleView, defStyle, 0);  
// 默认颜色设置为黑色                  mTitleTextColor = a.getColor(attr, Color.BLACK); 

   

这样就能保证每个想要设置默认值的能正确的被设置默认值了。

有问题欢迎指正,如引用的部分文字有侵权,请告知我,会立即处理、

   
   
   
   
   
   
   
   
   


更多相关文章

  1. 在Android中通过jni方式使用编译好的FFmpeg库-Android中使用FFmp
  2. Android(安卓)Q暗色模式适配踩坑—状态栏
  3. [Android(安卓)之美] 那些你不知道的APK 瘦身,让你的APK更小
  4. android/NDK开发assets资源中文名打包问题
  5. g1安装android软件详细攻略
  6. android重用layout-include标签的使用
  7. android 支付宝SDK集成
  8. J2me游戏如何快速移植到Android(安卓)(2)
  9. 在android的java代码中自定义log

随机推荐

  1. 可以直接拿来用的15个jQuery代码片段
  2. 嵌套在.get请求中的jQuery将不会执行
  3. 使用jquery 1.11.3.min.js时,jquery on cl
  4. jquery与JavaScript部分使用区别
  5. 如何更改Gmaps.js在Google地图中使用的图
  6. jQuery UI框架的Dreamweaver接口
  7. jQuery UI AutoComplete的使用
  8. 在使用kendo网格中的删除按钮后,如何刷新M
  9. jQuery自动完成不适用于多个文本输入
  10. 注册的时候,点击注册按钮,用jquery怎么直接