Android-自定义图片

来源:互联网 发布:method(i,2))用法Java 编辑:程序博客网 时间:2024/04/30 13:16

知识概览

  • BitmapDrawable 位图图片
  • ClipDrawable 裁剪图片
  • StateListDrawable 状态图片
  • TransitionDrawable 过渡图片
  • LayerListDrawable 层叠图片
  • LevelListDrawable 层级图片
  • InsetDrawable 插图图片
  • ShapeDrawable 形状图片
  • Nine-Patch File 9Patch图

BitmapDrawable

Bitmap图片主要是用Xml来创建一个位图文件,Xml能为Bitmap添加一些额外的属性 如“布局重力” 平铺模式。

语法:

<?xml version="1.0" encoding="utf-8"?><bitmap    xmlns:android="http://schemas.android.com/apk/res/android"    android:src="@[package:]drawable/drawable_resource"    android:antialias=["true" | "false"]    android:dither=["true" | "false"]    android:filter=["true" | "false"]    android:gravity=["top" | "bottom" | "left" | "right" | "center_vertical" |                      "fill_vertical" | "center_horizontal" | "fill_horizontal" |                      "center" | "fill" | "clip_vertical" | "clip_horizontal"]    android:mipMap=["true" | "false"]    android:tileMode=["disabled" | "clamp" | "repeat" | "mirror"] />

元素解释

  • gravity:定义了图片的重力倾向,当图片比容器还小的时候,其指示了图片在容器中的位置。
  • tileMode:平铺模式
    • clamp 拉伸的是图片最后的那一个像素;横向的最后一个横行像素,不断的重复,纵项的那一列像素,不断的重复;
    • repeat 复制平铺
    • mirror 镜面平铺

示例

  1. 定义一张平铺的图片(该图片可以节省内存开销)
    这里写图片描述

ClipDrawable

ClipDrawable就是用来裁剪其他图片的位图 你可以通过控制裁剪宽高来决定裁剪

语法:

<?xml version="1.0" encoding="utf-8"?><clip    xmlns:android="http://schemas.android.com/apk/res/android"    android:drawable="@drawable/drawable_resource"    android:clipOrientation=["horizontal" | "vertical"]    android:gravity=["top" | "bottom" | "left" | "right" | "center_vertical" |                     "fill_vertical" | "center_horizontal" | "fill_horizontal" |                     "center" | "fill" | "clip_vertical" | "clip_horizontal"] />

元素解释

  • drawable 需要被处理的图片源
  • clipOrientation 裁剪的方向 horizontal从左到右 vertical从上到下
  • gravity 设置裁剪的开始位置
    • top 最上面开始
    • center 中间向两边扩张
    • bottom 从底部开始
    • left 从左边开始
    • right 从右边开始

示例:如下演示了一张图片如何从下到下慢慢展示的效果

  • 在res/drawable下创建my_clip.xml

    <?xml version="1.0" encoding="utf-8"?><clip xmlns:android="http://schemas.android.com/apk/res/android"    android:drawable="@drawable/round"    android:clipOrientation="vertical"    android:gravity="top"  />
  • 在layout布局中引用

    <ImageView    android:id="@+id/image"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:background="@drawable/my_clip" /> 
  • 在Activity中直接控制裁剪的层级

    private ImageView mImageview;private Handler mHandler=new Handler(){    public void handleMessage(android.os.Message msg) {        ClipDrawable drawable = (ClipDrawable) mImageview.getBackground();        if (drawable.getLevel()!=10000) {            drawable.setLevel(drawable.getLevel() + 500);        }    }};@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    mImageview = (ImageView) findViewById(R.id.image);    new Thread(){            public void run() {                while (true) {                    SystemClock.sleep(50);                    mHandler.sendEmptyMessage(0);                   }            }    }.start();}

StateListDrawable

StateListDrawable是一个定义在xml的图片用来在不同状态展示同一张图片的不同效果,如一个按钮有按下 聚焦等状态 你可以为每一个状态附带一张图片

你可以在XML文件中使用一系列的状态列表,每一个状态表现通过元素表现,该元素定义在元素内,每一个属性描述了某一个状态和对应的图片

在状态改变的过程中,系统会循环遍历每一个状态的,以寻求最好的匹配。注意,这里在遍历时只会取去当前状态相匹配的第一个Item,而不是最匹配的那一个。

语法:

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"    android:constantSize=["true" | "false"]    android:dither=["true" | "false"]    android:variablePadding=["true" | "false"] >    <item        android:drawable="@[package:]drawable/drawable_resource"        android:state_pressed=["true" | "false"]        android:state_focused=["true" | "false"]        android:state_hovered=["true" | "false"]        android:state_selected=["true" | "false"]        android:state_checkable=["true" | "false"]        android:state_checked=["true" | "false"]        android:state_enabled=["true" | "false"]        android:state_activated=["true" | "false"]        android:state_window_focused=["true" | "false"] /></selector>

