首页 > 技术文章 > Android学习笔记_42_各种图形的炫酷效果的实现和使用

lbangel 2013-12-22 14:27 原文

一、文档位置:

  这里在android中的图形,在帮助文档的这个页面,
    android-sdk-windows\docs\guide\topics\resources\drawable-resource.html

二、图形种类:

  2.1 Bitmap:

  2.2 Nine-Patch File
  NinePatch是一种很有用的PNG图片格式,它可以在特定区域随文字大小进行缩放。如下:从上图可以看到,背景图片的中间区域会随着文字的大小进行缩放。背景图片是一张NinePatch图片。 NinePatch图片可以使用android自带的draw9patch工具来制作,该工具在SDK安装路径的tools目录下。执行该工具,然后点击“File”->“open 9-path”打开一张用于制作NinePatch图片的原来图片。在画布的上方和左方的边上画线指定缩放区域,勾选“Show patches”可显示画定的区域,绿色为固定大小区域,红色为缩放区域,文字会摆放在红色区域。制作完后,点击“File” “save 9-path”保存图片,draw9patch工具会自动为图片加上*.9.png后缀。把制作好的图片拷贝进项目的res/drawable目录,然后
编写代码。如下:

<TextView android:layout_width="wrap_content" 
    android:layout_height="wrap_content"
    android:text="退出" android:textColor="#330000"
    android:background="@drawable/button"/>

  Nine-Patch File这种图片可以指定在特定的区域进行缩放,比如,在一个图片中有文字,文字在图片的中间位置,右边是一个代表播放的三角图形,这时候当文字变多的时候,Nine-Patch File这种图图形,就可以拉伸中间位置,这样就可以撑得下更多的文字,而原来右边的代表播放的三角图形不会拉伸变化.
  cmd进入命令界面:
     输入:G:\android\android-sdk-windows\tools>draw9patch
  回车,这个时候就会看到制作9path图片的界面:这时候:点击“File”->“open 9-path”打开一张用于制作NinePatch图片的原来图片。
  在画布的上方和左方的边上画线指定缩放区域,勾选“Show patches”可显示画定的区域,绿色为固定大小区域,红色为缩放区域,文字会摆放在红色区域。制作完后,点击“File” “save 9-path”保存图片,draw9patch工具会自动为图片加上*.9.png后缀。

2.3 Layer List 层列表图形:

  可以使用一组图片合成一张图片,下面是文档中关于Layer List 层列表图形的介绍:
     file location: res/drawable/filename.xml,需要使用资源id,来找到这个文件.下面是源码:

<?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"   //给这个图片指定一个id  

        //下面这四个属性:上面,右边,底部,左边离边框的距离.
        android:top="dimension"
        android:right="dimension"
        android:bottom="dimension"
        android:left="dimension" />
</layer-list>

  应用: 一个相框中有一个美女图片,然后当点击切换按钮后,相框中的美女图片被切换了。

public class DrawableActivity extends Activity {
    private ImageView imageView;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       //2.找到imageView控件
        imageView = (ImageView) this.findViewById(R.id.imageView);
    }
    //1.点击按钮后会执行这个方法,切换图片
   public void changeImage(View v){ 
     //LayerDrawable layerDrawable = (LayerDrawable) imageView.getDrawable();
     //4.从imageview中取得,目前正在显示的照片,得到一个层列表图形layerDrawable
     //7.直接取得列表图形资源,然后设置,然后显示.这时候就可以了.所以这里有个特点
     //当drawable被imageview使用了,这时候要尝试修改它是没有用的,所以这里需要直接加载它,然后,再给它赋值就额可以了.
     LayerDrawable layerDrawable = (LayerDrawable)getResources().getDrawable(R.drawable.layerlist);
     Drawable drawable = getResources().getDrawable(R.drawable.icon);
     //6.首先取得资源对象.用getDrawable取得图形,得到图标这个图形,返回一个drawable图形.
     //将应用部署后,发现当点击按钮后,并不可以成功的切换图片,这里又尝试这样做.
     //5.这里第一个参数得到要切换的照片,这里指的是哪个在边框里面的图片
     //,第二个参数:是要切换的那张照片的drawable图形.(层列表图形.)
     layerDrawable.setDrawableByLayerId(R.id.userimage, drawable);
     //3.设置更换完的图形,这里要求传一个Drawable进去.
     imageView.setImageDrawable(layerDrawable);
    }
}

