Pro Android学习笔记(三):了解Android资源(上)

在Android开发中,资源包括文件或者值,它们和执行应用捆绑,无需在源代码中写死,因此我们可以改变或替换他们,而无需对应用重新编译。

了解资源构成

参考阅读Android学习笔记(三八):资源resource(上)、XML解析(XmlPullParser)Android学习笔记(三九):资源resource(下)

Strings资源。位于res/values下,可以有一个或多个xml文件。其中最为常见的是strings.xml,对于demo这类小例子,为了方便常全部都放在strings.xml中,但实际开发中,应进行合理组织。下面事xml文件的例子:

<?xml version="1.0" encoding="utf-8"?>
<resources> 
    <string name="app_name">Pro Android</string> 
    <string name="action_settings">Settings</string> 
    <string name="resource_test">Understanding Resources</string> 
</resources>

需要留意,对于标准的xml文件,有xmlns来指明schema,在此可以省略。如果非要加上,可以为:<resources xmlns="http://schemas.android.com/apk/res/android" >。每定义一个string,在R.java文件中将自动生成ID,由此可以通过ID,如R.string.app_name进行对应,ID事int,但Android或根据需要转换为对应的string。

public final class R { 
    … … 
    public static final class string { 
        public static final int action_settings=0x7f050001; 
        public static final int app_name=0x7f050000; 
        public static final int resource_test=0x7f050002; 
    } 
    … … 
}

Layout资源。res/layout下放着关键的View,每个activity或者每个screen要单独xml来描述。在代码用setContentView ( R.layout.xxxx ) 来进行映射。而layout xml文件中的view,则用R.id.xxxx来映射,可以通过findViewById来获取具体view的对象。

Resource Reference Syntax资源参考语法。用于分配在Android xml文件某个资源的ID的语法称为资源参考语法,具体为@[ package:] type/name,例如android:id="@+id/t1"。”+”表示如果t1的id没有定义为资源,去为它定义一个唯一的Id号码。实际上,我们可以预先定义id,以后再使用,方式如下,在res/values下的xml文件中进行定义。定义后,我们将在R.java文件中发现有关的R.id.t2的定义,如是,我们将使用android:id="@id/t2"。

<resources> 
    <item type="id" name="t2"/> 
</resources>

这里的type是对应R.java里面的资源类别的namespace,例如R.string则对应为string。此外可以是drawable,id,layout,string,attr,plurals,string-array(在R.java中为R.array)。这里的name,是指资源的名称,也对应R.java中ID名字。如果没有package,就是使用本地资源,和本app的R.java中。Andriod同时也提供了一些组件,例如ListView,使用<ListView android:id=”@android:id/list”…… />,这使用了android.R.java文件,实时上,我们可以使用其他包名,用该包下的R.java文件来解释。

编译和非编译的资源。资源来源两类文件:XML和raw文件,对应的也可以分为编译为二进制格式的,和非编译直接copy的。对于一般的资源XML文件,需要将XML的节点翻译的ID,所以需要编译为binary。其中res/xml中可放置任何XML格式的文件,如们自定的,可以通过R.xml.<file_name>来指向该资源,并用Android提供的XML reader来解析,如XMLPullPaser。

非编译为binary的文件位于res/raw,和所有res/下的资源一样,可用R.raw.<file_name>来获取该资源。读取是需使用stream-based的API,如下。audio和video文件属于这类raw文件,当然如果我们需要,也可以将一个xml文件放入res/raw目录下,作为raw文件来使用。

BufferedReader reader=new BufferedReader(new InputStreamReader(getResources().openRawResource(R.raw.w_city_code)));

主要的关键资源