元素解释

  • drawable 每一个状态需要设置的图片
  • state_pressed 按下
  • state_focused 聚焦
  • state_selected 选择
  • state_checkable 勾选中
  • state_enabled 可用

示例

  • xml文件保存为res/drawable/button.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="@drawable/platlogo" /> <!-- pressed -->    <item android:state_focused="true"          android:drawable="@drawable/platlogo" /> <!-- focused -->    <item android:drawable="@drawable/platlogo_alt" /> <!-- default --></selector>
  • 在布局中应用

    <Button    android:layout_height="wrap_content"    android:layout_width="wrap_content"    android:background="@drawable/button" />

TransitionDrawable

  • 一个TransitionDrawable是一个特殊的Drawable对象,可以实现两个drawable资源之间淡入淡出的效果。
  • 每个drawable被定义在元素的标签中,最多只能有两个,如果向前过渡 调用startTransition()。如果向后过渡,调用reverseTransition()。

语法:

<?xml version="1.0" encoding="utf-8"?><transitionxmlns:android="http://schemas.android.com/apk/res/android" >    <item        android:drawable="@[package:]drawable/drawable_resource"        android:id="@[+][package:]id/resource_name"        android:top="dimension"        android:right="dimension"        android:bottom="dimension"        android:left="dimension" /></transition>

示例:有的时候你想做一个渐变的动画 比如你想让一张图片慢慢展现出来 此时你会想到使用Animation。但是这样循环调用会导致一开始图片就展示出来 这样就出现了问题。

  1. XML文件保存为:res/drawable/my_transaction.xml:

    <?xml version="1.0" encoding="utf-8"?><transition xmlns:android="http://schemas.android.com/apk/res/android" >    <item android:drawable="@android:color/transparent" />    <item android:drawable="@drawable/p6" /></transition>
  2. 在layout文件中使用:

    <ImageView    android:id="@+id/iv"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:src="@drawable/my_transaction"/>
  3. 如下代码可以让动画从第一张图片慢慢渐变到第二张图片 时间为1000毫秒

    ImageView iv = (ImageView) findViewById(R.id.iv);TransitionDrawable drawable = (TransitionDrawable) iv.getDrawable();drawable.startTransition(1000);

LayerListDrawable

该图片可将多张图片叠加在一起。最常用的地方就是Progress进度条的使用。

语法

<?xml version="1.0" encoding="utf-8"?><layer-list    xmlns:android="http://schemas.android.com/apk/res/android" >    <item        android:drawable="@[package:]drawable/drawable_resource"        android:id="@[+][package:]id/resource_name"        android:top="dimension"        android:right="dimension"        android:bottom="dimension"        android:left="dimension" /></layer-list>

元素解释

  • drawable引用的图片
  • top顶部偏移量
  • right bottom left 其余三个边的偏移量

示例

这里写图片描述

  1. XML文件保存为:res/drawable/my_layerlist.xml:

    <?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android">    <item android:drawable="@drawable/p2" />    <item        android:drawable="@drawable/p2"        android:left="30dp"        android:top="30dp"        android:right="-30dp"        android:bottom="-30dp"/>    <item        android:drawable="@drawable/p2"        android:left="50dp"        android:top="50dp"        android:right="-50dp"        android:bottom="-50dp"/></layer-list>
  2. 在layout文件中使用:(因为前面的图片超过了原图右下边50个像素 所以这里的大小要比原图宽高分别多50dp)

    <ImageView    android:id="@+id/iv"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:paddingBottom="50dp"    android:paddingRight="50dp"    android:src="@drawable/my_layerlist" />

LevelListDrawable

LevelList是一个可以管理一批交替的位图,每一个位图通过android:maxLevel属性分配一个最大限度的数字。当调用LevelList的setLevel()方法的时候,他会从上到下匹配合适的图片并显示出来.

语法:

<?xml version="1.0" encoding="utf-8"?><level-list xmlns:android="http://schemas.android.com/apk/res/android" >    <item        android:drawable="@drawable/drawable_resource"        android:maxLevel="integer"        android:minLevel="integer" /></level-list>

元素解释

  • 只能包含一个或者以上的
  • 定义一个位图在某一层级
    • android:maxLevel 该item的最高限度
    • android:minLevel 该item的最低限度

示例

  1. 在drawable文件夹下创建一个my_levellist图片

    <?xml version="1.0" encoding="utf-8"?><level-list xmlns:android="http://schemas.android.com/apk/res/android">    <item android:drawable="@drawable/p0" android:maxLevel="0"/>    <item android:drawable="@drawable/p1" android:maxLevel="1"/>    <item android:drawable="@drawable/p2" android:maxLevel="2"/>    <item android:drawable="@drawable/p3" android:maxLevel="3"/>    <item android:drawable="@drawable/p4" android:maxLevel="4"/>    <item android:drawable="@drawable/p5" android:maxLevel="5"/>    <item android:drawable="@drawable/p6" android:maxLevel="6"/>    <item android:drawable="@drawable/p7" android:maxLevel="7"/>    <item android:drawable="@drawable/p8" android:maxLevel="8"/></level-list>
  2. 在布局文件下做一个引用

    <ImageView    android:id="@+id/iv"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:paddingBottom="50dp"    android:paddingRight="50dp"    android:src="@drawable/my_levellist" />
  3. 在代码中,每次点击一下则修改图片,当然 可以根据具体业务而定

    @Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    mIv = (ImageView) findViewById(R.id.iv);    mIv.setOnClickListener(this);}@Overridepublic void onClick(View v) {    LevelListDrawable drawable = (LevelListDrawable) mIv.getDrawable();    mIndex=drawable.getLevel();    mIndex++;    if (mIndex>8){        mIndex=0;    }    drawable.setLevel(mIndex);}

