10、Android--Shape

Shape

在Android开发中,我们可以使用shape定义各种各样的形状,也可以定义一些图片资源。相对于传统图片来说,使用shape可以减少资源占用,减少安装包大小,还能够很好地适配不同尺寸的手机。

Shape基础

Shape是一个很强大的对象,可以在XML中绘制不同的形状,下面展示Shape所支持的参数:

属性 描述
Corners android:radius为角的弧度,值越大角越圆。
android:topRightRadius="20dp" 右上角
android:bottomLeftRadius="20dp" 右下角
android:topLeftRadius="1dp" 左上角
android:bottomRightRadius="0dp" 左下角
Gradient 渐变
android:startColor 渐变开始的颜色
android:endColor 渐变结束的颜色
android:centerColor 中间点的颜色
android:angle是渐变角度,必须为45的整数倍。
android:type linear线性渐变;radial径向渐变
android:gradientRadius 径向渐变的半径
Stroke 描边
android:width 描边的宽度
android:color 描边的颜色。 我们还可以把描边弄成虚线的形式,设置方式为:
android:dashWidth="5dp" 一个'-'的宽度
android:dashGap="3dp" 间隔的宽度
注意的是corners的属性bottomLeftRadius为右下角、bottomRightRadius为左下角
Padding 内容边界距离
Size 大小
Solid android:color 使用的填充颜色

在Android 项目中的drawable目录下定义xml文件:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@color/white" />
    <stroke
        android:width="2px"
        android:color="@color/shape_stroke_line"/>
    <corners
        android:radius="0dp"/>
</shape>

除了上述的使用xml绘制Shape外,我们还可以通过代码动态设置Shape:

public static GradientDrawable getBackgroundDrawable(int solidColor, int strokeColor, int strokeWidth, float radius) {
    GradientDrawable drawable = new GradientDrawable();
    drawable.setColor(solidColor);
    drawable.setStroke(strokeWidth, strokeColor);
    drawable.setCornerRadius(radius);
    return drawable;
}

如果要修改渐变色,直接重载GradientDrawable的构造函数即可:

public static GradientDrawable getShapeWithGradient(int radius, int strokeColorStr, int[] colors){
    GradientDrawable gradientDrawable = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, colors);
    if (strokeColorStr != 0){
        gradientDrawable.setStroke(4, strokeColorStr);
    }
    gradientDrawable.setCornerRadius(radius);
    return gradientDrawable;
}

特殊属性

Shape可以定义当前Shape的形状的,比如矩形,椭圆形,线形和环形;这些都是通过shape标签属性来定义的,shape标签有下面几个属性:

rectangle,oval,line,ring

使用方式如下所示:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
  android:shape=["rectangle" | "oval" | "line" | "ring"] //shape的形状,默认为矩形,可以设置为矩形(rectangle)、椭圆形(oval)、线性形状(line)、环形(ring)   
  //下面的属性只有在android:shape="ring"时可用:   
  android:innerRadius="10dp" //  内环的半径; 
  android:innerRadiusRatio="2"  // 浮点型,以环的宽度比率来表示内环的半径;   
  android:thickness="3dp"   // 环的厚度;   
  android:thicknessRatio="2" //  浮点型,以环的宽度比率来表示环的厚度;  
  android:useLevel="false"> //  boolean值,如果当做是LevelListDrawable使用时值为true,否则为false。
</shape>

1、绘制矩形

Shape绘制矩形,方式如下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@color/colorPrimary"/>
</shape>

2、绘制椭圆

Shape绘制椭圆,方式如下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="@color/colorPrimary"/>
    <size android:height="100dp"
        android:width="100dp"/>
</shape>

3、绘制线条

Shape绘制线条,方式如下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="line">
    <stroke
        android:width="1dp"
         android:color="@color/colorAccent"
         android:dashGap="3dp"//虚线间距
         android:dashWidth="4dp"/>//虚线宽度
    <size android:height="3dp"/>
</shape>

4、绘制圆环

Shape绘制圆环,方式如下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="ring"
    android:useLevel="false"
    android:innerRadius="20dp" // 内环的半径
    android:thickness="10dp"> // 圆环宽度
    <!--useLevel需要设置为false-->
    <solid android:color="@color/colorAccent"/>
</shape>

Layer

Layer是在Photoshop中非常的功能。在Android中同样可以通过Layer来实现类似Photoshop中图层的概念。

在Android中有两种实现图层的方式:静态图层和动态图层

静态图层

所谓静态图层就是在xml文件中进行定义,可以实现图片的叠加效果。在Android项目的drawable目录下定义xml文件:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <!-- 图片  1-->
    <item android:drawable="@drawable/ic_launcher"></item>
    <!-- 图片 2 -->
    <item 
        android:drawable="@drawable/ic_launcher"
        android:left="10.0dip"
        android:top="10.0dip"
        android:right="10.0dip"
        android:bottom="10.0dip">
    </item>
</layer-list>  

然后在控件中使用background属性引用即可。

android:background="@drawable/layer_xxx"

动态图层

