Drawable资源

 在Android应用中,常常会用到Drawable资源,比如图片资源等,在Android开发中我们是用Drawable类来Drawable类型资源的。

Drawable资源一般存储在应用程序目录的\res\drawable目录下,当然依据分辨率的高低可以分别存储不同分辨率的资源到如下几个目录:

\res\drawable-hdpi

\res\drawable-mdpi

\res\drawable-xhdpi

\res\drawable-xxhdpi

其SDK文档中声明如下:

我们看到Drawable是一个抽象类(abstract class),它有好多子类(SubClass)来操作具体类型的资源,比如BitmapDrawable是用来操作位图,ColorDrawable用来操作颜色,

ClipDrawable用来操作剪切板等。

图片资源

图片资源是简单的Drawable资源,目前Android支持的图片格式有:gif、png、jpg等。我们只需要把图片资源放置到\res\drawable目中,那么在编译后的R.java类中就会生成图片资源的资源ID

我们在程序中就可以通过调用相关的方法来获取图片资源(程序中如果要访问drawable_resource_file_name,那么可以如此:[packagename].R.drawable.drawable_resource_file_name)。

注:Android中drawable中的资源名称有约束,必须是: [a-z0-9_.](即:只能是字母数字及_和.),而且不能以数字开头,否则编译会报错: Invalid file name: must contain only [a-z0-9_.]

以下代码片段演示了如何访问一个图片资源(资源名称drawablefilename):

ImageView imageView=(ImageView)findViewById(R.id.ImageView1);
imageView.setImageResource(R.drawable.drawablefilename);


StateListDrawable资源

StateListDrawable内可以分配一组Drawable资源,StateListDrawable 被定义在一个XML文件中,以 <selector>元素起始。其内部的每一个Drawable资源内嵌在<item>元素中。

当StatListDrawable资源作为组件的背景或者前景Drawable资源时,可以随着组件状态的变更而自动切换相对应的资源,例如,一个Button可以处于不同的状态(按钮按下、获取焦点)

我们可以使用一个StateListDrawable资源,来提供不同的背景图片对于每一个状态。,当组件的状态变更时,会自定向下遍历StateListDrawable对应的xml文件来查找第一个匹配的Item。

StatListDrawable资源所支持的组件状态如下图所示:

android:state_selected是选中
android:state_focused
是获得焦点
android:state_pressed
是点击
android:state_enabled
是设置是否响应事件,指所有事件

以下代码片段是一个StateListDrawable资源的XML文件描述样例:

XML 文件存储在: res/drawable/button_statelist.xml:

<?xmlversion="1.0"encoding="utf-8"?><selectorxmlns:android="http://schemas.android.com/apk/res/android"><itemandroid:state_pressed="true"android:drawable="@drawable/button_pressed"/><!-- pressed --><itemandroid:state_focused="true"android:drawable="@drawable/button_focused"/><!-- focused --><itemandroid:state_hovered="true"android:drawable="@drawable/button_focused"/><!-- hovered --><itemandroid:drawable="@drawable/button_normal"/><!-- default --></selector>

以下是Button的Layout文件:

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

当然我们也可以通过代码来设置Button的背景图片:

Button imageButton=(Button)findViewById(R.id.imageButton);

imageButton.setBackgroundResource(R.drawable.button_statelist);

在ListView中使用:
1.方法一:在listview中配置android:listSelector="@drawable/xxx
或者在listview的item中添加属性android:background="@drawable/xxx"

2.方法二:Drawable drawable = getResources().getDrawable(R.drawable.xxx);  
       ListView.setSelector(drawable);但是这样会出现列表有时候为黑的情况,需要加上:android:cacheColorHint="@android:color/transparent"使其透明。


参数说明:

其中selected和focused的区别有如下几点:

      1,我们通过查看setSelected()方法,来获取相关信息。

        SDK中对setSelected()方法----对于与selected状态有如下说明:

             public void setSelected (boolean selected)

             Since: APILevel 1

             Changes the selection state of this view. Aview can be selected or not. Note that selection is not the same as

        focus. Views are typically selected in the context of an AdapterView like ListView or GridView ;the selected view is 

        the view that is highlighted.

            Parameters selected   true if the view must be selected, false otherwise


           由以上可知:selected不同于focus状态,通常在AdapterView类群下例如ListView或者GridView会使某个View处于

     selected状态,并且获得该状态的View处于高亮状态。

 

    2、一个窗口只能有一个视图获得焦点(focus),而一个窗口可以有多个视图处于”selected”状态中。

 

      总结:focused状态一般是由按键操作引起的;

                pressed状态是由触摸消息引起的;

                selected则完全是由应用程序主动调用setSelected()进行控制。

 

      例如:当我们触摸某个控件时,会导致pressed状态改变;获得焦点时,会导致focus状态变化。于是,我们可以通过这种

   更新后状态值去更新我们对应的Drawable对象了。

ShapeDrawable资源

