layer-list -- layer-list的基本使用介绍

2018-03-16 23:56:14

1. layer-list 是啥?有啥作用?

点击查看 安卓官方开发指南中关于layerlsit的说明

(1). layer-list 是啥?

简单理解,layer 是层,list 是列表,那么 layer-list 就是层列表的意思。但是,是什么层列表呢?? 其实 layer-list 是用来创建 LayerDrawable 的,LayerDrawable 是 DrawableResource 的一种, 所以,layer-list 创建出来的是 图层列表,也就是一个drawable 图形。

(2). layer-list 有啥作用?

上面已经说过,layer-list 是用来创建 图层列表的,通过它能创建出一些特殊的 drawable, 比如:

下图 AlertDialog 中,我们只需要设置 button 的 顶部边线,以及 左侧button的右边线(或者右侧button的左边线),这种时候我们就无法直接使用 shape 了,因为直接使用 shape 绘制出来的是四个边框; 如果让美工切图也可以,但那样的话灵活度就差了很多,而且会增加app的体积;这种情况下,使用 layer-list 就是最佳选择。当然,layer-list 的用途还有很多,这里只是举一个例子,具体的使用请继续往下看。

这里写图片描述

2. layer-list 的大致原理

layer-list 的大致原理类似 RelativeLayout(或者FrameLayout) ,也是一层层的叠加 ,后添加的会覆盖先添加的。在 layer-list 中可以通过 控制后添加图层距离最底部图层的 左上右下的四个边距等属性,得到不同的显示效果。

上面示例图中,AlertDialog 底部的 ok按钮 的背景就是用layer-list实现的。该layer-list 中,底层使用一个填充色为蓝色 的shape,上层使用一个填充色为白色的shape ,然后控制上层距离最底层的顶部边距为1dp , 这样在视觉上就形成了一个 具有蓝色顶部边线的白色背景。具体代码继续往下看。

3. layer-list 基本使用示例:

因 layer-list 创建出来的也是 drawable 资源,所以,同 shape selector 一样,都是定义在 res 中的 drawable 文件夹中,也是一个 xml 文件。使用的时候,同shape selector , 布局文件中使用 @drawable/ xxx 引用, 代码中使用 R.drawable.xxx 引用。

layer-list 中不同的图层使用 item 节点来定义。

(1). 效果1 :单一边线

效果图:

图中,TextView 只有一个顶部边线

这里写图片描述

具体代码:

  • 创建带有蓝色顶部边线的 layer-list 图

在 res 目录中的 drawable 目录下,创建名称为 singleline.xml 的xml 文件,然后编辑 layer-list 的详细代码,如下:

<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <!--底层使用蓝色填充色-->
    <item>
        <shape>
            <solid android:color="#02a0ef"/>
        </shape>
    </item>

    <!--上面一层距离底层的顶部1dp,类似marginTop,填充色为白色,这样就形成了一个带有蓝色顶部边线的白色背景的图-->
    <item android:top="1dp">
        <shape>
            <solid android:color="#fff"/>
        </shape>
    </item></layer-list>1234567891011121314151617
  • 使用 layer-list 图,设置为textView的背景

 <TextView
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="@drawable/singleline"
        android:gravity="center"
        android:text="单一边线效果"/>123456

(2). 效果2 :双边线

效果图:

图中,TextView 具有上下边线 
这里写图片描述

具体代码:

  • 创建带有蓝色顶部和底部边线的 layer-list 图

<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <!--底层使用蓝色填充色-->
    <item>
        <shape>
            <solid android:color="#02a0ef"/>
        </shape>
    </item>

    <!--上面一层距离底层的顶部1dp,距离底部1dp,类似marginTop,填充色为白色,这样就形成了一个带有蓝色顶部边线和底部边线的白色背景的图-->
    <item android:bottom="1dp"
          android:top="1dp">
        <shape>
            <solid android:color="#fff"/>
        </shape>
    </item></layer-list>123456789101112131415161718
  • 使用 layer-list 图,设置为textView的背景

  <TextView
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_marginTop="10dp"
        android:background="@drawable/doubleline"
        android:gravity="center"
        android:text="双边线效果"/>12345678

(3). 效果3 :阴影

效果图:

这里写图片描述

具体代码:

  • 创建 layer-list

<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <!--底层的左边距离上层左边3dp, 底层的顶部,距离上层的顶部6dp,如果不做这个控制,底层和上层的左侧和上侧会重合在一起-->
    <item android:left="3dp"
          android:top="6dp">
        <shape>
            <solid android:color="#b4b5b6"/>
        </shape>
    </item>

    <!--上层的右边距离底层的右边3dp, 上层的底部距离底层的底部6dp-->
    <item android:bottom="6dp"
          android:right="3dp">
        <shape>
            <solid android:color="#fff"/>
        </shape>
    </item></layer-list>12345678910111213141516171819
  • 使用 layer-list 图,

  <TextView
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:layout_marginTop="10dp"
        android:background="@drawable/shadow"
        android:gravity="center"
        android:text="阴影效果"/> 1234567

