Java初学者直接在Java源码使用"hello" 和123 类型的字符串和整型,但时间长了就会忘记当初定义的原因,有经验的也许会定义字符串常量ResultSet.TYPE_FORWARD_ONLY,有经验的一看就知道其原因,这种写法已经降低了耦合性,Android则对这些字符串常量、数值常量进行进一步的改进:把用到的各种资源字符串常量、颜色资源、数组资源、菜单资源都集中放到res目录下,应用程序则直接使用这些资源中定义的值。
资源类型及存储方式
Android应用资源可分为两大类:
1.无法通过R清单类访问的原生资源,保存在assets目录下
2.可通过R资源清单类访问的资源,保存在res目录下
资源存储:
/res/animator 存放定义属性动画的XML文件
/res/anim 定义补间动画的XML文件
/res/color 存放定义不同颜色下颜色列表的XML文件
/res/drawable 存放位图(png,jpg,gif)和Drawable对象(BItmapDrawable,NinePatchDrawable,StateListDrawable,AnimationDrawable,Drawable)
/res/layout 存放各种用户界面的布局文件
/res/menu 存放为应用程序定义的各种菜单的资源,包括选项菜单,子菜单,上下文菜单资源
/res/raw 存放任意类型的原生资源(例如音频,视频等)在Java代码中调用Resource对象的openRawResource(int id)方法获取该资源二进制输入流。
/res/values 存放简单值的XML文件,包括字符串、数组、整数、颜色等。都存放在<resources></resources>节点下。建议不同类型存放在不同XML文件中。
使用方式:
Java代码中
<package_name>.R.<resource_type>.<resouece_name>
例如:android.R.layout.simple_expandable_list_item_1 引用Java程序所在的R类的包,包名可以省略
其实上述写法并不是引用真正的资源对象,而是Andoird应用的API允许直接使用int类型的资源清单项代替应用资源。获取实际资源可以借助Resource类(Android资源访问总管家)。Resource主要提供两类方法:
getXxx(int id):根据自愿清单ID来获取实际资源
getAssets() :获取访问/assets/目录下资源的AssetManager对象
Resource由Context调用getResource()方法来获取
//获取Resource
Resources res = getResources();
//获取字符串资源
String mainTitile = res.getText(R.string.main_titile);
//获取Drawable资源
res.getDrawable(R.drawable.ic_launcher);
//获取数组资源
int [] arr = res.getIntArray(R.array.books);
<resources>
<color name="red">#ff00</color>
<string name="hello">Hello</string>
</resources>
控件引用
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/red">
</TextView>
array资源
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="@array/test"></ListView>
<resources>
<string-array name="test">
<item>1</item>
<item>2</item>
<item>3</item>
<item>@string/hello_world</item>
</string-array>
上面代码可以看出资源之前可以相互引用。
StateListDrawable资源
StateListDrawable用于组织多个Drawable对象。当使用StateListDrawable作为目标组件的背景,前景图片时,StateListDrawable对象多显示的Drawable对象会随目标组件状态的改变而自动切换。
定义StateListDrawable对象的XML文件的根元素为<selector..../> 该元素可以包含多个<item..../>可以指定
android:color或android:drawable指定颜色或Drawable对象。
android:state_xxx:指定一个特定状态(active、checked、last、pressed等)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="德玛西亚"
android:textColor="@drawable/my_color" >
</EditText>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="盖伦"
android:textColor="@drawable/my_color" >
</EditText>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 获取焦点时的颜色 -->
<item android:state_focused="true" android:color="#f44"></item>
<!-- 失去焦点时颜色 -->
<item android:state_focused="false" android:color="#455"></item>
</selector>
LayerDrawable资源
与StateListDrawable有点类似,LayerDrawable也可包含一个Drawable数组,因此系统将会按这些Drawable对象的数组顺序来绘制它们,索引最大的Drawable对象将会被绘制在最上面。
定义LayerDrawable对象的XML文件的根元素为<layer-list...../>,该元素可以包含多个<item..../>元素,可以指定如下属性:
android:drawable:指定作为LayerDrawable元素之一的Drawable对象
android:id为该Drawable对象指定唯一标识
android:buttom|top|button:它们用于指定一个长度值,用于指定将该Drawable对象绘制到目标组件的指定位置。
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<SeekBar
android:id="@+id/bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100"
android:progressDrawable="@drawable/my_bar"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/layout_logo"/>
</LinearLayout>
my_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 定义轨道背景 -->
<item android:id="@android:id/background" android:drawable="@drawable/ic_launcher"></item>
<item android:id="@android:id/progress" android:drawable="@drawable/b"></item>
</layer-list>
layout_logo.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<bitmap
android:gravity="center"
android:src="@drawable/ic_launcher" />
</item>
<item android:top="25dp" android:left="25dp">
<bitmap
android:gravity="center"
android:src="@drawable/ic_launcher" />
</item>
<item android:top="50dp" android:left="50dp">
<bitmap
android:gravity="center"
android:src="@drawable/ic_launcher" />
</item>
</layer-list>
效果图:
上述代码可以看出ImageView的src可以指定图片,还可以是layer(图层),图层item中定义每个显示的Bitmap图片和所在的位置<bitmap android:gravity="center" >这里所说的居中是相对于ImageView空间容器大小的居中。
SharpDrawable资源
之前UI简单美化提过,这个就不说了
ClipDrawable资源
ClipDrawable代表从其他的位图上截取一个"图片片段",在XML文件中定义ClipDrawable对象使用<clip....../>元素,语法为:
<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_launcher"
android:clipOrientation="horizontal|vertical"
android:gravity="top|bottom|right">
</clip>
使用ClipDrawable对象时可调用setLevel(int level) 方法来设置截取的大小,0截取的图片为空;10000时,截取整张图片
利用level慢慢展开的风景,当点击图片时自动全部显示
public class MainActivity extends Activity {
private ImageView img;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
img = (ImageView) findViewById(R.id.img);
//获取图片所显示的ClipDrawable对象
final ClipDrawable drawable = (ClipDrawable) img.getDrawable();
final Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what==0x123){
//修改ClipDrawable的level的值
drawable.setLevel(drawable.getLevel()+20);
}
}
};
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
Message msg = new Message();
msg.what=0x123;
//发送消息通知应用修改ClipDrawable对象的level的值
handler.sendMessage(msg);
if(drawable.getLevel()>=10000){
timer.cancel();
}
}
}, 0, 300);
img.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
drawable.setLevel(10000);
}
});
}
}
上面代码其实就是时刻的在改变裁减之后的值在显示形成的徐徐展开效果。
AnimationDrawable资源
AnimationDrawable代表一个动画,支持帧动画和补间动画。
定义补间动画的XML资源文件以<set..../>元素作为根元素,该元素可以指定a:lpha透明度、scale缩放、translate位移、ratate旋转。动画存放路径res/animi。ADT创建android应用时不带有该路径,需要手动创建。
MainActivity.java
public class MainActivity extends Activity {
ImageView imageView1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView1=(ImageView) findViewById(R.id.imageView1);
//加载动画资源
final Animation animation = AnimationUtils.loadAnimation(this, R.anim.set_test);
//设置动画结束后保留结束状态
animation.setFillAfter(true);
Button bn = (Button) findViewById(R.id.bn);
bn.setText("开始动画");
bn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//开始动画
imageView1.startAnimation(animation);
}
});
}
}
set_test.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator"
android:duration="5000">
<!-- 定义缩放变换 -->
<scale android:fromXScale="1.0"
android:toXScale="1.4"
android:fromYScale="1.0"
android:toYScale="0.6"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="true"
android:duration="2000"/>
<!-- 定义位移变换 -->
<translate
android:fromXDelta="10"
android:toXDelta="130"
android:fromYDelta="30"
android:toYDelta="-80"
android:duration="2000"/>
</set>
Property Animation资源
Animation代表一个属性动画,但它只是一个抽象类,通常会使用它的子类:AnimatorSet、ValueAnimator、ObjectAnimator、TimeAnimator。需要animator目录,创建项目的时候没有。手动创建。
定义属性动画XML资源能以三个元素中的任意一个作为根元素
<set...../> 它是一个父元素,用于包含其他<objectAnimator>或者<set.../>子元素,该属性定义的资源代表AnimatorSet对象
<objectAnimator.../>用于定义ObjectAnimtor动画
<animator.../> 用于定义ValueAnimator动画
背景颜色一直变化的Demo
public class MainActivity extends Activity {
ImageView imageView1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout l = (LinearLayout)findViewById(R.id.container);
l.addView(new MyAnimtionView(this));
}
public class MyAnimtionView extends View{
public MyAnimtionView(Context context) {
super(context);
//加载动画资源
ObjectAnimator colorAnim = (ObjectAnimator) AnimatorInflater.loadAnimator(context, R.animator.object_test);
colorAnim.setEvaluator(new ArgbEvaluator());
//对该View本身应用属性动画
colorAnim.setTarget(this);
//开始动画
colorAnim.start();
}
}
}
res/animator/object_test.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="backgroundColor"
android:duration="3000"
android:valueFrom="#FF8080"
android:valueTo="#8080FF"
android:valueType="intType"
android:repeatCount="infinite"
android:repeatMode="reverse"
>
</objectAnimator>
总结:
资源名 目录 根节点
StateListDrawable Drawable <selector..../>
LayerDrawable Drawable <layer-list..../>
Property Animation animator <objectAnimator.../>
SharpDrawable Drawable <shape...../>
AnimationDrawable anim <set..../>