String Arrays。位于res/values/*.xml,格式如下:

<?xml version="1.0" encoding="utf-8"?>
<resources> 
    <string-array name="rt_test_array"> 
        <item>one</item> 
        <item>two</item> 
        <item>three</item> 
    </string-array
</resources>

在R.java中自动生成ID,可以在用R.array.xxxx来调用

public final class R { 
    public static final class array { 
        public static final int rt_test_array=0x7f050000; 
    }   
   … …  
}

在程序中可以如下调用

//通过getResources()获取activity的resource对象,通过该对象获取string-array资源
String strs[] = getResources().getStringArray(R.array.rt_test_array);
for(String s: strs){ 
   …… 
}

复数Plurals。这对中文而言没有什么意义,但是在英文中,有There is one egg. 和There are 5 eggs. 的区别。需要在信息表达方面进行区分对待,plurals就是针对此进行处理。

在quantity中有效的选择显示有6个,但是如果locale为en时,实际有效的是“one”和“other”,设置其余的,经试验,并无效果。书中言,对于其他的语言设置也是这样,除了捷克语,对于2-4,对应为few。

Resources res = getResources();  //获取资源对象 
//res.getQuantityString(),第一个参数为plurals的ID,第二参数为0,对应quantity的选择,由于有效的只有1和其他,则对应other,因此s1为There are %d eggs.
String s1= res.getQuantityString(R.plurals.rt_test_plurals, 0); 
//第二个参数为0,对应other,第三个参数为2,是根据format对%d的填充,即为There are 0 eggs.
s1= res.getQuantityString(R.plurals.rt_test_plurals, 0,2); 
//第二个参数为1,对应one,即为There is 1 egg. 
s1= res.getQuantityString(R.plurals.rt_test_plurals, 1); 
//第二个参数为1,对应one,由于format没有需要填入,为There is 1 egg.
s1= res.getQuantityString(R.plurals.rt_test_plurals, 1,1); 
//第二个参数为2,对应other,由于format有input,为There are 6 eggs.
s1= res.getQuantityString(R.plurals.rt_test_plurals, 2,6);

Wei:经过试验,在XML中用%s来替代%d是可行的,但是如果input的数目超过1个,如2个或以上,则在编译时会报错。plurals就只是为了处理西文中复数的问题,不要搞得太复杂。对于上面的例子,第二和第三参数应该匹配,这样才便于阅读,例如res.getQuantityString(R.plurals.rt_test_plurals,6,6)。

再谈String。string资源可以带有输入,可以带有html格式。我们看看以下的string资源的获取和输出。

我们通过下面的代码在TextView tv中进行输入。


tv.append ( getString(R.string.rt_simple_string)) );
tv.append (“\n”)); 
...... //依次在tv中显示string 
tv.append ( getString(R.string.rt_format_string,"World","my friend") );
...... //依次在tv中显示string

//特别留意最后两个。在资源中带有HTML的格式,如果仍用<b></b>,在获取资源时,这部分信息会消失,需要用&lt; 和 &gt; 来表示左右尖括号。多少有些麻烦。此外要使HTML格式有效,需要告知TextView这是一个HTML格式,否则会直接将<b></b>作为字符串内容显示。下面试验再次证明需要将尖括号改写。

tv.append ( Html.fromHtml( getString(rt_html_string1) + "<br/>") );
tv.append ( Html.fromHtml( getString(rt_html_string2)+ "<br/>") );

我们可以在view中直接引用string,如 andriod:text=”@string/rt_simple_string”。

Color。color资源同样在res/values/下面定义。

<color name="rt_blue">#0000f0</color>

代码调用如下。处理我们定义,我们还可以使用Android预定义的一些颜色,具体可以参考http://developer.android.com/reference/android/R.color.html#background_light

int color = getResources().getColor(R.color.rt_blue);
tv.setTextColor(color); 
tv.setBackgroundColor(getResources().getColor(android.R.color.background_dark));

Dimension。同样,在res/values/下任何xml文件可以定义

<dimen name="rt_dp">5dp</dimen>,
其中dp为Android的尺寸单位,Android长度单位详解(dp、sp、px、in、pt、mm、dip) ,android中定义的dimension单位有以下这些:
px(Pixels ,像素)            :对应屏幕上的实际像素点。 
in(Inches ,英寸)            :屏幕物理长度单位。 
mm(Millimeters ,毫米):屏幕物理长度单位。 
pt(Points ,磅)               :屏幕物理长度单位,1/72英寸。 
dp(与密度无关的像素)     :逻辑长度单位,在 160 dpi 屏幕上,1dp=1px=1/160英寸。随着密度变化,对应的像素数量也变化,但并没有直接的变化比例。
dip                                      :与dp相同,多用于Google示例中。 
sp(与密度和字体缩放度无关的像素):与dp类似,但是可以根据用户的字体大小首选项进行缩放。

从资源中获取dimension如下,可以在setTextSize( )等场合使用dimension,或者直接在XML中设置android:textSize="@dimen/rt_dp"

float dimen = getResources().getDimension(R.dimen.rt_dp);

Image资源。由于手机尺寸的不同,同一个图片,可制造成不同的尺寸,放置在res/drawable-?dpi中,系统会进行自动选择,ic_launcher图标。我们也可以不考虑手机实际尺寸,使用同一个图标,可以放置在res/drawable中。试验,为了简单,采用同一尺寸。图片的格式可以是*.gif,*.jpg和*.png。

实验中我们将sample_image.png放置到drawble。在XML中可以如下引用


第一个图中图片出现伸拉

<Button android:id="@+id/vt_button1"
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/resource_test" 
    android:background="@drawable/sample_image"/
<ImageButton android:id="@+id/vt_img_button3" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:contentDescription="@string/resource_test" 
    android:src="@drawable/sample_image"/>

当然,也可以在java编码中来调用。如下

Drawable d = getResources().getDrawable(R.drawable.sample_image); 
button.setBackground(d); 
等同于下面 
button.setBackgroundResource(R.drawable.ic_launcher); 
绝大部分的view都具有setBackground的方法。

Wei:在Android的API Guides中这样写道:A bitmap graphic file (<.png, .jpg, or .gif). Creates a BitmapDrawable. 但getDrawable()返回的Drawble。同样根据API Guides,我们可以通过设置bitmap xml来,而这个输出BitmapDrawable,该XML放置在res/drawable/下,如下

<?xml version="1.0" encoding="utf-8"?>
<bitmap
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@[package:]drawable/drawable_resource"
    android:antialias=["true" | "false"]
    android:dither=["true" | "false"]
    android:filter=["true" | "false"]
    android:gravity=["top" | "bottom" | "left" | "right" | "center_vertical" |
                      "fill_vertical" | "center_horizontal" | "fill_horizontal" |
                      "center" | "fill" | "clip_vertical" | "clip_horizontal"]
    android:tileMode=["disabled" | "clamp" | "repeat" | "mirror"] />

Color-Drawable资源。在了image外,drawable资源还可以是color-drawable,也就是一个颜色方框。定义颜色方框,可以在res/values中任何XML文件中加入:

<resource> 
    <drawable name="red_rectangle">#f00</drawable> 
    <drawable name="blue_rectangle">#0000ff</drawable> 
    <drawable name="green_rectangle">#00f0f0</drawable> 
</resource>

在view的xml中,同样可以设置

android:background="@drawable/red_rectangle"

或者在java code里面

Button b1 = (Button)findViewById(R.id.vt_button0);
ColorDrawable grDrawble = (ColorDrawable)getResources().getDrawable(R.drawable.green_rectangle);
b1.setBackground(grDrawble);

在实际效果如下

一片颜色不好看,要进行复杂地设置,需要单独在一个 xml文件中,通过shape来描述。该文件放置在res/drawable/目录下。下面是my_round_red_retangle.xml的内容

<?xml version="1.0" encoding="utf-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <solid android:color="#f0600000"/> <!-- 这是底层 --> 
    <stroke android:width="3dp" android:color="#ffff8080" /> <!-- 这是边框 --> 
    <corners android:radius="13dp"/> <!-- 设置圆角 -->
    <padding android:left="10dp" android:top="10dp" android:bottom="10dp" android:right="10dp" />
</shape>

在java code的使用如下,也可以用android:background="@drawable/my_round_red_rectangle"。Wei:根据Android API Guide,使用的类型是SpanDrawable,如是,会出错,还是用用GradientDrawable。

Button b2 = (Button)findViewById(R.id.vt_button2);
GradientDrawable roundTangle = (GradientDrawable) getResources().getDrawable(R.drawable.my_round_red_rectangle);
b2.setBackground(roundTangle);

再给出一个例子

<?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"/> 
    <corners android:radius="8dp"/> 
</shape>

相关链接: 我的Android开发相关文章

时间: 2024-10-19 19:59:41

Pro Android学习笔记(三):了解Android资源(上)的相关文章

Android学习笔记三:Intent实现页面跳转

在主Activity的OnCreate()方法中,通过findViewById得到Activiity_main中已定义的组件,例如Button.EditText等,注意需要强制转型view到具体的类型. 给取得的组件btn添加监听器如OnClickListener(),在其中实例化Intent对象,参数为要跳转的出发类和目标类. 用putExtra()方法添加内容到intent对象中,内容为K-V对.K中可写标记,V中存要传输的内容. public void onClick(View arg0)

Android学习笔记进阶之在图片上涂鸦(能清屏)

Android学习笔记进阶之在图片上涂鸦(能清屏) 2013-11-19 10:52 117人阅读 评论(0) 收藏 举报 HandWritingActivity.java [java] view plaincopy package xiaosi.handWriting; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import andro

android学习笔记40——国际化和资源自适应

国际化——Internationalization,简称I18N. 本地化——Localization,检查L10N. java国际化资源的思路: java提供国际化资源的思路,是将程序中的标签.提示信息放在资源文件中,程序需要支持那些语音,就需要提供对应的资源文件. 资源文件是key-value类型,每个资源文件的key一致,value随不同语音而改变. java国际化主要通过如下三个类完成: 1.java.util.ResourceBundle——用于加载一个国家.语言资源包: 2.java

android学习笔记39——使用原始资源

原始资源 android中没有专门提供管理支持的类型文件,都被称为原始资源.例如:声音资源... android原始资源存放位置: 1.res/raw,android SDK会处理该目录下的原始资源,会在R清单中生成唯一索引 2./assets/,该目录下的资源是更彻底的原始资源.android通过AssetManager来管理该目录下的原始资源 注意:原始资源通过SDK生成的唯一索引的使用方式同其他资源使用方式一致.EG:R.raw.filename/@raw.filename AssetMa

Android学习笔记:对Android应用进行单元测试

原文地址:http://blog.csdn.net/duancanmeng/article/details/7458851 第一步:在AndroidManifest.xml中加入如下两段代码: <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.pccw" android:versionCode="1" android:versi

Android学习笔记十六.Android数据存储与IO.SharedPreferences

SharedPreferences 对于应用程序的数据输入.输出,如果是应用程序只是少量数据需要保存,那么使用普通文件就可以了(SharedPrefereces);但如果应用程序有大量数据需要存储.访问,就需要借助数据库了.Android系统内置了SQLite数据库,SQLite数据库是一个真正轻量级的数据库,它没有后台进程,整个数据库就对应于一个文件. 1.SharedPreferences简介 (1)概念:SharedPreferences保存的数据主要是类似于配置信息格式的数据,因此它保存

Android学习笔记(三)

ContentProvider简介 ContentProvider是不同应用程序之间进行数据交换的标准API,当一个应用程序需要把自己的数据暴露给其他程序使用时,该应用程序便可通过提供ContentProvider来实现,其他应用程序就可通过ContentResolver来操作ContentProvider暴露的数据.如果某一应用程序通过ContentProvider暴露了自己的数据操作接口,则不管该应用程序是否启动,其他应用程序都可以通过该接口来操作该应用程序的内部数据,包括增加.删除.修改.

Android学习笔记三:用Intent串联activity

一:Intent Intent可以理解为 意图. 我们可以通过创建intent实例来定义一个跳转意图,意图包括:要跳转到哪个页面.需要传递什么数据. 然后通过startActivity(intent)来启动跳转. 有两种方式定义Intent:显式Intent.隐式Intent. 二:显式Intent 1)我们可以在actvity的java文件中,通过代码显示定义Intent,参数为:从哪个页面,跳转到哪个页面. Intent intent = new Intent(FirstActivity.t

Android学习笔记----解决“com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536”问题

同时在工程中引入了多个第三方jar包,导致调用的方法数超过了android设定的65536个(DEX 64K problem),进而导致dex无法生成,也就无法生成APK文件. 解决办法如下: 1.谷歌官方已经给出了相关的文档,参照网上搜索的资料,首先,我的问题是: Error:Execution failed for task ':duchazhushou:dexRelease'. > com.android.ide.common.internal.LoggedErrorException:

Android学习笔记—第二章 Android四大组件

第二章 Android四大组件 Activity(活动窗口): Android程序中最基本的模块,为用户操作而展示的可视化用户界面.一个Android应用程序可以只有一个Activity,也可以包含多个Activity,数量及每个Activity的作用取决于应用程序及其设计. (1)Activity的生命周期 创建→运行   onCreate   onStart   onResume 运行→销毁   onPause    onStop    onDestory 运行→停止(不可见  不可操作)