declare styleable从源码中浅析Android中怎么利用attrs和styles定义控件

declare styleable  时间:2022-02-27  阅读:()

从源码中浅析Android中怎么利用attrs和styles定义控件

1.attrs.xml: 我们知道Android的源码中有attrs.xml这个文件,这个文件实际上定义了所有的控件的属性,就是我们在布局文件中设置的各类属性 你可以找到attrs.xml这个文件,打开它,全选,右键->Show In->OutLine。可以看到整个文件的解构 我们大概可以看出里面是Android中的各种属性的声明,比如textStyle这个属性是这样定义的: Java代码 那么现在你知道,我们在写android:textStyle的时候为什么会出现normal,bold和italic这3个东西了吧,就是定义在这个地方。 再看看textColor: Java代码 format的意思是说:这个textColor可以以两种方式设置,要么是关联一个值,要么是直接设置一个颜色的RGB值,这个不难理解,因为我们可以平时也这样做过。 也就是说我们平时在布局文件中所使用的各类控件的属性都定义在这里面,那么这个文件,除了定义这些属性外还定义了各种具体的组件,比如TextView,Button,SeekBar等所具有的各种特有的属性 比如SeekBar: Java代码 也许你会问SeekBar的background,等属性怎么没有看到?这是因为Android中几乎所有的组件都是从View中继承下来的,SeekBar自然也不例外,而background这个属性几乎每个控件都有,因此被定义到了View中,你可以在declare-styleable:View中找到它。 总结下,也就是说attrs.xml这个文件定义了布局文件中的各种属性attr:***,以及每种控件特有的属性declare-styleable:*** 2.styles.xml: 刚才的attrs.xml定义的是组件的属性,现在要说的style则是针对这些属性所设置的值,一些默认的值。 这个是SeekBar的样式,我们可以看到,这里面设置了一个SeekBar的默认的样式,即为attrs.xml文件中的各种属性设置初始值 Java代码 这个是Button的样式: Java代码 有了属性和值,但是这些东西是如何关联到一起的呢?它们如何被android的framework层所识别呢? 3.组件的源码 我们看下TextView的源码: Java代码 public TextView(Context context) { this(context, null); }//这个构造器用来给用户调用,比如new TextView(this); public TextView(Context context, AttributeSet attrs) { this(context, attrs,.android.internal.R.attr.textViewStyle); } public TextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle);//为用户自定义的TextView设置默认的style mText = ""; //设置画笔 mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); mTextPaint.density = getResources().getDisplayMetrics().density; mTextPaint.setCompatibilityScaling( getResources().getCompatibilityInfo().applicationScale); mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mHighlightPaint.setCompatibilityScaling( getResources().getCompatibilityInfo().applicationScale); mMovement = getDefaultMovementMethod(); mTransformation = null; //attrs中包含了这个TextView控件在布局文件中定义的属性,比如android:background,android:layout_width等 /.android.internal.R.styleable.TextView中包含了TextView中的针对attrs中的属性的默认的值 //也就是说这个地方能够将布局文件中设置的属性获取出来,保存到一个TypeArray中,为这个控件初始化各个属性 TypedArray a = context.obtainStyledAttributes( attrs,.android.internal.R.styleable.TextView, defStyle, 0); int textColorHighlight = 0; ColorStateList textColor = null; ColorStateList textColorHint = null; ColorStateList textColorLink = null; int textSize = 15; int typefaceIndex = -1; int styleIndex = -1; /* * Look the appearance up without checking first if it exists because * almost every TextView has one and it greatly simplifies the logic * to be able to parse the appearance first and then let specific tags * for this View override it. */ TypedArray appearance = null; //TextView_textAppearance不太了解为什么要这样做?难道是为了设置TextView的一些默认的属性? int ap = .android.internal.R.styleable.TextView_textAppearance, -1); if (ap != -1) { appearance = context.obtainStyledAttributes(ap, .android.internal.R.styleable. TextAppearance); } if (appearance != null) { int n = appearance.getIndexCount(); for (int i = 0; i < n; i++) { int attr = appearance.getIndex(i); switch (attr) { .android.internal.R.styleable.TextAppearance_textColorHighlight: textColorHighlight = appearance.getColor(attr, textColorHighlight); break; .android.internal.R.styleable.TextAppearance_textColor: textColor = appearance.getColorStateList(attr); break; .android.internal.R.styleable.TextAppearance_textColorHint: textColorHint = appearance.getColorStateList(attr); break; .android.internal.R.styleable.TextAppearance_textColorLink: textColorLink = appearance.getColorStateList(attr); break; .android.internal.R.styleable.TextAppearance_textSize: textSize = appearance.getDimensionPixelSize(attr, textSize); break; .android.internal.R.styleable.TextAppearance_typeface: typefaceIndex = appearance.getInt(attr, -1); break; .android.internal.R.styleable.TextAppearance_textStyle: styleIndex = appearance.getInt(attr, -1); break; } } appearance.recycle(); } //各类属性 boolean editable = getDefaultEditable(); CharSequence inputMethod = null; int numeric = 0; CharSequence digits = null; boolean phone = false; boolean autotext = false; int autocap = -1; int buffertype = 0; boolean selectallonfocus = false; Drawable drawableLeft = null, drawableTop = null, drawableRight = null, drawableBottom = null; int drawablePadding = 0; int ellipsize = -1; boolean singleLine = false; int maxlength = -1; CharSequence text = ""; CharSequence hint = null; int shadowcolor = 0; float dx = 0, dy = 0, r = 0; boolean password = false; int inputType = EditorInfo.TYPE_NULL; int n = a.getIndexCount(); for (int i = 0; i < n; i++) { int attr = a.getIndex(i); //通过switch语句将用户设置的,以及默认的属性读取出来并初始化 switch (attr) { .android.internal.R.styleable.TextView_editable: editable = a.getBoolean(attr, editable); break; .android.internal.R.styleable.TextView_inputMethod: inputMethod = a.getText(attr); break; .android.internal.R.styleable.TextView_numeric: numeric = a.getInt(attr, numeric); break; //更多的case语句... .android.internal.R.styleable.TextView_textSize: textSize = a.getDimensionPixelSize(attr, textSize);//设置当前用户所设置的字体大小 break; .android.internal.R.styleable.TextView_typeface: typefaceIndex = a.getInt(attr, typefaceIndex); break; //更多的case语句... } 通过上面的代码大概可以知道,每个组件基本都有3个构造器,其中只传递一个Context上下文的那个构造器一般用来在java代码中实例化使用。 比如你可以 Java代码 = new TextView(context); 来实例化一个组件。 最终调用的是第3个构造器 Java代码 public TextView(Context context, AttributeSet attrs, int defStyle) 在这个构造器中为你设置了默认的属性attrs和值styles。关键不在这里,而是后面通过使用下面的代码 Java代码 TypedArray a = context.obtainStyledAttributes( attrs,.android.internal.R.styleable.TextView, defStyle, 0); 来将属性和值获取出来,放到一个TypeArray中,然后再利用一个switch语句将里面的值取出来。再利用这些值来初始化各个属性。这个View最终利用这些属性将这个控件绘制出来。 如果你在布局文件中定义的一个View的话,那么你定义的值,会被传递给构造器中的attrs和styles。也是利用同样的方式来获取出你定义的值,并根据你定义的值来绘制你想要的控件。 再比如其实Button和EditText都是继承自TextView。看上去两个控件似乎差异很大,其实不然。Button的源码其实相比TextView变化的只是style而已:

