Android初级教程 - shape的详细介绍与使用

445 阅读3分钟

小知识,大挑战!本文正在参与 “程序员必备小知识” 创作活动

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。

使用shape一般都是在实现效果简单且单一,或 公司内无设计师的场景下

当然如果你比较懒的话,还是找设计要图吧,不过小心被藐视了…

基础知识

使用shape有点好处就是便捷性和兼容性,否则你需要找设计师要多套尺寸的图了 ~

shape常见边框形状

  • 长方形(默认)
  • 圆形
  • 环形
  • 线条

shape标签解析

<?xml version="1.0" encoding="utf-8"?>
<!--shape形状-->
<!--rectangle 长方形 /默认-->  
<!--oval 椭圆-->  
<!--line 线-->  
<!--ring 环形-->  
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <!--solid标签: shape图形背景色-->  
    <!--PS: 这个和上面的gradient标签会互斥, 一个是设置背景色, 一个是设置渐变色-->  
    <solid android:color="#ff0" />

    <!--stroke标签: 边框(这里小数是有效的,但是会导致显示不全)-->  
    <!--width 边框的宽度-->  
    <!--color 边框的颜色-->  
    <!--下面两个参数是 把边框变成虚线用-->  
    <!--dashGap 虚线中空格的长度-->  
    <!--dashWidth 虚线中实线的长度-->
    <stroke
        android:width="1dp"
        android:color="@color/CustomColor7" />

    <!--边角度圆化(圆角)-->
    <!--针对部分场景,如顶部圆化,底部直角 或 顶部直角,底部圆化 可以考虑 radius内的下方属性-->
	<!--指定方向的radius 优先于通用radius属性-->
    <!--android:topRightRadius="5dp"-->
    <!--android:topLeftRadius="5dp"-->
    <!--android:bottomRightRadius="10dp"-->
    <!--android:bottomLeftRadius="10dp"-->
    <corners android:radius="5dp" />

    <!--size标签 shape图形的宽度和高度  这里一般不用设置, 它的优先级没有控件的优先级大, 他指定控件的宽高就好, shape图形会随控件拉伸-->  
    <size
        android:width="15dp"
        android:height="5dp" />
        
    <!--padding标签: 这里的padding是控件中间内容与shape图形图片的距离-->  
    <padding
        android:left="10dp"
        android:right="10dp" />

    <!--gradient标签: 简单的说: 让图形变成一个有颜色梯度的-->  
    <!--渐变色 angle(角度方向,90度为上下渐变,0为左右渐变),-->
    <!--angle 是颜色变换的角度, 默认是0, 取值必须是45的 倍数. 0: 是颜色从左边到右边, 90: 是颜色从底部到顶部, -->  
    <!--startColor centerColor endColor 一起使用: 开始的颜色, 中间的颜色, 结束的颜色-->  
    <!--centerX centerY是指定位置坐标, 取值是0.0f ~ 1.0f 之间, 例如: android:centerX="0.5f"  表示X方向的中间位置-->  
    <!--type 颜色渐变的类型, 取值类型有三种: linear/radial/sweep  -->  
    <!--linear 线性变化, 就是颜色从左往右, 从下往上-->  
    <!--radial 放射变化, 例如: 从一个圆中心到圆的边缘变化-->  
    <!--sweep 扫描式渐变, 类似雷达扫描的那种图形-->  
    <!--gradientRadius 和android:type="radial"一起连用, 半径-->  
    <gradient
        android:angle="45"
        android:centerColor="@color/CustomColor2"
        android:endColor="@color/CustomColor3"
        android:startColor="@color/CustomColor1" />

</shape>

使用方式

  1. 在res - drawable - 创建shape_自命名.xml(一般为shape开头)
    在这里插入图片描述
  2. 文件内部shape为最外层标签,可设置当前的shape形状,有圆形,长方形,环形,线形(删除线)
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    
</shape>
  1. 在需要的地方可以设置@drawable/shape效果,如ImageView的src属性,TextView的android:background
 <ImageView
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:background="@drawable/shape_自命名.xml"
     android:scaleType="centerCrop"
  />

开发实战

Shape - Demo下载地址

实现效果
  • Demo内包含6种效果
  • 各种效果,需熟悉掌握,长方形同时可实现圆化
  • 第三,第四种效果设置TextView的背景均是高度被限制的原因

这里写图片描述

