赞
踩
Android的命名空间在开发中使用的频率其实是比较少的,但是对于开发者来说还是要学会简单使用的,它的作用场合一般是用户自定义View的组件中!
简单的应用举例,比如:一个自定义的进度条组件,在布局文件中设置好最大值,然后用自定义组件的代码来获取布局文件中设置的数字。
Android命名空间实际考查的是资源文件Attribute的获取使用!
Android命名空间有三部分内容:
资源文件放在res/calues目录下,(文件名任意,一般设置为attrs.xml)示例代码:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--定义属性 -->
<attr name="titleName"/>
<attr name="numberOne"/>
<attr name="numberTwo"/>
<!--定义styleable对象来组合多个属性 -->
<declare-styleable name="MyViewStyle">
<attr name="titleName"/>
<attr name="numberOne"/>
</declare-styleable>
</resources>
//获取styleable资源对象
TypedArray typeArray=context.obtainStyledAttributes(attrs,R.styleable.MyViewStyle);
//获取styleable资源对象里面的字符串
String name=typeArray.getString(R.styleable.MyViewStyle_titleName);
//获取styleable资源对象里面的数字
int numberOne=typeArray.getInt(R.styleable.MyViewStyle_numberOne, 0);
上面styleable中是字符串还是数字是一般由布局文件中来设置就可以(属性值后面的值有字母或符号就是字符串,),当然也可以在资源文件中定义好,比如上面资源文件中
<!--定义属性 -->
<attr name="titleName" format="string"/>
<attr name="numberOne" format="integer"/>
这时如果布局文件中的numberOne为字符串时也是会报错!
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myxmlns="http://schemas.android.com/apk/res/com.example.attribute"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<!--使用自定义组件,并指定属性资源文件中的属性 -->
<com.example.attribute.MyView
android:layout_width="match_parent"
android:layout_height="20dp"
android:background="#f00"
myxmlns:titleName="这是我的测试命名空间的标题"
myxmlns:numberOne="100"
myxmlns:numberTwo="200"
/>
</LinearLayout>
上面有两个关键的地方要注意:
一个是命名空间的定义,这里名称myxmlns是任意定义的,但是”=”后面的固定格式:”http://schemas.android.com/apk/res/+自定义组件的包名。
另一个是命名空间后面的属性,必须要在资源文件中定义好,如下:
<!--定义属性 -->
<attr name="titleName"/>
<attr name="numberOne"/>
<attr name="numberTwo"/>
之后这里才能在布局文件中设置的就是这三个属性:
myxmlns:titleName="这是我的测试命名空间的标题"
myxmlns:numberOne="100"
myxmlns:numberTwo="200"
如果没有定义好直接设置是后报错的,比如这里写:
myxmlns:numberThree=”300”,因为numberThree没有在资源文件中定义!
到这里Android命名空间的知识点就大概介绍完毕了。
下面是介绍两个示例程序:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--定义属性 -->
<attr name="titleName" format="string"/>
<attr name="numberOne" format="integer"/>
<attr name="numberTwo"/>
<!--定义styleable对象来组合多个属性 -->
<declare-styleable name="MyViewStyle">
<attr name="titleName"/>
<attr name="numberOne"/>
</declare-styleable>
<!-- 定义styleable2对象来组合多个属性 -->
<declare-styleable name="MyViewStyle2">
<attr name="titleName"/>
<attr name="numberOne"/>
<attr name="numberTwo"/>
</declare-styleable>
</resources>
上面可以创建多个styleable组合,组合里面可以有一个或多个定义好的属性。
package com.example.attribute;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
public class MyView extends View{
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
//获取styleable资源对象
TypedArray typeArray=context.obtainStyledAttributes(attrs,R.styleable.MyViewStyle);
//获取styleable资源对象里面的字符串
String name=typeArray.getString(R.styleable.MyViewStyle_titleName);
//获取styleable资源对象里面的数字
int numberOne=typeArray.getInt(R.styleable.MyViewStyle_numberOne, 0);
//获取第二组styleable资源对象
TypedArray typeArray2=context.obtainStyledAttributes(attrs,R.styleable.MyViewStyle2);
String name2=typeArray2.getString(R.styleable.MyViewStyle2_titleName);
int numberOne2=typeArray2.getInt(R.styleable.MyViewStyle2_numberOne, 1);
int numberTwo2=typeArray2.getInt(R.styleable.MyViewStyle2_numberTwo, 2);
//打印第一组styleable资源对象里面的数据
Log.e("TAG","typeArray中titleName="+name+",numberOne="+numberOne);
///打印第二组styleable资源对象里面的数据
Log.e("TAG","typeArray2中titleName="+name+",numberOne="+numberOne+",numberTwo="+numberTwo2);
}
public MyView(Context context) {
super(context);
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myxmlns="http://schemas.android.com/apk/res/com.example.attribute"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="命名空间" />
<!--使用自定义组件,并指定属性资源文件中的属性 -->
<com.example.attribute.MyView
android:layout_width="match_parent"
android:layout_height="20dp"
android:background="#f00"
myxmlns:titleName="这是我的测试命名空间的标题"
myxmlns:numberOne="100"
myxmlns:numberTwo="200"
/>
</LinearLayout>
这里MainActivity中没有什么代码就不写了,但是oncreate中的setContentView(R.layout.activity_main);是不能少的!
运行程序后,显示的界面:
上面没啥内容,重点是资源数据的获取,下面是Log的数据:
到这里资源文件的数据就能成功获取了!Android命名空间的使用也是简单演示使用了一遍!
设计一个自定义的ImageView图片组件,在布局文件中设计几秒后完全显示它的图片!
效果:
设计过程:
资源文件放在res/calues目录下,attrs.xml代码:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--定义属性 -->
<attr name="duration" format="integer"/>
<!--定义styleable对象来组合一个或多个属性 -->
<declare-styleable name="MyViewStyle">
<attr name="duration"/>
</declare-styleable>
</resources>
package com.example.attribute2;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;
public class MyImageView extends ImageView{
//图片透明度每次改变的大小
int alphaDelta=0;
//记录图片当前的透明度
int curAlpha=0;
//每隔多少秒改变一次
final int SPEED=300;//300毫秒改变一次透明度
public MyImageView(Context context, AttributeSet attrs) {
super(context, attrs);
//获取styleable资源对象
TypedArray typeArray=context.obtainStyledAttributes(attrs,R.styleable.MyViewStyle);
//获取styleable资源对象里面的数字
int duration=typeArray.getInt(R.styleable.MyViewStyle_duration, 1000);
Log.e("TAG","duration="+duration);
//计算每次改变的透明度的大小
alphaDelta=255*SPEED/duration;
setImageAlpha(curAlpha);//刚开始不显示
//按发送消息,通知系统改变图片的透明度
handler.sendEmptyMessageDelayed(111, SPEED);
}
public MyImageView(Context context) {
super(context);
}
Handler handler=new Handler(){
public void handleMessage(android.os.Message msg) {
if (msg.what==111) {
if (curAlpha>=255) {
curAlpha=255;
MyImageView.this.setImageAlpha(curAlpha);
handler.removeMessages(111);
}else{
//每次增加curAlpha的值
curAlpha+=alphaDelta;
MyImageView.this.setImageAlpha(curAlpha);
Log.e("TAG","curAlpha="+curAlpha);
//按发送消息,通知系统改变图片的透明度
handler.sendEmptyMessageDelayed(111, SPEED);//这里是自己给自己发消息!
}
}
};
};
}
上面图片每次透明度的改变可以用定时器来设计,但是定时器要用到子线程,有时程序退出线程还在执行,所以我一般尽量少用线程相关的。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myxmlns="http://schemas.android.com/apk/res/com.example.attribute2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="这是一个慢慢显示的图片" />
<!--使用自定义组件,并指定属性资源文件中的属性 -->
<com.example.attribute2.MyImageView
android:src="@drawable/yts"
android:layout_width="match_parent"
android:layout_height="match_parent"
myxmlns:duration="6000"
/>
</LinearLayout>
package com.example.attribute2;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
上面程序中可以看到程序的调用是很方便的,只要把自定义的组件复制进去后,可以直接在布局文件中调用和设置组件的参数。这也许就是命名空间的方便的地方,也就是调用方便(方便调用者),但是设计起来还是要写多一些代码。
定义资源文件示例代码:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--定义属性 -->
<attr name="titleName"/>
<attr name="numberOne"/>
<attr name="numberTwo"/>
<!--定义styleable对象来组合多个属性 -->
<declare-styleable name="MyViewStyle">
<attr name="titleName"/>
<attr name="numberOne"/>
</declare-styleable>
</resources>
布局文件的示例代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myxmlns="http://schemas.android.com/apk/res/com.example.attribute"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<!--使用自定义组件,并指定属性资源文件中的属性 -->
<com.example.attribute.MyView
android:layout_width="match_parent"
android:layout_height="20dp"
android:background="#f00"
myxmlns:titleName="这是我的测试命名空间的标题"
myxmlns:numberOne="100"
myxmlns:numberTwo="200"
/>
</LinearLayout>
定义一个属性,可以在布局文件中使用命名空间的名称结合属性定义属性的具体值。
定义一个styleable对象,每个styleable对象就是一组attr属性的集合,里面可以定义多个定义好的属性,使用java代码可以获取该组集合里面属性的值。
命名空间资源文件代码的文件的命名也是任意的,但是为了更好标识一般写attrs.xml
名称是可以任意的,下面使用的命名空间名称也是上面必须的,上面的命名空间名称是myxmlns。
xmlns表示的是命名空间的意思,这里可以看到根布局中必须要有一个android的命名空间,并且格式也是固定的,只有定义了android系统的命名空间才能使用android中某些组件的的属性,比如android:textSize=“18” 后android:backColor=“#f00”等等。
命名空间可以直接在布局文件中定义好自定义属性的一些属性,调用时只要在布局文件中设置属性,而不用再去代码中设置,但是自定义组件中必须要做代码处理(获取和设置!)。
简单的说就是提前做处理,调用方便!
但是正常开发的程序中很少用到
除非是你经常要用到打自定义组件,并且要设置多个属性值,可以考虑使用命名空间,简化调用程序步骤!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。