/drawable/res/drawable/icon.png
/drawable/res/drawable/user.png
/drawable/res/drawable/layerlist.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  <!-- 使用两张照片合成一个新的照片:faceback,和user
   -->
   <!-- 指定需要合成的单个照片 
     android:top="68dp"
        android:right="18dp"
        android:bottom="22dp"
        android:left="18dp"
        android:id="@+id/userimage"
        如果不写这几句,照片会整个的占满整个屏幕
        这个xml的内容,可以在帮助文档中,找到:
        file:///G:/android/android-sdk-windows/docs/guide/topics/resources/drawable-resource.html#LayerList
        example:XML file saved at res/drawable/layers.xml: <?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
      <bitmap android:src="@drawable/android_red"
        android:gravity="center" />
    </item>
    <item android:top="10dp" android:left="10dp">
      <bitmap android:src="@drawable/android_green"
        android:gravity="center" />
    </item>
    <item android:top="20dp" android:left="20dp">
      <bitmap android:src="@drawable/android_blue"
        android:gravity="center" />
    </item>
</layer-list>
    -->
    <item android:drawable="@drawable/faceback" />
    <item android:drawable="@drawable/user"
        android:top="68dp"
        android:right="18dp"
        android:bottom="22dp"
        android:left="18dp"
        android:id="@+id/userimage"
        />
         <!-- android:id="@+id/userimage"使用这个属性给图片定义一个id -->
</layer-list>

/drawable/res/layout/main.xml

  <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <!-- 这里用一个imageView控件,实现图片的存放 -->
<ImageView  
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:src="@drawable/layerlist"
    android:id="@+id/imageView"
    />
<!-- 点击按钮后,要求实现图片切换的功能 :-->
 <Button
   android:background="@drawable/rectangle"
  android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="切换"
    android:onClick="changeImage"
 />
</LinearLayout>

注意:层列表图形,就可以用来开发,给图片加相框的功能,只要是想要多张照片合成一张照片的时候,都可以用到层列表图形
2.4 State List 状态列表图形:

   当我们点击某个按钮,或者是某个控件的时候,会切换图片,也就是随着,控件的状态来显示不同的图形.
   这里实现,当按钮显示的时候显示一张照片,当按钮被按下去的时候,显示另一张照片
   文件位置: res/drawable/filename.xml
   语法:

<?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"]]
 //true:按下这个显示控件的时候,显示这张照片
 //false:没有按下这个显示控件的时候,显示这张照片
        android:state_focused=["true" | "false"]
        //true:当这个显示控件得到焦点的时候,显示这张照片
 //false:当这个显示控件没得到焦点的时候,显示这张照片
        android:state_hovered=["true" | "false"]
 //这个没有标明,用的时候可以查查.
        android:state_selected=["true" | "false"]
 //true:当这个显示控件被选择的时候,显示这张照片
 //false:当这个显示控件不被选择的时候,显示这张照片
 //这里选择是指的用上下键,当有框,或不同颜色,指定这个控件被选择的时候
        android:state_checkable=["true" | "false"]
 //true:当这个显示控件可以被勾选的时候,显示这张照片
 //false:当这个显示控件不可以被勾选的时候,显示这张照片
        android:state_checked=["true" | "false"]
 //true:当这个显示控件被勾选的时候,显示这张照片
 //false:当这个显示控件不被勾选的时候,显示这张照片
        android:state_enabled=["true" | "false"]
 //true:当这个显示控件被可用的时候,显示这张照片
 //false:当这个显示控件不可用的时候,显示这张照片
        android:state_window_focused=["true" | "false"] />
 //true:当该控件所在窗口获得焦点的时候,显示这张照片
 //false:当该控件所在窗口没获得焦点的时候,显示这张照片
 //这些就是显示控件的不同状态.