Android中使用saveLayer()方法创建一个图层,图层是基于栈的结构进行管理的。通过调用saveLayer()、saveLayerAlpha()方法将一个图层入栈,使用restore()、restoreToCount()方法将一个图层出栈。入栈的时候,后面所有操作都发生在该图层上,出栈的时候,则会把图像绘制到上层的Canvas上。

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawColor(Color.WHITE);
    mPaint.setColor(Color.BLUE);
    canvas.drawCircle(150, 150, 100, mPaint);
    
    canvas.saveLayerAlpha(0, 0, 400, 400, 127, LAYER_TYPE_NONE);
    mPaint.setColor(Color.RED);
    canvas.drawCircle(200, 200, 100, mPaint);
    canvas.restore(); 
}

效果如下所示:

图层透明度设置为0 - 255之间:

当透明度为127时,即半透明、当透明度为255时,即完全不透明、当透明度为0时,即完全透明。

Selector

Selector是存放在drawable文件夹中 用来设置控件背景和字体颜色的

常用选择器

创建xml文件,位置:drawable/xxx.xml中,同目录下记得放相关图片

属性 描述
android:state_selected 是否选中
android:state_focused 是否获得焦点
android:state_pressed 是否点击
android:state_enabled 是否响应事件

使用方法如下所示:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
       <!-- 没有焦点时的背景图片 --> 
       <item android:drawable="@drawable/handle_normal" android:state_enabled="true" android:state_window_focused="false"/> 
       <!-- 触摸模式按下时的背景图片 --> 
       <item android:drawable="@drawable/handle_pressed" android:state_pressed="true"/> 
       <item android:drawable="@drawable/handle_focused" android:state_enabled="true" android:state_focused="true"/> 
       <item android:drawable="@drawable/handle_normal" android:state_enabled="true"/> 
       <!-- 获得焦点时的图片背景 --> 
       <item android:drawable="@drawable/handle_focused" android:state_focused="true"/> 
       
       <!-- android:state_selected 是否选中 
            android:state_focused 是否获得焦点   
            android:state_pressed 是否点击 
            android:state_enabled 是否设置是否响应事件,指所有事件 --> 
</selector>  

定义选择器后,使用有两种方式,在布局中使用'background'属性设置或用过代码动态设置选择器:

其中在ListView中设置选择器的方式如下:

第一种方式:

在listview中配置android:listSelector="@drawable/xxx
在listview的item中添加属性android:background="@drawable/xxx"

第二种方式:

Drawable drawable = getResources().getDrawable(R.drawable.xxx);  
ListView.setSelector(drawable);

注意:出现列表有为黑色的情况,需要加上android:cacheColorHint="@android:color/transparent使其透明。

Shape选择器

Selector除了使用图片外,我们还可以使用Shape资源来设置。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_pressed="true">
        <shape android:shape="rectangle">
            <!-- 填充的颜色 -->
            <solid android:color="#33444444"/>
            <!-- 设置按钮的四个角为弧形 -->
            <corners android:radius="5dp"/>
            <!-- padding:Button里面的文字与Button的边界的间隔 -->
            <padding 
                android:bottom="10dp"
                android:left="10dp"
                android:right="10dp"
                android:top="10dp"/>
        </shape>
    </item>
    
    <item android:state_pressed="false">
        <shape android:shape="rectangle">
            <!-- 填充的颜色 -->
            <solid android:color="#FFFFFF"/>
            <!-- 设置按钮的四个角为弧形 -->
            <corners android:radius="5dp"/>
            <!-- padding:Button里面的文字与Button边界间隔 -->
            <padding 
                android:bottom="10dp"
                android:left="10dp"
                android:right="10dp"
                android:top="10dp"/>
        </shape>
    </item>
</selector>  

为了便于观看我们还可以将Shape单独定义为xml文件,然后通过drawable属性来引用。

shape_01.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <!-- 填充的颜色 -->
    <solid android:color="#33444444" />
    <!-- 设置按钮的四个角为弧形 -->
    <corners android:radius="5dp" />
    <!-- padding:Button里面的文字与Button的边界的间隔 -->
    <padding
        android:bottom="10dp"
        android:left="10dp"
        android:right="10dp"
        android:top="10dp" />
</shape>

shape_02.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <!-- 填充的颜色 -->
    <solid android:color="#FFFFFF" />
    <!-- 设置按钮的四个角为弧形 -->
    <corners android:radius="5dp" />
    <!-- padding:Button里面的文字与Button的边界的间隔 -->
    <padding
        android:bottom="10dp"
        android:left="10dp"
        android:right="10dp"
        android:top="10dp" />
</shape>

然后在Selector选择器中使用drawable属性引用,定义selector_shape.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_pressed="true" android:drawable="shape_01"/>
    <item android:state_pressed="false" android:drawable="shape_02"/>
</selector>

注意:在使用过程中如果无效的话要考虑是否有获取焦点,如果没有可以设置焦点android:focusable="true"

Color选择器

除了可以使用Shape来充当Selector的资源外,还可以使用颜色,这个也是最常用的方式,代码如下所示:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true"><color android:color="#999999" /></item>
    <item android:state_pressed="false"><color android:color="#ffffff" /></item>
</selector> 

颜色选择器的使用方式和其他选择器的使用方式是一样的,使用background属性指定。

原文地址:https://www.cnblogs.com/pengjingya/p/5507758.html