ShapeDrawable资源绘制一个特定的形状,比如矩形、椭圆等。如果你想自己动态的绘制二位图形,那么我们就可以使用ShapeDrawable资源对象,用ShapeDrawable,我们可以绘制我们所能想象的形状。。一个ShapeDrawable 需要一个Shape对象来管理呈现资源到UI Screen,如果没有Shape设置,那么会默认使用RectShape对象。

ShapeDrawable 被定义在一个XML文件中,以 <shape> 元素起始。其内部的每一个Drawable资源内嵌在<item>元素中

以下代码片段便是一个ShapeDrawable的XML定义

<?xmlversion="1.0"encoding="UTF-8"?><shapexmlns:android="http://schemas.android.com/apk/res/android"android:shape="oval"><!-- 定义填充渐变颜色 --><gradientandroid:startColor="#00f"android:endColor="#00f"android:angle="45"android:type="sweep"/><!-- 设置内填充 --><paddingandroid:left="7dp"android:top="7dp"android:right="7dp"android:bottom="7dp"/>
    <!-- 设置背景色
    <solid android:color="#00f"/>
    -->
    <!-- 设置圆角矩形 
<cornersandroid:radius="8dp"/></shape>

参数说明:

<!-- 

  android:shape=["rectangle" | "oval" | "line" | "ring"]

  shape的形状,默认为矩形,可以设置为矩形(rectangle)、椭圆形(oval)、线性形状(line)、环形(ring)

  下面的属性只有在android:shape="ring时可用:

  android:innerRadius 尺寸,内环的半径。

  android:innerRadiusRatio 浮点型,以环的宽度比率来表示内环的半径,

  例如,如果android:innerRadiusRatio,表示内环半径等于环的宽度除以5,这个值是可以被覆盖的,默认为9.

  android:thickness 尺寸,环的厚度

  android:thicknessRatio 浮点型,以环的宽度比率来表示环的厚度,例如,如果android:thicknessRatio="2",

  那么环的厚度就等于环的宽度除以2。这个值是可以被android:thickness覆盖的,默认值是3.

  android:useLevel boolean值,如果当做是LevelListDrawable使用时值为true,否则为false.

  -->

<shape

    xmlns:android="http://schemas.android.com/apk/res/android"

    android:shape="rectangle">


<!--

      圆角 

      android:radius   整型 半径

      android:topLeftRadius   整型 左上角半径

      android:topRightRadius   整型 右上角半径

      android:bottomLeftRadius 整型 左下角半径

      android:bottomRightRadius 整型 右下角半径

     -->

<corners  

        android:radius="8dp"

        android:topLeftRadius="5dp"

        android:topRightRadius="15dp"

        android:bottomLeftRadius="20dp"

        android:bottomRightRadius="25dp"  

        />


<!--

        渐变色

        android:startColor  颜色值 起始颜色

        android:endColor    颜色值 结束颜色

        android:centerColor 整型   渐变中间颜色,即开始颜色与结束颜色之间的颜色

        android:angle       整型   渐变角度(PS:当angle=0时,渐变色是从左向右。 然后逆时针方向转,当angle=90时为从下往上。angle必须为45的整数倍)

        android:type        ["linear" | "radial" | "sweep"] 渐变类型(取值:linear、radial、sweep)

                            linear 线性渐变,这是默认设置

                            radial 放射性渐变,以开始色为中心。

                            sweep 扫描线式的渐变。

       android:useLevel   ["true" | "false"] 如果要使用LevelListDrawable对象,就要设置为true。设置为true无渐变。false有渐变色

       android:gradientRadius 整型 渐变色半径.当 android:type="radial" 时才使用。单独使用 android:type="radial"会报错。

       android:centerX     整型   渐变中心X点坐标的相对位置

       android:centerY   整型   渐变中心Y点坐标的相对位置

    -->

    <gradient

        android:startColor="#FFFF0000"

        android:endColor="#80FF00FF"

        android:angle="45"

        /> 

        

    <!--

          内边距,即内容与边的距离 

          android:left   整型 左内边距

          android:top   整型 上内边距

          android:right   整型 右内边距

          android:bottom 整型 下内边距

      -->

     <padding 

         android:left="10dp"

         android:top="10dp"

         android:right="10dp"

         android:bottom="10dp"

         />

     

    <!-- 

       size 大小

       android:width 整型 宽度

       android:height 整型 高度

    -->

    <size

        android:width="600dp"

        />

    

    <!--

        内部填充

        android:color 颜色值 填充颜色

    -->

    <solid 

        android:color="#ffff9d77"

        />

    

     <!--

         描边

         android:width 整型 描边的宽度

         android:color 颜色值 描边的颜色

         android:dashWidth 整型 表示描边的样式是虚线的宽度, 值为0时,表示为实线。值大于0则为虚线。

         android:dashGap   整型 表示描边为虚线时,虚线之间的间隔 即“ - - - - ”

     -->

     <stroke 

        android:width="2dp"

        android:color="#dcdcdc"  

        /> 