</selector>

 

2.5 Level List 级别列表图形:
  类型图形可以用于管理一组可进行切换的图片。使用setLevel方法可以进行图片切换,Android会根据level的值自动选择对应的图片。手机显示剩余电量就是用Level List图形来显示不同图片的。
  文件位置: res/drawable/filename.xml
  语法

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

2.6 Transition Drawable 过程图形:

  也就是从一张图片过度到另一张图片
  文件位置: res/drawable/filename.xml

<xml version="1.0" encoding="utf-8"?>
<transition
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" />
</transition>

2.7 Clip Drawable 剪切图形:

      Clip Drawable类型图形(裁剪图形)
  文件位置: res/drawable/filename.xml

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

2.8 Scale Drawable 缩放图形:
file:///G:/android/android-sdk-windows/docs/guide/topics/resources/drawable-resource.html#StateList
2.9 Shape Drawable 形状图形:

  file location: res/drawable/filename.xml
 The filename is used as the resource ID.
 b.resource reference: In Java: R.drawable.filename
 In XML: @[package:]drawable/filename 
 android:shape=["rectangle" | "oval" | "line" | "ring"] > 矩形,椭圆形,线性,环形.

<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape=["rectangle" | "oval" | "line" | "ring"] >
    //这个用来指定形状
    <corners
    //这个指的是圆角的,圆角的大小由半径决定的.
        android:radius="integer"
 //如果一个矩形的四个角的圆角,大小都一样的话就只设置这个就行了
        android:topLeftRadius="integer"
        android:topRightRadius="integer"
        android:bottomLeftRadius="integer"
        android:bottomRightRadius="integer" 
 //如果矩形的,四个圆角的大小不一样的话,那么需要进行每个圆角的半径设置,这时候就
 //用到了下面的四个属性.
 />
    <gradient
    //这个是渐变,用来指定渐变的颜色,可以由一种颜色过渡到另一种颜色,
    //还可以在从一种颜色过渡到另一种颜色的时候,指定一个中间色.
        android:angle="integer"
 //这个是角度.渐变是有角度的,从一种颜色过渡到另一个颜色,
 //指定是水平的还是180度...还是多少度..等等.
        android:centerX="integer"//中间过渡色出现在什么地方
        android:centerY="integer"////中间过渡色出现在什么地方
        android:centerColor="integer"//指定中间过渡色是什么颜色.
 //这三个用来指定过渡色
        android:endColor="color"//过渡色的结束颜色
        android:gradientRadius="integer"//当时圆形渐变色的时候,需要指定渐变的半径
        android:startColor="color"//过渡色的开始颜色
        android:type=["linear" | "radial" | "sweep"]//指定是什么渐变色,比如,
 //线性渐变色,还是圆形渐变色...当时圆形渐变色的时候,需要指定渐变半径
        android:usesLevel=["true" | "false"] />//是否使用级别,可以设为默认值就可以
    <padding//指定内间距,假设定义了一个矩形,那么内间距,就是内容离矩形的边界线的距离.
        android:left="integer"
        android:top="integer"
        android:right="integer"
        android:bottom="integer" />
    <size//代表,线框的宽
        android:width="integer"//定义边界线的粗细.
        android:height="integer"
  android:dashWidth="integer"//当边界是虚线的时候,用来定义
        android:dashGap="integer"//定义虚线的宽度.
 />
    <solid//单一填充色,这个和渐变色是不可以同时使用的.
        android:color="color" />
    <stroke//这个和size差不多
        android:width="integer"
        android:color="color"
        android:dashWidth="integer"
        android:dashGap="integer" />
</shape>

三、后台代码:

  包含以上图形的后台实现。

 