shape常用标签
shape_rectangle.xml(长方形)
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle"
    android:useLevel="false">

    <!--内部填充-->
    <solid android:color="@color/CustomColor5" />

    <!--描边(这里小数是有效的,但是会导致显示不全)-->
    <stroke
        android:width="1dp"
        android:color="@color/CustomColor7" />

    <!--大小-->
    <size
        android:width="15dp"
        android:height="5dp" />

    <!--边角度圆化(圆角)-->
    <!--针对部分场景,如顶部圆化,底部直角 或 顶部直角,底部圆化 可以考虑 radius内的下方属性-->
    <!--android:topRightRadius="5dp"-->
    <!--android:topLeftRadius="5dp"-->
    <!--android:bottomRightRadius="10dp"-->
    <!--android:bottomLeftRadius="10dp"-->
    <corners android:radius="5dp" />

    <!--俩边的内边距-->
    <padding
        android:left="10dp"
        android:right="10dp" />

    <!--渐变色 angle(角度方向,90度为上下渐变,0为左右渐变),-->
    <gradient
        android:angle="45"
        android:centerColor="@color/CustomColor2"
        android:endColor="@color/CustomColor3"
        android:startColor="@color/CustomColor1" />

</shape>
shape_oval.xml (圆形)
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval"
    android:useLevel="false">

    <!--内部填充-->
    <solid android:color="@color/colorAccent" />

    <!--描边(这里小数是有效的,但是会导致显示不全)-->
    <stroke
        android:width="1dp"
        android:color="@color/colorPrimary" />

    <!--大小-->
    <size
        android:width="5dp"
        android:height="5dp" />

    <!--边角度圆化(圆角,大多用处长方形,因本身是圆形,这里不设置)-->
    <corners />

    <padding />
    
</shape>
shape_ring.xml (环形)
<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="ring"
    android:useLevel="false">
    
    <!--内部填充-->
    <solid android:color="@color/colorAccent"/>

    <!--描边-->
    <stroke
        android:width="0.1dp"
        android:color="@color/colorPrimary"
        />

    <!--大小-->
    <size
        android:width="5dp"
        android:height="5dp"
        />

    <!--边角度圆化(圆角)-->
    <corners />

    <padding />
    
    <gradient />
</shape>
shape_line.xml (删除线)
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="line"
    android:useLevel="false">

    <!--内部填充-->
    <solid android:color="@color/colorAccent" />

    <!--描边-->
    <stroke
        android:width="1dp"
        android:color="@color/colorPrimary" />

    <!--大小-->
    <size
        android:width="5dp"
        android:height="5dp" />

    <!--边角度圆化(圆角)-->
    <corners android:radius="5dp" />

    <padding />

    <gradient
        android:angle="45"
        android:centerColor="@color/CustomColor2"
        android:endColor="@color/CustomColor3"
        android:startColor="@color/CustomColor1" />
        
</shape>
shape_dotted_line.xml (虚线)

方式一:shape方式 - 横直虚线

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="line">
    
    <!--shape:表示是线条-->
    <!--width:表示是线段的高度-->
    <!--dashGap:表示线段与线段之间间隔-->
    <!--dashWidth:表示线段的宽度-->
    <stroke
        android:width="1dp"
        android:color="#ff6677"
        android:dashGap="5dp"
        android:dashWidth="5dp" />

</shape>

方式二:DottedLine 自定义控件 - 竖直的虚线

public class DottedLine extends View {

    private Paint mDotPaint;

    public DottedLine (Context context) {
        super(context);
        initView();
    }

    public DottedLine (Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public DottedLine (Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    private void initView() {
        mDotPaint = new Paint();
        mDotPaint.setColor(Color.parseColor("#FF6677")); //画笔颜色
        mDotPaint.setStrokeWidth(2); //画笔宽度
        // 1、STROKE 描边
        // 2、FILL_AND_STROKE 填充内部和描边
        // 3、FILL:填充内部
        mDotPaint.setStyle(Paint.Style.STROKE);
        //1、Cap.BUTT 这条路径结束,而不是超越它。
        //2、Cap.ROUND 结束是个半圆
        //3、Cap.SQUARE 结束是个方形
        mDotPaint.setStrokeCap(Paint.Cap.ROUND);//
        //设置抗锯齿
        mDotPaint.setAntiAlias(true);
        //设置是否抖动
        mDotPaint.setDither(true);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        float startY = getHeight();
        float startX = getWidth() / 2;
        DashPathEffect dashPathEffect =
                new DashPathEffect(new float[]{8, 10, 8, 10}, 0);
        mDotPaint.setPathEffect(dashPathEffect);
        Path path = new Path();
        path.moveTo(startX,0);
        path.lineTo(startX,startY);
        canvas.drawPath(path,mDotPaint);
    }
}
实战使用

此处讲明了多种效果的调用方式,简单方便,没必要看下方的Demo代码 ~

AllEffectActivity (项目实用 - 项目主要使用AllEffectActivity的代码)

package com.yl.shape.shapedemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class AllEffectActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_all_effect);
    }
}

activity_all_effect

