【UI篇】Android布局理解之xmlns

1、什么是xmlns?有什么用?

xmlns,即xml 命名空间。其作用是区分不同来源和用途的属性,以免产生多个属性同名无法区分的错误。

2、常用的三个xmlns?

常用的三个xmlns。

一、xmlns:android="http://schemas.android.com/apk/res/android"

它是在Android布局文件xml中在根布局中声明使用的。例:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".ui.CustomView.CustomViewActivity"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/rela_cus">



</RelativeLayout>

其作用是支持使用并提示android 原生控件、常用布局自带的属性,所有例如:

android:layout_height="match_parent"

像这样带着android前缀的属性值都是android命名空间的属性。
其作用就是原生View属性的语法文件

二、xmlns:tools="http://schemas.android.com/tools"

他的作用有以下三点。

Point 1

他仅仅作用于开发调试阶段,当打包为apk的时候所有tools添加的属性都会被摒弃。仔细观察,这个URI在*.com/后面并没有apk/这个部分,也算是体现了这个特点。这个可以用来在写页面的时候调试,而且很多android空间中有的属性,tools空间中都有。所以这样就方便进行页面的调整。即使忘记删除也不会影响到最终的结果。

Point 2

tools:context="XXActivity的包名路径"
这个的作用是直接在编写xml文件阶段就能看到包含当前Activity的主题限制在内的页面样式

Point 3

tools:layout=@layout/your fragment layout name
这个的作用是直接在编写xml文件阶段就能看到包含目标Fragment所在的页面样式。

三、xmlns:app="http://schemas.android.com/apk/res-auto"

这个命名空间是结合自定义控件来使用的。在下一个部分我们会分析自定义xmlns和这个的等价关系。

3、如何自定义xmlns?

首先我们明确一下,自定义xmlns的目的是开辟一个空间来为自定义View定义一些属性值,而且为了让我们明确区分开这个属性是自定义View自身特有的,我们可以自定义一个与之对应的xmlns来设置这个属性。
命名方法是:xmlns:自定义变量名="http://schemas.android.com/apk/自定义View的包名路径"。例:

xmlns:myViewns="http://schemas.android.com/apk/自定义View的包名路径"

当使用其属性时,其格式为:

 myViewns:text="我是修改版!"
 myViewns:textColor="#000000"

但是在Android Studio 2.0以上就不推荐这么写。最好还是使用官方定义好的自定义View的自适应空间。

xmlns:app="http://schemas.android.com/apk/res-auto"

代码如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".ui.CustomView.CustomViewActivity"
    android:id="@+id/rela_cus">
   
   <com.lay.demopro74.ui.CustomView.MyTextView
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       app:text="999"
       app:textColor="#000000"
       />


</RelativeLayout>

这个东西的使用是需要自定义控件配合的。
Step 1
在values文件夹下,新建一个attrs资源文件,如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyTextView">
    <attr name="text" format="string"></attr>
    <attr name="textColor" format="color"></attr>
</declare-styleable>
</resources>

Step 2
在自定义文件的构造方法中解析上下文对应的资源文件内容,得到xml中设置的属性值。

package com.lay.demopro74.ui.CustomView;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;

import com.lay.demopro74.R;


/**
 * User: AnyiLiu
 * Date: 2019/9/24
 * Time: 14:05
 */
public class MyTextView extends View {

    private Paint mPaint;

    private String mTextValue="我是默认版!";

    private int mColor=Color.RED;

    public MyTextView(Context context) {
        this(context,null);
    }

    public MyTextView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public MyTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyTextView);
        CharSequence mText = typedArray.getText(R.styleable.MyTextView_text);
        if(!TextUtils.isEmpty(mText)){
            mTextValue=mText.toString();
        }
        mColor = typedArray.getColor(R.styleable.MyTextView_textColor, Color.rgb(201, 231, 180));
//        mPaint.setColor(mColor);
        typedArray.recycle();

        initPaint();


    }

    //画笔
    private void initPaint() {
        mPaint=new Paint();
        mPaint.setColor(mColor);
//        mPaint.setAntiAlias(true);
//        mPaint.setDither(true);
        mPaint.setStrokeWidth(40f);
        mPaint.setStyle(Paint.Style.STROKE);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawText(mTextValue,100,100,mPaint);
    }
    //修改内容、位置和颜色-方案一:View类中写set方法;
    //xml-修改内容、位置、颜色

}

Step 3
最后才在xml文件中直接使用。这也是为什么很多第三方控件的自定义属性都是app空间格式的原因。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".ui.CustomView.CustomViewActivity"
    android:id="@+id/rela_cus">

   <com.lay.demopro74.ui.CustomView.MyTextView
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       app:text="999"
       app:textColor="#000000"
       />

</RelativeLayout>

细节无处不在,学习还是要想对待这个命名空间一样去追根究底。继续努力。

推荐阅读更多精彩内容