public class DrawableActivity extends Activity {
    private ImageView imageView;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       //2.找到imageView控件
        imageView = (ImageView) this.findViewById(R.id.imageView);
    }
    //1.点击按钮后会执行这个方法,切换图片
   public void changeImage(View v){
     //这个是用来测试,裁剪动画的.
     ClipDrawable clipDrawable = (ClipDrawable) imageView.getDrawable();
     //取得裁剪图形.
    clipDrawable.setLevel(clipDrawable.getLevel()+1000);
     //指定级别,如果级别值是0,代表全部裁剪,所以设置为0的时候,会全部裁剪,看不到
    //当为10000的时候会不裁剪.全部显示.
     
     //得到相应的,这里v是传进来的,这里需要(Button)v把传进来的v转换为button控件
    //然后调用button控件的.getBackground(),方法,(TransitionDrawable)
    //这里再把button的Background转换为过度显示图形.
    //然后设置,过度的事件为500毫秒.
    TransitionDrawable transitionDrawable = (TransitionDrawable) ((Button)v).getBackground();
     transitionDrawable.startTransition(500);
     
    
     /*下面是用来实现图片的级别列表图形的,也就是当级别12,在对应的图片设置的级别
      * 范围内的时候,就会显示对应的图片
      * LevelListDrawable levelListDrawable = (LevelListDrawable) imageView.getDrawable();
     levelListDrawable.setLevel(12);*/
     
    
     /*下面这个部分是用来测试层列表图形的
      * 
      * //LayerDrawable layerDrawable = (LayerDrawable) imageView.getDrawable();
     //4.从imageview中取得,目前正在显示的照片,得到一个层列表图形layerDrawable
     //7.直接取得列表图形资源,然后设置,然后显示.这时候就可以了.所以这里有个特点
     //当drawable被imageview使用了,这时候要尝试修改它是没有用的,所以这里需要直接加载它
     //然后,再给它赋值就额可以了.
     LayerDrawable layerDrawable = (LayerDrawable)getResources().getDrawable(R.drawable.layerlist);
     Drawable drawable = getResources().getDrawable(R.drawable.icon);
     //6.首先取得资源对象.用getDrawable取得图形,得到图标这个图形,返回一个drawable图形.
     //将应用部署后,发现当点击按钮后,并不可以成功的切换图片,这里又尝试这样做.
     //5.这里第一个参数得到要切换的照片,这里指的是哪个在边框里面的图片
     //,第二个参数:是要切换的那张照片的drawable图形.(层列表图形.)
     layerDrawable.setDrawableByLayerId(R.id.userimage, drawable);
     //3.设置更换完的图形,这里要求传一个Drawable进去.
     imageView.setImageDrawable(layerDrawable);
     */
    }
}

/drawable/res/drawable/bg_normal.9.png
/drawable/res/drawable/bg_selected.9.png
/drawable/res/drawable/clip.xml

 <?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/user"
    android:clipOrientation="horizontal"
    android:gravity="left" />
<!-- 
 android:drawable="@drawable/user"用来指定对哪张图片裁剪,
 android:clipOrientation="horizontal"是水平裁剪,还是垂直裁剪
 android:gravity="left" 裁剪的方向是从左到右 -->

/drawable/res/drawable/faceback.png
/drawable/res/drawable/icon.png
/drawable/res/drawable/layerlist.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  <!-- 使用两张照片合成一个新的照片:faceback,和user
   -->
   <!-- 指定需要合成的单个照片 
     android:top="68dp"
        android:right="18dp"
        android:bottom="22dp"
        android:left="18dp"
        android:id="@+id/userimage"
        如果不写这几句,照片会整个的占满整个屏幕
        这个xml的内容,可以在帮助文档中,找到:
        file:///G:/android/android-sdk-windows/docs/guide/topics/resources/drawable-resource.html#LayerList
        example:XML file saved at res/drawable/layers.xml: <?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
      <bitmap android:src="@drawable/android_red"
        android:gravity="center" />
    </item>
    <item android:top="10dp" android:left="10dp">
      <bitmap android:src="@drawable/android_green"
        android:gravity="center" />
    </item>
    <item android:top="20dp" android:left="20dp">
      <bitmap android:src="@drawable/android_blue"
        android:gravity="center" />
    </item>