InsetDrawable

表示一个drawable嵌入到另外一个drawable内部,并且在内部留一些间距,这一点很像drawable的padding属性,区别在于 padding表示drawable的内容与drawable本身的边距,insetDrawable表示两个drawable和容器之间的边距。当控件需要的背景比实际的图片边框小的时候比较适合使用InsetDrawable。

语法:

<?xml version="1.0" encoding="utf-8"?><inset    xmlns:android="http://schemas.android.com/apk/res/android"    android:drawable="@drawable/drawable_resource"    android:insetTop="dimension"    android:insetRight="dimension"    android:insetBottom="dimension"    android:insetLeft="dimension" />

元素解释

  • 定义InsetDrawable的根元素
    • android:drawable 需要被扩展的图片
    • android:insetTop=”dimension” 在该插图上面设置一些间距 其他属性类似

示例:

这里写图片描述

ShapeDrawable

一个定义如矩形 椭圆 线 环形的图片。一般我们的圆角输入框就是它来定义的。

语法:

<?xml version="1.0" encoding="utf-8"?><shape    xmlns:android="http://schemas.android.com/apk/res/android"    android:shape=["rectangle" | "oval" | "line" | "ring"]    android:innerRadius="dimension"    android:innerRadiusRatio="inetger"    android:thickness="dimension"    android:thicknessRatio="integer"    android:useLevel="boolean" >    <corners        android:radius="integer"        android:topLeftRadius="integer"        android:topRightRadius="integer"        android:bottomLeftRadius="integer"        android:bottomRightRadius="integer" />    <gradient        android:angle="integer"        android:centerX="float"        android:centerY="float"        android:centerColor="integer"        android:endColor="color"        android:gradientRadius="integer"        android:startColor="color"        android:type=["linear" | "radial" | "sweep"]        android:useLevel=["true" | "false"] />    <padding        android:left="integer"        android:top="integer"        android:right="integer"        android:bottom="integer" />    <size        android:width="integer"        android:height="integer" />    <solid        android:color="color" />    <stroke        android:width="integer"        android:color="color"        android:dashWidth="integer"        android:dashGap="integer" /></shape>

元素解释

  • 一个形状图形的根元素

    • android:shape 形状 可以是rectangle矩形 oval椭圆形 line线 ring环形
    • android:innerRadius=”dimension” 环形可用 定义内部的原型半径
    • android:thickness=”dimension” 环形厚度
    • android:innerRadiusRatio=”inetger” 环形内部半径比率 使用此属性要先定义 如果size宽度是100dp, 而该值写5,那么厚度为20dp
    • android:thicknessRatio=”integer” 环形厚度比例 计算跟上面一样
    • android:useLevel 是否在levellistDrawable中使用。 一般是false
  • corners圆角

    • android:radius定义圆角半径 这里定义的是四个圆角半径
    • topLeftRadius topRightRadius bottomLeftRadius bottomRightRadius 分别定义四个角的圆角半径
  • size 定义内容的大小

  • solid 定义填充色
  • gradient 定义渐变颜色
    • startColor centerColor endColor 开始中间结束的渐变颜色
    • angle 定义渐变的角度
    • type= linear线性 radial放射式 sweep扫过
  • stroke
    • android:width 形状线的粗细
    • android:color 形状线的颜色
  • padding 内边距

示例:环形

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"    android:innerRadiusRatio="3.3"    android:shape="ring"    android:thicknessRatio="5"    android:useLevel="false" >    <gradient        android:angle="45"        android:startColor="#FFFF0000"        android:centerColor="#FF00FF00"        android:endColor="#FF0000FF"        android:type="sweep" />    <stroke        android:width="1dp"        android:color="@android:color/black" />    <size        android:height="50dp"        android:width="50dp" /></shape>

示例:圆角背景

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" >    <stroke        android:width="1dp"        android:color="@android:color/black" />    <solid android:color="@android:color/white" />    <corners android:radius="4dp" /></shape>

Nine-Patch File

Nine-Patch File

文件位置

res/drawable/filename.9.png

示例

With an image saved at res/drawable/myninepatch.9.png, this layout XML applies the Nine-Patch to a View:

<Button    android:layout_height="wrap_content"    android:layout_width="wrap_content"    android:background="@drawable/myninepatch" />
0 0