转载请注明出处:http://blog.csdn.net/evan_man/article/details/51615568
本篇博客内容是对Android中Resource资源的介绍。大部分内容从Android官方网站上获取,对其进行分析、理解和再加工最终得到下面的内容。本文最后的style部分介绍了视图控件是如何根据系统主题设定自己的样式,如字体大小、颜色和视图背景等信息,该部分对于以后分析各种View控件大有益处。请尊重他人劳动成果,请勿随意剽窃,转载请注明,谢谢!
Animation
一、属性动画
文件位置在res/animator/filename.xml中。Java代码中使用R.animator.filename获取;xml文件中使用@[package:]animator/filename方式获取资源。文件中只能有一个根元素<set>, <objectAnimator>, or <valueAnimator>。一般都是使用<set>它能够内嵌<set>,
<objectAnimator>, or <valueAnimator>。下面对各类常用标签进行简单介绍
<set>
- 该标签有一个android:ordering属性,控制内嵌在其中的动画展示顺序
<objectAnimator>
- 用于在指定的一段时间类控制一个Object的特定属性
- android:propertyName属性;如android:propertyName="alpha",目标对象需要有对应的setAlpha()方法
- android:valueTo属性;动画最终停留的值
- android:valueFrom属性;动画起始的值
- android:duration属性:动画生命时间
- android:valueType属性:属性数据类型
<animator>
- 代表ValueAnimator,用于在一段时间类修改一个值。除了没有android:propertyName属性其它同<objectAnimator>基本一致
示例
-------------------xml文件内容------------------------ res/animator/property_animator.xml: <set android:ordering="sequentially"> <set> <objectAnimator android:propertyName="x" android:duration="500" android:valueTo="400" android:valueType="intType"/> <objectAnimator android:propertyName="y" android:duration="500" android:valueTo="300" android:valueType="intType"/> </set> <objectAnimator android:propertyName="alpha" android:duration="500" android:valueTo="1f"/> </set> ----------------------Java客户代码------------------------------ AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext, R.anim.property_animator); set.setTarget(myObject); set.start();
二、补帧动画(渐变动画)
文件位置在res/drawable/filename.xml中。Java代码中使用R.drawable.filename获取;xml文件中使用@[package:]drawable.filename方式获取资源。文件中只能有一个根元素<animation-list>,然后内部嵌套很多<item>元素。下面对各类常用标签进行简单介绍
<animation-list>
- android:oneshot属性为true只反映一次,false则循环放映
<item>
- android:drawable属性指定这一帧所使用的图片
- android:duration属性指定这一帧停留的时间
示例
-------------------xml文件内容------------------------ res/anim/rocket.xml: <?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> <item android:drawable="@drawable/rocket_thrust1" android:duration="200" /> <item android:drawable="@drawable/rocket_thrust2" android:duration="200" /> <item android:drawable="@drawable/rocket_thrust3" android:duration="200" /> </animation-list> ----------------------Java客户代码------------------------------ ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image); rocketImage.setBackgroundResource(R.drawable.rocket_thrust); rocketAnimation = (AnimationDrawable) rocketImage.getBackground(); rocketAnimation.start();
Drawable
一、Bitmap File
文件位置在res/drawable/filename.png (.png, .jpg, or .gif)中。文件格式推荐为png,jpg次之,gif不推荐。这里的文件都会被转换成bitmapDrawable对象。Java代码中使用R.drawable.filename获取;xml文件中使用@[package:]drawable/filename方式获取资源。
二、Layer List
文件位置在res/drawable/filename.xml中。Java代码中使用R.drawable.filename获取;xml文件中使用@[package:]drawable/filename方式获取资源。用于显示一组drawable试图。
示例
-------------------xml文件内容------------------------ res/drawable/layers.xml: <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <bitmap android:src="@drawable/android_red" android:gravity="center" /> </item> <item android:top="10dp" android:left="10dp"> <bitmap android:src="@drawable/android_green" android:gravity="center" /> </item> <item android:top="20dp" android:left="20dp"> <bitmap android:src="@drawable/android_blue" android:gravity="center" /> </item> </layer-list> ----------------------客户代码------------------------------ <ImageView android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/layers" />
三、State List
文件位置在res/drawable/filename.xml中。Java代码中使用R.drawable.filename获取;xml文件中使用@[package:]drawable/filename方式获取资源。根据当前View的状态显示不同的背景样式。根目录必须为<selector>,下面对常用元素进行说明。
<selector>
- xmlns:android 定义xml域名空间其值必须为"http://schemas.android.com/apk/res/android".
<item>
- 定义不同状态对应不同的drawable
- android:drawable:其值是对一个drawable资源的引用
- android:state_pressed、android:state_focused、android:state_selected等等状态
示例
-------------------xml文件内容------------------------ res/drawable/button.xml: <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:drawable="@drawable/button_pressed" /> <!-- pressed --> <item android:state_focused="true" android:drawable="@drawable/button_focused" /> <!-- focused --> <item android:state_hovered="true" android:drawable="@drawable/button_focused" /> <!-- hovered --> <item android:drawable="@drawable/button_normal" /> <!-- default --> </selector> ----------------------客户代码------------------------------ <Button android:layout_height="wrap_content" android:layout_width="wrap_content" android:background="@drawable/button" />
四、Level List
文件位置在res/drawable/filename.xml中。Java代码中使用R.drawable.filename获取;xml文件中使用@[package:]drawable/filename方式获取资源。用于管理一组Drawable,Obejct可以通过setLevel()显示不同Drawable,比如电池的状态。根目录必须为<level-list>,下面的元素为<item>;
<item>
- android:drawable:所对应的Drawable资源
- android:maxLevel:当前Drawable能显示的level最大值
- android:minLevel:当前Drawable能显示的level最小值
示例
<?xml version="1.0" encoding="utf-8"?> <level-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@drawable/status_off" android:maxLevel="0" /> <item android:drawable="@drawable/status_on" android:maxLevel="1" /> </level-list>
五、Shape Drawable
文件位置在res/drawable/filename.xml中。Java代码中使用R.drawable.filename获取;xml文件中使用@[package:]drawable/filename方式获取资源。定义一个几何图形。根目录必须为<shape>。
<shape>
- xmlns:android:xml域名空间通常值为"http://schemas.android.com/apk/res/android".
- android:shape:几何形状,"rectangle"、"oval"、"line"(需要通过<stroke> 指定宽度)、"ring" 对应矩形、椭圆、线、环。
- 当android:shape="ring"时:
- android:innerRadius:环的内部半径
- android:thickness:环的厚度
- 当android:shape="rectangle"时:
- <corners>该标签用于设置每个角上的角度
- android:radius:所有角的半径;也有android:topLeftRadius、android:topRightRadius等针对不同角设置不同的弧度
<solid>
- 形状填充颜色,只有一个android:color属性指定颜色
<gradient>
- 当前形状的渐变颜色
- android:angle:渐变的角度,0从左到右,90从上到下
- android:startColor:起始颜色
- android:centerColor:开始到结束中间的颜色
- android:endColor:结束颜色
- android:type:渐变样式,线性还是?
<size>
- 形状大小
- android:height:高度
- android:width:宽度
<stroke>
- 当前形状的边
- android:width:宽度
- android:color:颜色
示例
-------------------xml文件内容------------------------ res/drawable/gradient_box.xml: <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:startColor="#FFFF0000" android:endColor="#80FF00FF" android:angle="45"/> <padding android:left="7dp" android:top="7dp" android:right="7dp" android:bottom="7dp" /> <corners android:radius="8dp" /> </shape> ----------------------客户代码------------------------------ <TextView android:background="@drawable/gradient_box" android:layout_height="wrap_content" android:layout_width="wrap_content" />
此外还有Transition Drawable、Clip Drawable、Scale Drawable这里就不再介绍了。
Menu
被应用在Options Menu, Context Menu, or submenu中,通过MenuInflater进行加载。文件位置在res/menu/filename.xml中。Java代码中使用R.menu.filename获取;xml文件中使用@[package:]menu.filename方式获取资源。<menu>必须为其根目录,能够内嵌<item> 和 <group> e两种元素
<item>
- android:id:定义一个唯一的id
- android:title:菜单标题
- android:titleCondensed:如果系统嫌弃前面内容太长可以选择使用这里的值
- android:icon:图标
- android:onClick:指定其点击事件处理方法,不设置也可以在onOptionMenu中处理点击事件,这里指定的方法必须声明在Activity中,且是public,而且参数为 MenuItem。
- android:showAsAction:控制合适如何显示当前item。
- ifRoom表明有空间则放,没空间存入overflowMenu中;
- withText同时显示一个字符,可以显示一个"|“字符作为两个Action之间的界限。
- never、always一个永不一个总是显示到ActionBar中。
- collapseActionView:不展开当前Item关联的Action View。
- android:actionLayout:Layout use as action View
- android:actionViewClass:类的全称,如android.widget.SearchView
- android:actionProviderClass:共享信息使用,如android.widget.ShareActionProvider
- android:orderInCategory:当前item在group中的权重,值越大越往后
<group>
- 管理一组item
示例
-------------------xml文件内容------------------------ res/menu/example_menu.xml <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/item1" android:title="@string/item1" android:icon="@drawable/group_item1_icon" android:showAsAction="ifRoom|withText"/> <group android:id="@+id/group"> <item android:id="@+id/group_item1" android:onClick="onGroupItemClick" android:title="@string/group_item1" android:icon="@drawable/group_item1_icon" /> <item android:id="@+id/group_item2" android:onClick="onGroupItemClick" android:title="@string/group_item2" android:icon="@drawable/group_item2_icon" /> </group> <item android:id="@+id/submenu" android:title="@string/submenu_title" android:showAsAction="ifRoom|withText" > <menu> <item android:id="@+id/submenu_item1" android:title="@string/submenu_item1" /> </menu> </item> </menu> ----------------------Java客户代码------------------------------ public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.example_menu, menu); return true; } public void onGroupItemClick(MenuItem item) { // One of the group items (using the onClick attribute) was clicked // The item parameter passed here indicates which item it is // All other menu item clicks are handled by onOptionsItemSelected() }
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-----------------------下面的xml文件都是存放在values目录下的,前面都是定义在特定的animator、drawable、menu目录中----------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
String
一、String
文件位置在res/values/filename.xml中。Java代码中使用R.string.string_name获取;xml文件中使用@string/string_name方式获取资源。根目录必须是<resources>
<string>
- name:string的名字
示例
-------------------xml文件内容----------------------- res/values/strings.xml <?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello!</string> </resources> ----------------------客户代码------------------------------ <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" />
二、String Array
文件位置在res/values/filename.xml中。Java代码中使用R.array.string_array_name获取。根目录必须是<resources>
<string-array>
- name:字符数组的名字
- <item>:数组元素中的值
示例
-------------------xml文件内容----------------------- res/values/strings.xml: <?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="planets_array"> <item>Mercury</item> <item>Venus</item> <item>Earth</item> <item>Mars</item> </string-array> </resources> ----------------------Java客户代码------------------------------ Resources res = getResources(); String[] planets = res.getStringArray(R.array.planets_array);
Bool
-------------------xml文件内容----------------------- res/values-small/bools.xml: <?xml version="1.0" encoding="utf-8"?> <resources> <bool name="screen_small">true</bool> <bool name="adjust_view_bounds">true</bool> </resources> ----------------------Java客户代码------------------------------ Resources res = getResources(); boolean screenIsSmall = res.getBoolean(R.bool.screen_small); ----------------------客户代码------------------------------ <ImageView android:layout_height="fill_parent" android:layout_width="fill_parent" android:src="@drawable/logo" android:adjustViewBounds="@bool/adjust_view_bounds" />
Color
-------------------xml文件内容----------------------- res/values/colors.xml: <?xml version="1.0" encoding="utf-8"?> <resources> <color name="opaque_red">#f00</color> <color name="translucent_red">#80ff0000</color> </resources> ----------------------Java客户代码------------------------------ Resources res = getResources(); int color = res.getColor(R.color.opaque_red); ----------------------客户代码------------------------------ <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:textColor="@color/translucent_red" android:text="Hello"/>
Dimension
-------------------xml文件内容----------------------- res/values/dimens.xml: <?xml version="1.0" encoding="utf-8"?> <resources> <dimen name="textview_height">25dp</dimen> <dimen name="textview_width">150dp</dimen> <dimen name="ball_radius">30dp</dimen> <dimen name="font_size">16sp</dimen> </resources> ----------------------Java客户代码------------------------------ Resources res = getResources(); float fontSize = res.getDimension(R.dimen.font_size); ----------------------客户代码------------------------------ <TextView android:layout_height="@dimen/textview_height" android:layout_width="@dimen/textview_width" android:textSize="@dimen/font_size"/>
Integer
-------------------xml文件内容----------------------- res/values/integers.xml: <?xml version="1.0" encoding="utf-8"?> <resources> <integer name="max_speed">75</integer> <integer name="min_speed">5</integer> </resources> ----------------------Java客户代码------------------------------ Resources res = getResources(); int maxSpeed = res.getInteger(R.integer.max_speed);
Integer Array
-------------------xml文件内容----------------------- res/values/integers.xml: <?xml version="1.0" encoding="utf-8"?> <resources> <integer-array name="bits"> <item>4</item> <item>8</item> <item>16</item> <item>32</item> </integer-array> </resources> ----------------------Java客户代码------------------------------ Resources res = getResources(); int[] bits = res.getIntArray(R.array.bits);
Style
文件位置在res/values/filename.xml中。xml文件中使用 @[package:]style/style_name方式获取资源。根目录必须是<resources>
<style>
- name:style的名字
- parent:父类,可为空
<item>
- 定义样式的单独属性,是<style>标签下的子标签
- name:属性attribute名字
示例
-------------------xml文件内容----------------------- <?xml version="1.0" encoding="utf-8"?> <resources> <style name="CustomText" parent="@style/Text"> <item name="android:textSize">20sp</item> <item name="android:textColor">#008</item> </style> </resources> ----------------------客户代码------------------------------ <?xml version="1.0" encoding="utf-8"?> <EditText style="@style/CustomText" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Hello, World!" />
样式的定义与使用
attr:
定义自定义属性。如
<attr name="custom_attr1" format="string" />
<attr name="custom_attr2" format="string" />
定义一个attr就会在R文件里面生成一个Id
使用自定义属性
int[] custom_attrs = {R.attr.custom_attr1,R.custom_attr2};
styleable:
attr不依赖于styleable,styleable只是为了方便attr的使用,有一个分组的概念,属性的使用范围更加明确。定义一个styleable,我们可以在R文件里自动生成一个int[],数组里面的int就是定义在styleable里面的attr的id。
定义
<declare-styleable name="custom_attrs">
<attr name="custom_attr1" format="string" />
<attr name="custom_attr2" format="string" />
</declare-styleable>
使用
TypedArray typedArray = context.obtainStyledAttributes(set,R.styleable.custom_attrs);
obtainStyledAttributes()
参数指定从哪里获取到指定的属性
obtainAttributes(AttributeSet set, int[] attrs)
- 从layout设置的属性集中获取attrs中的属性
- set:表示从layout文件中直接为这个View添加的属性的集合
- 还记得View构造器的参数(Context context, AttributeSet set)?
obtainStyledAttributes(int[] attrs)
- 直接从Theme中读取属性
obtainStyledAttributes(int resId,int[] attrs)
- 从资源文件定义的style中读取属性
- resId:直接从资源文件中定义的某个样式中读取
obtainStyledAttributes (AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes)
- defStyleAttr:是自定义一个可以在Theme中配置样式的关键,如TextView
- <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
- //在主题中设置textview的style
- <item name="android:textViewStyle">@style/textviewstyle</item>
- </style>
- <style name="textviewstyle" parent="android:style/Widget.TextView">
- <!--指定一些属性-->
- </style>
- public TextView(Context context, AttributeSet attrs) {
- //指定属性textViewStyle为defStyleAttr,然后系统会去搜索Theme中你为这个 属性配置的style
- this(context, attrs, com.android.internal.R.attr.textViewStyle);
- }
- defStyleRes:直接从资源文件中定义的某个样式中读取
综上样式的数据来源有四个:set,defStyleAttr,NULL,defStyleRes。优先级如下set -> defStyleAttr(主题可配置样式) -> defStyleRes(默认样式) -> NULL(主题中直接指定)。下面说人话,查找样式顺序如下:
- View的layout中声明的属性。如app:custom_attr="value"或者android:style="@style/myStyle"
- 当前App或者Activity的Theme中配置样式,需要在obtainStyledAttributes (AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) 方法中声明(红色字体)
- obtainStyledAttributes (AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) 方法中(红色字体)声明的资源中的属性
- 当前App或者Activity的Theme中声明的属性
下面给出一个样例
一、声明attr
res/values/styles.xml <declare-styleable name="custom_attrs"> <attr name="custom_color1" format="color"></attr> <attr name="custom_color2" format="color"></attr> <attr name="custom_color3" format="color"></attr> <attr name="custom_color4" format="color"></attr> <attr name="custom_color5" format="color"></attr> </declare-styleable> <attr name="custom_style" format="reference"></attr>
二、定义attr
---------------------partA-----------------------------
res/layout/mylayout.xml <com.exmp.MyCustomView android:layout_width="wrap_content" android:layout_height="wrap_content" android:style="@style/myStyle" app:custom_color1="#ff000000" > </com.exmp.MyCustomView> res/values/styles.xml <style name="myStyle"> <item name="custom_color1">#ff111111</item> <item name="custom_color2">#ff111111</item> </style>
-----------------------PartB------------------------------
res/values/styles.xml <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> //配置style <item name="custom_style">@style/custom_theme</item> //直接在主题中指定 <item name="custom_color1">#ff444444</item> <item name="custom_color2">#ff444444</item> <item name="custom_color3">#ff444444</item> <item name="custom_color4">#ff444444</item> <item name="custom_color5">#ff444444</item> </style> res/values/styles.xml <style name="custom_theme"> <item name="custom_color1">#ff222222</item> <item name="custom_color2">#ff222222</item> <item name="custom_color3">#ff222222</item> </style>
------------------------PartC----------------------------
<style name="default_style"> <item name="custom_color1">#ff333333</item> <item name="custom_color2">#ff333333</item> <item name="custom_color3">#ff333333</item> <item name="custom_color4">#ff333333</item> </style>
三、对应java客户代码
public MyCustomView(Context context) { this(context,null); } public MyCustomView(Context context, AttributeSet set) { this(context, set, R.attr.custom_style); //对应PartB } public LinearRecyclerView(Context context, AttributeSet set, int defStyle) { super(context, set, defStyle); final TypedArray a = context.obtainStyledAttributes( set, R.styleable.custom_attrs, defStyle, R.style.default_style); //对应PartC }
TypedArray中获取的属性值分别是:
custom_color1=#ff000000 //布局文件中直接指定,优先级最高
custom_color2=#ff111111 //布局同通过style指定,也包含在set中,优先级第二
custom_color3=#ff222222 //布局通过主题中配置风格style
custom_color4=#ff333333 //由系统Theme直接指定的
custom_color5=#ff444444
注意:TypedArray主要有两个作用,第一是内部去转换attrid和属性值数组的关系;第二是提供了一些类型的自动转化。可以将其看成一个Json数据
<include>/<merge>
<include>
是将整个布局文件(xml)作为一个View添加到父布局文件中,<include>中的view有自己单独的视图结构。可以将include看成是把xml文件整个原封不动的添加到父布局中,没有修改任何参数。可以重写include中的最外层根目录的属性,但是必须重写<layout_height><layout_width>两个属性。
<merge>
出现在被复用的布局文件中,最后还是通过include标签将其添加到父布局中,但是添加到父布局中之后,可以看成<merge>标签自动消失。此处的布局文件直接嵌入到父布局文件中。前面的<include xml>是通过一个根(如FrameLayout)嵌套进父布局中的。
Reference:
http://www.jianshu.com/p/61b79e7f88fc(介绍attr)
https://developer.android.com/guide/topics/resources/available-resources.html(所有resource、android官方资料)