</layer-list>
    -->
    <item android:drawable="@drawable/faceback" />
    
    <item android:drawable="@drawable/user"
        android:top="68dp"
        android:right="18dp"
        android:bottom="22dp"
        android:left="18dp"
        android:id="@+id/userimage"
        />
         <!-- android:id="@+id/userimage"使用这个属性给图片定义一个id 
         -->
        
</layer-list>

drawable/res/drawable/levellist.xml

<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 这里只要是级别的值为0到10的时候显示这一张照片 -->
    <item android:drawable="@drawable/faceback" android:minLevel="0" android:maxLevel="10" />
    <item android:drawable="@drawable/user" android:minLevel="11" android:maxLevel="20"/>
</level-list>

drawable/res/drawable/rectangle.xml

  <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
   <!-- //渐变色,渐变角度270度 -->
    <gradient
        android:startColor="#FFFF0000"
        android:endColor="#80FF00FF"
        android:angle="270"/>
    <!-- //内间距 -->
    <padding android:left="7dp"
        android:top="7dp"
        android:right="7dp"
        android:bottom="7dp" />
    <!-- //圆角的大小 -->
    <corners android:radius="8dp" />
   <!-- //边界线,宽度2个像素,颜色:#FFFFFF,虚线的间隔线8个像素,间隔,也就是没有颜色的空隙
   //是2个像素 -->
    <stroke
        android:width="2dp"
        android:color="#FFFFFF"
        android:dashWidth="8dp"
        android:dashGap="4dp" />
</shape>

/drawable/res/drawable/statelist.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
   <!--  注意这里所有的状态是可以组合使用的.比如这里指定,当这个控件
   被按下去,并且这个控件可用的时候显示这张图片
    -->
    <item android:state_pressed="true" android:state_enabled="true" android:drawable="@drawable/bg_selected" /> <!-- pressed -->
 <!--  //true:按下这个显示控件的时候,显示这张照片
 //false:没有按下这个显示控件的时候,显示这张照片 -->
    <item android:state_selected="true" android:drawable="@drawable/bg_selected" /> <!-- focused -->
   <!--  //true:当这个显示控件被选择的时候,显示这张照片
 //false:当这个显示控件不被选择的时候,显示这张照片 -->
    <item android:drawable="@drawable/bg_normal" /> <!-- default -->
    <!-- 这个代表匹配所有的状态,比如有一个状态发生了,这个状态先和前面的状态匹配,如果和前面
    的都不匹配,那么就和这个匹配 -->
</selector>

drawable/res/drawable/transition.xml

  <?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
   <!-- 过度是需要在代码中控制的,这里要求当过度方式的时候,从这一张图片过度到下面的这一张图片 -->
    <item android:drawable="@drawable/bg_normal" />
    <item android:drawable="@drawable/bg_selected" />
</transition>


/drawable/res/drawable/user.png
drawable/res/layout/main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <!-- 这里用一个imageView控件,实现图片的存放 
    android:src="@drawable/layerlist"
    这个imageview是用来测试,层列表图形的.
      android:src="@drawable/levellist"
   这个是用来测试,级别图形的.
    -->
 
<ImageView  
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:src="@drawable/clip"
    android:id="@+id/imageView"
    />
<!-- 点击按钮后,要求实现图片切换的功能 :-->
 <!-- android:background="@drawable/statelist" 
这里用来测试,过度类型图形
android:background="@drawable/transition"
这里是用来测试形状类型图形的
 android:background="@drawable/rectangle"
 
 -->
 <Button
   android:background="@drawable/rectangle"
  android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="切换"
    android:onClick="changeImage"
 />
</LinearLayout>

 

推荐阅读