(4). 效果4 : 图片层叠

图片层叠的时候,有两种效果,一种是缩放后层叠,一种是不缩放的层叠。默认是缩放效果。具体效果以及实现代码如下:

效果图 1) : 带有缩放效果的

这里写图片描述

具体代码 1):

  • 创建 layer-list

<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!--默认缩放-->
    <item>
        <bitmap            android:src="@drawable/ic_launcher"/>
    </item>

    <item android:left="35dp"
          android:top="35dp">
        <bitmap            android:src="@drawable/ic_launcher"/>
    </item>

    <item android:left="70dp"
          android:top="70dp">
        <bitmap            android:src="@drawable/ic_launcher"/>
    </item></layer-list>1234567891011121314151617181920

或者也可以使用如下代码,实现缩放的叠加图:

<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!--这种方式拿到的是带有缩放的效果,即便给item 设置了gravity 并且从模拟器上看到的效果是不缩放的,但是真机上依旧是缩放的效果-->
    <item android:drawable="@drawable/ic_launcher">
    </item>
    <item android:drawable="@drawable/ic_launcher"
          android:left="45dp"
          android:top="45dp">
    </item>
    <item android:drawable="@drawable/ic_launcher"
          android:left="90dp"
          android:top="90dp">
    </item></layer-list>123456789101112131415
  • 使用 layer-list 图,

   <ImageView        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/overlay"
    />12345

效果图 2):不带缩放效果的

注意: 
A. 不缩放的时候,必须在 item 节点中使用 bitmap 节点,并给 bitmap 设置 gravity=center ;

B. 虽然在实现缩放效果的时候,可以直接使用 item 中的 drawable属性,但实现不缩放的效果时,如果还用drawable 属性,即便给item 设置了gravity =center ,在真机上的效果依旧是缩放的。(但模拟器是不缩放的)

这里写图片描述

具体代码 2):

  • 创建 layer-list

<?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:left="35dp"
          android:top="35dp">
        <bitmap android:gravity="center"
                android:src="@drawable/ic_launcher"/>
    </item>

    <item android:left="70dp"
          android:top="70dp">
        <bitmap android:gravity="center"
                android:src="@drawable/ic_launcher"/>
    </item></layer-list>12345678910111213141516171819202122
  • 使用 layer-list 图,

 <ImageView        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/overlay"
    />12345

(5). 效果5 :叠加旋转

效果图:

这里写图片描述

具体代码:

  • 创建 layer-list

<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item>
        <rotate android:fromDegrees="-10" android:pivotX="0"
                android:pivotY="0">
            <bitmap android:src="@drawable/decibel_blue_background"/>
        </rotate>
    </item>
    <item>
        <rotate android:fromDegrees="10" android:pivotX="0"
                android:pivotY="0">
            <bitmap android:src="@drawable/decibel_orange_background"/>
        </rotate>
    </item>
    <item>
        <rotate android:fromDegrees="30" android:pivotX="0"
                android:pivotY="0">
            <bitmap android:src="@drawable/decibel_red_background"/>
        </rotate>
    </item></layer-list>123456789101112131415161718192021222324

旋转的时候,只需要给出 起始的角度( fromdegress )即可。

  • 使用 layer-list 图,

     <!--图片叠加并带旋转效果-->
    <ImageView        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/rotate"/>12345

4. layer-list 的扩展使用

(1).实现选择器的效果

主要使用组件:RadioGroup Selector layer-list

1). 效果图:

这里写图片描述

2). 具体代码



  • 定义 selector 选择器 


selector 的 item 节点中,直接嵌套 layer-list 
当然也可以先写好layer-list ,然后再去引用

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!--被选中时是4dp的底部边线-->
    <item android:state_checked="true">
        <layer-list>
            <item>
                <shape>
                    <solid android:color="#f00"/>
                </shape>
            </item>
            <item android:bottom="4dp">
                <shape>
                    <solid android:color="#fff"/>
                </shape>
            </item>
        </layer-list>
    </item>

    <!--未被选中的是2dp的底部边线-->
    <item>
        <layer-list>
            <item>
                <shape>
                    <solid android:color="#f00"/>
                </shape>
            </item>
            <item android:bottom="2dp">
                <shape>
                    <solid android:color="#fff"/>
                </shape>
            </item>
        </layer-list>
    </item></selector>12345678910111213141516171819202122232425262728293031323334