Sharktech:鲨鱼机房1Gbps无限流量美国服务器;丹佛$49/月起,洛杉矶$59/月起

sharktech怎么样?sharktech鲨鱼机房(Sharktech)我们也叫它SK机房,是一家成立于2003年的老牌国外主机商,提供的产品包括独立服务器租用、VPS主机等,自营机房在美国洛杉矶、丹佛、芝加哥和荷兰阿姆斯特丹等,主打高防产品,独立服务器免费提供60Gbps/48Mpps攻击防御。机房提供1-10Gbps带宽不限流量服务器,最低丹佛/荷兰机房每月49美元起,洛杉矶机房最低59美元...

如何低价香港服务器购买?有没有便宜的香港服务器推荐?

如何低价香港服务器购买?想要做一个个人博客,想用香港服务器,避免繁琐备案,性能不需要多高,只是记录一些日常而已,也没啥视频之类的东西,想问问各位大佬有没有低价的香港服务器推荐?香港距大陆近,相比美国服务器最大的优势在于延迟低,ping值低,但是带宽紧张,普遍都是1M,一般戏称其为“毛细血管”。同时价格普遍高,优质稳定的一般价格不菲。大厂云梯队阿里云、腾讯云两家都有香港服务器,要注意的是尽量不要选择...

印象云七夕促销,所有机器7折销售,美国CERA低至18元/月 年付217元!

印象云,成立于2019年3月的商家,公司注册于中国香港,国人运行。目前主要从事美国CERA机房高防VPS以及香港三网CN2直连VPS和美国洛杉矶GIA三网线路服务器销售。印象云香港三网CN2机房,主要是CN2直连大陆,超低延迟!对于美国CERA机房应该不陌生,主要是做高防服务器产品的,并且此机房对中国大陆支持比较友好,印象云美国高防VPS服务器去程是163直连、三网回程CN2优化,单IP默认给20...

declare styleable为你推荐
蓝屏代码电脑蓝屏,出现代码。密码设置电脑怎么设置密码最好的视频播放器最好的视频播放器有哪些?小蓝条AU多轨怎么调出每个音轨下面一个小蓝条调整音量充值卡充值充值卡怎么充值游戏spinmaster会飞的小仙女玩具什么品牌程序员段子20、老婆给当程序员的老公打电话:“下班顺路买一斤包子带回来,如果看到卖西瓜的,买一个。”当晚,程序blacken曲婉婷ShineOverme中英文歌词廖华《学学孔子怎样当老师》读后感 南京廖华网页错误详细信息网页错误详细信息 消息: 'this._self.style' 为空或不是对象
万网域名注册 域名注册信息查询 域名查询系统 免费申请域名 注册cn域名 bluehost 2014年感恩节 42u标准机柜尺寸 发包服务器 老左正传 国外代理服务器软件 购买国外空间 吉林铁通 双线asp空间 宏讯 备案空间 监控服务器 广东服务器托管 服务器防御 zencart安装 更多