我们可以用ShapeDrawable 来设置组件的背景色(用setBackgroundDrawable()方法),如上的代码片段可设置一个TextEdit的背景色为蓝色的椭圆形状。当然我们也可以绘制自定义的View

我们构建自定义形状的View时,由于ShapeDrawable 有其自己的draw()方法,我们可以构建一个View视图的子类,然后override View.onDraw()方法,如下代码片段是一个样例:

publicclass CustomDrawableView extends View {
      private ShapeDrawable mDrawable;

      public CustomDrawableView(Context context) {
      super(context);

      int x = 10;
      int y = 10;
      int width = 300;
      int height = 50;

      mDrawable = new ShapeDrawable(new OvalShape());
      mDrawable.getPaint().setColor(0xff74AC23);
      mDrawable.setBounds(x, y, x + width, y + height);
      }

      protectedvoid onDraw(Canvas canvas) {
      mDrawable.draw(canvas);
      }
    }

基于上述代码我们可以在我们的Activity中编程的构建自定义视图:

CustomDrawableView mCustomDrawableView;

      protectedvoid onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      mCustomDrawableView = new CustomDrawableView(this);

      setContentView(mCustomDrawableView);
      }

当然我们也可以使用XML文件来描述:自定义的Drawable类必须重载view (Context, AttributeSet) 构造函数。接着我们添加Layout文件如下:

<com.example.shapedrawable.CustomDrawableView
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      />

ClipDrawable

ClipDrawable资源定义在一个XML中,表示裁剪(Clips)一个其他资源基于ClipDrawable资源的Level。你可以控制裁剪的Drawable的宽度高度及gravity属性,ClipDrawable常常被用来作为一个progressbars的实现。

以下样例是一个ClipDrawable资源:

<?xmlversion="1.0"encoding="utf-8"?><clipxmlns:android="http://schemas.android.com/apk/res/android"android:drawable="@drawable/android"android:clipOrientation="horizontal"android:gravity="left"/>

下面的ImageView布局文件应用Clipdrawable资源:

 

<ImageViewandroid:id="@+id/image"android:background="@drawable/clip"android:layout_height="wrap_content"android:layout_width="wrap_content"/>
下面的代码获取drawable并且增加其裁剪,以便于渐增的显示图像
ImageView imageview = (ImageView) findViewById(R.id.image);

ClipDrawable drawable = (ClipDrawable) imageview.getDrawable();

drawable.setLevel(drawable.getLevel() + 1000);

当然我们可以使用一个Timer来实现图片的渐增显示。

注意: 默认的Level值是0,表示图片被这个裁剪,故图片是不可见的。当值达到10000是代码裁剪为0,图片可以完全显示。



AnimationDrawable

AnimationDrawable通过定义一系列的Drawable对象构建一个基于帧的动画(frame-by-frame animations),可以被用来作为视图的背景色。

最简单的构建一个帧动画是在XML文件中构建一个动画,我们可以设定动画作为视图的背景色,通过调用AnimationDrawable.start()方法来运行动画。

如下代码片段是一个AnimationDrawable资源的XML文件,资源文件位置:res\drawable\spin_animation.xml

<animation-listxmlns:android="http://schemas.android.com/apk/res/android"android:oneshot="true"><itemandroid:drawable="@drawable/rocket_thrust1"android:duration="200"/><itemandroid:drawable="@drawable/rocket_thrust2"android:duration="200"/><itemandroid:drawable="@drawable/rocket_thrust3"android:duration="200"/></animation-list>

我们可以看到,AnimationDrawable资源文件以<animation-list>元素为根,包含一系列的<Item>节点,每一个节点定义了一个帧(frame)及持续时常。

上述动画运行了3个帧,通过设置android:oneshot 属性(attribute)为true,动画会循环一次并停留在最后一帧,如果为false那么会轮询(loop)的运行动画

我们可以通过编码来加载播放动画:

// Load the ImageView that will host the animation and// set its background to our AnimationDrawable XML resource.
 ImageView img = (ImageView)findViewById(R.id.spinning_wheel_image);
 img.setBackgroundResource(R.drawable.spin_animation);

 // Get the background, which has been compiled to an AnimationDrawable object.
 AnimationDrawable frameAnimation = (AnimationDrawable) img.getBackground();

 // Start the animation (looped playback by default).
 frameAnimation.start();
 

注意:AnimationDrawable. start()方法不能够在Activity的onCreate()方法中调用,因为AnimationDrawable还未完全的附加(attached)到Window,如果你不需要交互而立即播放动画,那么可以在onWindowFocusChanged() 方法中,这个方法会在你的Activity Windows获取焦点是触发。

结束语

至此我们的Drawable资源就介绍完了,当然还有好多的Drawable子类未进行介绍,感兴趣的可以关注SDK文档。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值