注意: 
在上面的代码中,由于并没有具体的shape ,所以可以省略shape , 直接用 color , 简化后的代码如下:

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">

    <!--被选中时是4dp的底部边线-->
    <item android:state_checked="true">
        <layer-list>
            <item>
                <color android:color="#f00"/>
            </item>
            <item android:bottom="5dp">
                <color android:color="#fff"/>
            </item>
        </layer-list>
    </item>

    <!--未被选中的是2dp的底部边线-->
    <item>
        <layer-list>
            <item>
                <color android:color="#f00"/>
            </item>
            <item android:bottom="2dp">
                <color android:color="#fff"/>
            </item>
        </layer-list>
    </item></selector>123456789101112131415161718192021222324252627
  • 使用selector

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              android:padding="15dp">
    <RadioGroup        android:id="@+id/rg"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <RadioButton            android:id="@+id/rb1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/selector_bk_rb"
            android:button="@null"
            android:checked="true"
            android:gravity="center"
            android:padding="10dp"
            android:text="第1 个button"/>
        <RadioButton            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/selector_bk_rb"
            android:button="@null"
            android:gravity="center"
            android:padding="10dp"
            android:text="第2 个button"/>
        <RadioButton            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/selector_bk_rb"
            android:button="@null"
            android:gravity="center"
            android:padding="10dp"
            android:text="第3 个button"/>

    </RadioGroup></LinearLayout>    123456789101112131415161718192021222324252627282930313233343536373839404142

注意: 
在 RadioGroup 中,是通过 RadioButton 的 id 来控制是否选中。 
所以,如果需要设置某一个 RadioButton 为默认选中,就必须给该 RadioButton 设置 id ; 
如果不设置 id ,导致的结果就是该 RadioButton 会一直处于选中状态!!!


  • 2019-11-28 11:00:35

    Vue子组件调用父组件的方法

    下面有三种方法,我自己重点推荐第一种,毕竟这种简单粗暴好用好理解,不过这个有一个弊端,再组件嵌套组件的时候,尤其是用第三方组件里面调用自己的子组件的时候,其实已经是孙子组件了,这个时候就要parent.parent。。。。,这样就不好了,我们就得考虑其他方法了,具体怎么判断是父组件,还是爷爷组件,我会单独出一篇文章讲述。

  • 2019-11-29 13:04:47

    计算一个多边形的重心点坐标(准确版)

    在之前的 《如何判断一个多边形是否合法》 一文中有提到,用无人机规划飞行路线前,往往需要框选一个多边形的区域。 而在地图控件上显示这个多边形区域时,往往会遇到这样一个需求:需要把所要测绘的多边形区域移动到地图中心。 实现这个需求的基本思路就是:获取到多边形区域的重心点坐标,然后利用地图控件的 setCenter方法,就可以把地图的显示中心移动到多边形区域重心了。那么问题来了,如何求出一个多边形的重心点坐标呢?

  • 2019-11-29 13:06:27

    如何判断一个多边形是否合法

    利用无人机对一片区域进行测绘前,我们会先在地图上框选一个区域,然后再规划飞行的路线,而需要测绘的这片区域往往是一个多边形。在 MeshKit 中,我们加入了多边形区域的编辑功能,其中就涉及判断用户所编辑出来的多边形是否合法的问题。

  • 2019-11-29 13:47:22

    百度地图做电子围栏总结

    在地图上画出围栏,设置围栏信息后保存,生成围栏列表。全选时,地图视野可看到全部的围栏区域,单独勾选会调整地图视野到当前勾选的围栏。围栏区域的中心点要显示围栏名称。

  • 2019-11-29 13:50:29

    图片连接处出现白线

    block导致,只要父元素设置font-size:0或者设置img display: block; 便可。但是我设置了没有用,这条线不是所有的机型都有,而且页面滚动之后又消失,我琢磨半天,各种尝试,发现把图片高度减少(增加)1px就解决了。因为我们的项目是用postcss-px-to-viewport,我每张图片都是设置高度的,应该是数值转换出现偏差。

  • 2019-11-29 13:54:07

    粗略计算多边形中心点(并不是很准确,但简单好用)

    也是再做栅栏系统,搜索如何获取多边形中心点的问题上,发现了这个,简单易于理解,但是并不是特变准确,但也不影响使用。 后来发现了新的算法,并且百度地图也提供相应的api。 具体内容我写在了前面的文章,大家可以找一下。

  • 2019-11-29 14:20:38

    vue,vuthis.$parent算法

    由于组件嵌套,其实vue parent的位置也改变了,我们可以通过下面的图片,来看一下,parent到底什么哪一层