Android 布局文件中Tools属性的应用

每当创建新项目的时候,在MainActivity的布局文件layout中的根节点上都有一个xmlns:tools=”http://schemas.android.com/tools”的命名空间声明,以前一直认为没什么用处,知道最近看了文档才知道tools包含很多很实用的属性,下面就记录下tools一些主要属性的用法。

介绍

Android Studio支持在tools命名空间中定义的许多XML属性来使用一些设计时使用的特性,例如在界面预览中显示fragment的布局。还有一些编译时行文,例如开启资源压缩模式来压缩你的XML布局资源。当你编译你的app时,编译工具就会清除tools声明的属性,所以对APK的大小和运行时行为没有任何影响。

使用tools属性很简单,首先需要在XML布局的根节点中声明tools命名空间,例如下面代码所示:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent>

错误处理属性

下面3个属性主要是用来消除Lint的警告出错信息。

  • tools:ignore
    这个属性适合所有的元素节点,用于Lint。接受一个参数来使这个元素节点及其子节点来忽略Line警告问题信息,参数是Lint问题ID,可以接受多个Lint问题ID,但是必须以逗号分隔。
    例如,下面的代码使tools忽略MissingTranslation错误:
  • <string name="show_all_apps" tools:ignore="MissingTranslation">All</string>

  • tools:targetApi
    这个属性适合所有的元素节点,用于Lint。这个属性的工作原理与作用和@TargetApi注解的方式一样,可以指定一个API级别来使这个元素节点正常工作。
    这个属性告诉tools这个元素节点只能在指定的API级别或者更高级别才能正常工作。当元素节点在当前API级别或者minSdkVersion无法正常工作时,会停止Lint的警告错误信息。
    例如,GridLayout只能在API级别14或者更高正常工作,你可以使用tools来限制使用环境:
  • <GridLayout 
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        tools:targetApi="14" >

  • tools:locale
    这个属性适合<resources>标签元素 ,用于Lint和Android Studio编辑器。主要用来指定resources标签内元素使用的默认地区语言,来防止报告拼写出错信息。地区语言通过由两个字母组成的 ISO 639-1 语言代码定义,可以选择后跟两个字母组成的 ISO 3166-1-alpha-2 区域码(前带小写字母“r”),例如en,fr,en-rUs,fr-rFR,fr-rCA等等。
  • 例如,可以在values/string.xml文件中使用locale属性来指定字符串默认使用的语言。

    <resources xmlns:tools="http://schemas.android.com/tools"
        tools:locale="es">

    界面预览属性

    下面的属性定义可以在Android Studio中布局预览界面中查看布局的特性。这些属性比较重要,可以使用tools来在设计界面时显示效果。

  • tools: instead of android:
    这个属性适合view元素节点,用于在Android Studio layout布局管理器。可以在布局中使用tools前戳来替代android: 来给view的任何属性赋值,例如tools:text等等。这个属性可以使你在编写布局时来查看效果,但是在APP运行期间这些tools元素的值却对APP没有任何影响。
  • 例如,我们在编写TextView时想查看字体大小或样式时,一般是使用android:text赋值一些字符串,这种做法是错误的。应该使用tools:text属性来指定一些字符串,但这些tools:text中的字符串只能在界面预览中可见,在APP运行期间这些数据时没有作用的。
    这里写图片描述

    在布局文件中可以同时使用android:和tools:来给相同的属性赋值,这两种是不会冲突的,android:属性主要用于运行期间,和tools:属性主要用于界面预览期间。
    这个属性也可以用来在界面预览时复位一个属性。例如,在一个FrameLayout中有两个Button,你想查看其中一个Button的界面预览,你可以设置另外一个Button在界面预览不可见,例如:

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="First" />
    
    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Second"
        tools:visibility="invisible"  />

    第二个Button将在界面预览中被隐藏,但是在运行时没有隐藏,因为没有设置android:visibility属性。

  • tools:context
    这个属性适合根节点元素,用于Lint和Android Studio 布局管理器。这个属性用来声明哪个activity与当前的布局关联。当使用这个属性时,当前的布局就获取到activity的一些信息,从而在xml布局或者界面预览中使用activity的特性,例如当设置activity的主题时,界面预览就会显示布局对应的主题。
    还有一个更重要的特性时,你可以指定事件的处理者,例如可以指定Button的onClick事件的处理者,就不用在activity为这个Button设置监听器。首先需要在MainActivity中创建一个方法,参数必须与onClick事件处理者一样,也就是一个View参数,例如:
  • public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
    
        public void onButtonClicked(View view){
            Log.e("Test","onClicked");
        }
    }

    然后就可以在XML布局中Button元素节点中使用android:onClick来绑定这个Click事件处理者,达到解耦:

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.example.jason.mvvmtest.MainActivity">
    
    <Button
            android:id="@+id/Button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            tools:text="test"
            android:onClick="onButtonClicked"/>

    要使用这个特性,必须在根布局中使用tools:context属性来关联与当前布局相关的activity,可以使用简写或者使用全路径来指定activity的路径:

    <android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        tools:context=".MainActivity" >

  • tools:layout
    这个属性适合<fragment&rt;元素节点,用于Android Studio布局管理器。这个属性可以指定布局预览中显示在fragment中的布局,因为fragment中的布局我们一般是在代码中动态添加的,即onCreateView方法放回的View,所以Activity中布局预览不能显示,使用tools:layout就可以在Activity中实时显示fragment中的布局了。
  • 例如activity布局:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.example.jason.mvvmtest.MainActivity">
    
        <fragment
            android:name="com.example.jason.mvvmtest.HeadFragment"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            tools:layout="@layout/fragment_head_img"/>
    
    </LinearLayout>

    fragment中布局:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
    
        <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@drawable/headimg"/>
    
    </LinearLayout>

    以上代码就可以在activity中的预览界面中显示fragment的布局了。

  • tools:listitem / tools:listheader / tools:listfooter
    这些属性主要用于<AdapterView&rt; 和它的子类 例如ListView,用于Android Studio布局管理器。
    顾名思义,listitem就是在ListView中显示的item项,listheader就是头部布局,listfooter就是尾部布局。
    例如:
  •     <ListView
            android:id="@+id/ListView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:listitem="@layout/listview_item"
            tools:listfooter="@layout/listview_footer"
            tools:listheader="@layout/listview_header"/>

    item,header和footer布局只是一个text 运行效果如下所示:
    这里写图片描述
    这个属性在Android Studio2.2中不能正常运行,在2.3以上已经修复。
    Android Studio2.3下载链接:http://tools.android.com/download/studio/builds/android-studio-2-3-beta-4

  • tools:showIn
    这个属性适合被<include&rt; 引用的布局中的根节点view,用于Android Studio布局管理器。当我们需要重复使用某个布局文件时,我们会使用<include&rt标签来达到视图复用的效果。在复用的布局文件的根节点中可以使用tools:showIn来指定包含这个布局文件的父布局,这样就可以在这个复用布局文件的预览界面中看到父布局中的布局了,就可以实时查看这个复用布局在父布局中的显示效果。
    例如:
    在activity_main父布局中使用Include引用重复布局:
  •     <include
            layout="@layout/include_text"/>

    当没有使用tools:showIn属性时,复用布局界面预览只显示这个布局内容,如下所示:
    这里写图片描述

    当在根节点元素中加入tools:showIn=”@layout/activity_main” 属性后就可以在复用布局中看到整个父布局和它在父布局中的显示效果了:
    这里写图片描述

  • tools:menu
    这个属性使用任何根元素节点view,用于Android Studio布局管理器。这个属性可以指定哪个menu显示在界面预览的app bar中。参数可以是一个或者多个menu的ID,多个menu的ID要用逗号隔开。注意ID不包含@menu或者任何ID前缀和没有.xml后缀。例如:
  • <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:menu="menu1,menu2" />

    资源压缩属性

    以下介绍的属性在使用资源压缩时,会开启严格的引用检查,或者可以声明保持或者丢弃某些资源。
    开启资源压缩很简单,只需要在build.gradle文件中设置shrinkResources 属性为true就开启了。属性minifyEnabled 指的是代码压缩,在编译时会清除一些没有使用到的代码文件,从而减小APP的大小。如下代码同时开启了资源压缩和代码压缩。

    android {
        ...
        buildTypes {
            release {
                shrinkResources true
                minifyEnabled true
                proguardFiles getDefaultProguardFile('proguard-android.txt'),
                        'proguard-rules.pro'
            }
        }
    }

  • tools:shrinkMode
    这个属性适用于<resources&rt; 标签。用于资源压缩构建工具。这个标签可以开启build工具的两种模式,一种是”safe mode”安全模式,就是保留所有显式引用的资源和可能使用Resources.getIdentifier()动态地引用的资源。另一种是”strict mode”严格模式,只保留在代码中显式的引用的资源或其他资源。
    系统模式的模式是安全模式(shrinkMode=”safe”)。要开启严格模式,只需要在<resources&rt; 标签中增加shrinkMode=”strict”,例如:
  • <?xml version="1.0" encoding="utf-8"?>
    <resources xmlns:tools="http://schemas.android.com/tools"
        tools:shrinkMode="strict" />

    当开启了严格模式后,你需要使用tools:keep属性去保留你需要保留的资源,使用tools:discard属性去显式地删除多余的资源。

  • tools:keep
    这个属性适用于<resources&rt; 标签,用于资源压缩构建工具。当开启资源压缩功能去移除不使用的资源时,这个属性允许你指定某些资源去保留,这些资源通常是在运行时被引用,例如使用Resources.getIdentifier()动态生成资源名。
    首先需要在res目录中建立一个XML文件,例如可以在res/raw/中创建一个keep.xml资源文件,然后建立一个<resources&rt; 标签,并在tools:keep属性中指定每一个需要保留的资源,多个文件用逗号分隔。
  • <?xml version="1.0" encoding="utf-8"?>
    <resources xmlns:tools="http://schemas.android.com/tools"
        tools:keep="@layout/activity_main,@layout/listview_item" />

    可以使用星号作为一个通配符,模糊匹配。

    <?xml version="1.0" encoding="utf-8"?>
    <resources xmlns:tools="http://schemas.android.com/tools"
        tools:keep="@layout/used_1,@layout/used_2,@layout/*_3" />

  • tools:discard
    这个属性适用于<resources&rt; 标签,用于资源压缩构建工具。当开启资源压缩功能去删除未使用的资源时,这个属性允许你指定哪个资源需要被清除,通常是这个资源虽然被引用但是清除后不影响APP的运行,或者因为Gradle插件错误地认为资源是被引用实际上却没有。
    首先需要在res目录中建立一个XML文件,例如可以在res/raw/中创建一个discard.xml资源文件,然后建立一个<resources&rt; 标签,并在tools:discard属性中指定每一个需要删除的资源,多个文件用逗号分隔。
  • <?xml version="1.0" encoding="utf-8"?>
    <resources xmlns:tools="http://schemas.android.com/tools"
        tools:discard="@layout/unused_1" />
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值