<?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_all_effect"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.yl.shape.shapedemo.AllEffectActivity">

    <TextView
        android:layout_marginTop="40dp"
        android:layout_width="wrap_content"
        android:layout_height="25dp"
        android:text="圆形"
        android:gravity="center"
        android:layout_gravity="center"
        android:background="@drawable/shape_oval"
        />

    <TextView
        android:layout_marginTop="20dp"
        android:layout_width="wrap_content"
        android:layout_height="25dp"
        android:text="长方形"
        android:gravity="center"
        android:layout_gravity="center"
        android:background="@drawable/shape_rectangle"
        />

    <TextView
        android:layout_marginTop="20dp"
        android:layout_width="wrap_content"
        android:layout_height="25dp"
        android:text="删除线"
        android:gravity="center"
        android:layout_gravity="center"
        android:background="@drawable/shape_line"
        />

    <TextView
        android:layout_marginTop="20dp"
        android:layout_width="wrap_content"
        android:layout_height="25dp"
        android:text="环形"
        android:gravity="center"
        android:layout_gravity="center"
        android:background="@drawable/shape_ring"
        />
</LinearLayout>

以下代码可忽略 - 此处代码多而臃肿,完全是为了给新手细化每种效果,建议直接看上方的开发使用即可 ~

MainActivity

package com.yl.shape.shapedemo;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private TextView mOver;
    private TextView mRectangle;
    private TextView mLine;
    private TextView mRing;
    private TextView mAll;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mOver = (TextView) findViewById(R.id.over);
        mRectangle = (TextView) findViewById(R.id.rectangle);
        mLine = (TextView) findViewById(R.id.line);
        mRing = (TextView) findViewById(R.id.ring);
        mAll = (TextView)findViewById(R.id.all);

        mOver.setOnClickListener(this);
        mRectangle.setOnClickListener(this);
        mLine.setOnClickListener(this);
        mRing.setOnClickListener(this);
        mAll.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.over:
                startActivity(new Intent(this,OverActivity.class));
            	break;
            case R.id.rectangle:
                startActivity(new Intent(this,RectangleActivity.class));
            	break;
            case R.id.line:
                startActivity(new Intent(this,LineActivity.class));
            	break;
            case R.id.ring:
                startActivity(new Intent(this,RingActivity.class));
            	break;
            case R.id.all:
                startActivity(new Intent(this,AllEffectActivity.class));
                break;
        }
    }
}

activity.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:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.yl.shape.shapedemo.MainActivity">

    <TextView
        android:id="@+id/over"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center"
        android:padding="5dp"
        android:text="Shape_圆形" />

    <View
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="#64CDFF" />

    <TextView
        android:id="@+id/rectangle"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center"
        android:padding="5dp"
        android:text="Shape_长方形圆角化" />

    <View
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="#64CDFF" />

    <TextView
        android:id="@+id/line"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center"
        android:padding="5dp"
        android:text="Shape_线条" />

    <View
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="#64CDFF" />

    <TextView
        android:id="@+id/ring"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center"
        android:padding="5dp"
        android:text="Shape_Ring形状" />

    <View
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="#64CDFF" />

    <TextView
        android:id="@+id/all"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center"
        android:padding="5dp"
        android:text="项目适用Shape效果" />

    <View
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="#64CDFF" />

</LinearLayout>

OverActivity(圆形)

package com.yl.shape.shapedemo;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

/**
 * Created by YongLiu on 2017/8/3.
 */

public class OverActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_over);
    }
}

activity_over

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

    <ImageView
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/shape_oval"
         />
</RelativeLayout>

RectangleActivity(长方形)

package com.yl.shape.shapedemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class RectangleActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rectangle);
    }
}

activity_rectangle

<?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_rectangle"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.yl.shape.shapedemo.RectangleActivity">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/shape_rectangle"
        />
</RelativeLayout>

RingActivity(环形)

package com.yl.shape.shapedemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class RingActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ring);
    }
}

activity_ring

<?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_ring"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.yl.shape.shapedemo.RingActivity">

    <TextView
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="20dp"
        android:text="ImageView设置的src"
        android:gravity="center"
        />

    <ImageView
        android:layout_marginTop="10dp"
        android:layout_width="match_parent"
        android:layout_height="20dp"
        android:src="@drawable/shape_ring"
        />

    <TextView
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="20dp"
        android:text="Text设置的背景Ring"
        android:gravity="center"
        />

    <TextView
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="20dp"
        android:background="@drawable/shape_ring"
        />
</LinearLayout>

LineActivity (线形)

package com.yl.shape.shapedemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class LineActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_line);
    }
}

activity_line

<?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_line"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.yl.shape.shapedemo.LineActivity">

    <TextView
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="20dp"
        android:text="Text设置的背景Ring"
        android:gravity="center"
        />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="20dp"
        android:layout_centerInParent="true"
        android:background="@drawable/shape_line"
        android:id="@+id/textView" />

    <TextView
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="20dp"
        android:text="ImageView设置的src"
        android:gravity="center"
        />

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:src="@drawable/shape_line"
        />
</LinearLayout>