Android命名空间的使用总结

       Android的命名空间在开发中使用的频率其实是比较少的,但是对于开发者来说还是要学会简单使用的,它的作用场合一般是用户自定义View的组件中!
       简单的应用举例,比如:一个自定义的进度条组件,在布局文件中设置好最大值,然后用自定义组件的代码来获取布局文件中设置的数字。
       Android命名空间实际考查的是资源文件Attribute的获取使用!

一.Android命名空间的基础知识要点

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>

(二)自定义组件的创建MyView,以及获取资源数据的设置,主要代码:

//获取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命名空间的知识点就大概介绍完毕了。
下面是介绍两个示例程序:

二.命名空间的属性值的获取

(一)資源文件的定义,文件名attrs.xml在res/values目录下

<?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);

    }

}

(三)布局文件activity_main.xml中的调用

<?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);是不能少的!
运行程序后,显示的界面:
j1
上面没啥内容,重点是资源数据的获取,下面是Log的数据:
j2
       到这里资源文件的数据就能成功获取了!Android命名空间的使用也是简单演示使用了一遍!

三.下面是命名空间的一个简单应用

       设计一个自定义的ImageView图片组件,在布局文件中设计几秒后完全显示它的图片!
效果:
s3
设计过程:

(一)资源文件的定义

资源文件放在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);//这里是自己给自己发消息!
                }

            }

        };
    };

}

       上面图片每次透明度的改变可以用定时器来设计,但是定时器要用到子线程,有时程序退出线程还在执行,所以我一般尽量少用线程相关的。

(三)布局文件activity_main.xml中的调用

<?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);
    }
}

       上面程序中可以看到程序的调用是很方便的,只要把自定义的组件复制进去后,可以直接在布局文件中调用和设置组件的参数。这也许就是命名空间的方便的地方,也就是调用方便(方便调用者),但是设计起来还是要写多一些代码。

三.Android命名空间的总结

(一)资源文件中的知识

定义资源文件示例代码:

<?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>

1.attr元素作用:

       定义一个属性,可以在布局文件中使用命名空间的名称结合属性定义属性的具体值。

2.declare-styleable子元素:

       定义一个styleable对象,每个styleable对象就是一组attr属性的集合,里面可以定义多个定义好的属性,使用java代码可以获取该组集合里面属性的值。
       命名空间资源文件代码的文件的命名也是任意的,但是为了更好标识一般写attrs.xml

(二)命名空间xmlns的名称:

       名称是可以任意的,下面使用的命名空间名称也是上面必须的,上面的命名空间名称是myxmlns。
       xmlns表示的是命名空间的意思,这里可以看到根布局中必须要有一个android的命名空间,并且格式也是固定的,只有定义了android系统的命名空间才能使用android中某些组件的的属性,比如android:textSize=“18” 后android:backColor=“#f00”等等。

(三)最后强调一下命名空间的作用:

       命名空间可以直接在布局文件中定义好自定义属性的一些属性,调用时只要在布局文件中设置属性,而不用再去代码中设置,但是自定义组件中必须要做代码处理(获取和设置!)。
       简单的说就是提前做处理,调用方便!
       但是正常开发的程序中很少用到
       除非是你经常要用到打自定义组件,并且要设置多个属性值,可以考虑使用命名空间,简化调用程序步骤!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

峥嵘life

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值