res/资源文件

本文详细介绍了Android应用中res/目录的各个子目录及其用途,包括动画、颜色、布局、菜单、图片、值和XML文件等。讲解了九宫格图片、Drawable资源、帧动画、矢量图以及矢量动画的创建和使用,还涉及兼容性问题的解决策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

res/目录是放置预置资源的地方

tips:1.不可以在res/目录下直接创建资源文件,否则会出现编译异常
      2.res/子目录下不可以再有子目录
      3.res/子目录/文件名由字母、数字和下划线组成,且只能以英文小写字母或下划线开始。英文字母只能是小写的。
        如果不符合以上规则,文件不会映射到R.Java文件中。

res/目录下的子目录:

  • res/anim/:定义valueAnimation中的tweenAnimation(补间动画)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@[package:]anim/interpolator_resource"
    android:shareInterpolator=["true" | "false"] >
    <alpha
        android:fromAlpha="float"
        android:toAlpha="float" />
    <scale
        android:fromXScale="float"
        android:toXScale="float"
        android:fromYScale="float"
        android:toYScale="float"
        android:pivotX="float"
        android:pivotY="float" />
    <translate
        android:fromXDelta="float"
        android:toXDelta="float"
        android:fromYDelta="float"
        android:toYDelta="float" />
    <rotate
        android:fromDegrees="float"
        android:toDegrees="float"
        android:pivotX="float"
        android:pivotY="float" />
    <set>
        ...
    </set>
</set>


//在代码中实例化
Animation animation =  AnimationUtils.loadAnimation(this, R.anim.anim);
view.startAnimation(animation);//将valueAnimation用于view上并启动动画

  • res/animator/:定义propertyAnimation(属性动画)
<set
  android:ordering=["together" | "sequentially"]>

    <objectAnimator
        android:propertyName="string"
        android:duration="int"
        android:valueFrom="float | int | color"
        android:valueTo="float | int | color"
        android:startOffset="int"
        android:repeatCount="int"
        android:repeatMode=["repeat" | "reverse"]
        android:valueType=["intType" | "floatType"]/>

    <animator
        android:duration="int"
        android:valueFrom="float | int | color"
        android:valueTo="float | int | color"
        android:startOffset="int"
        android:repeatCount="int"
        android:repeatMode=["repeat" | "reverse"]
        android:valueType=["intType" | "floatType"]/>


 </set>


//在代码中实例化
Animator animator  = AnimatorInflater.loadAnimator(this, R.animator.animator);
 animator.setTarget(button1);//设置动画的目标对象
 animator.start();//启动动画

  • res/color/:定义color-state-list(不同状态下显示不同颜色)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:color="hex_color"//满足一下状态时的颜色(16进制数可以是#RGB/#ARGB)
        android:state_pressed=["true" | "false"]//被按压的状态
        android:state_focused=["true" | "false"]//在前台获得焦点状态
        android:state_selected=["true" | "false"]//被选择的状态(如tab中被选择)
        android:state_checkable=["true" | "false"]//能否复选状态
        android:state_checked=["true" | "false"]//复选被选择状态
        android:state_enabled=["true" | "false"]//能被触摸或点击状态
        android:state_window_focused=["true" | "false"] />
      <item
         android:color="#ff66dd"/>  
</selector>

//注意:系统选择状态的顺序是,根据xml中从上往下,符合当前状态的第一个列表项将被应用,因此,默认值(没有状态要求的)列表项应该放在最后一位

//在代码中实例化
int color = getResources().getColorStateList(R.color.dd);
button.setTextColor(color);

  • res/ interpolator/:定义动画加速器

  • res/layout/:定义视图布局

  • res/menu/:定义菜单(optionMenu(actionBar中menu,contextMenu(长按弹出的menu),subMenu(menu的item点击弹出的子菜单)
//属性介绍
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@[+][package:]id/resource_name"
          android:title="string"
          android:titleCondensed="string"//简要标题,当标题太长无法显示完全时使用
          android:icon="@[package:]drawable/drawable_resource_name"
          android:onClick="method name"//点击事件方法,在activity中与button的onclick一样,必须是
                                         public void的方法,参数只有一个MenuItem,可以覆盖
                                         onOptionItemSelected()方法
          android:showAsAction=["ifRoom" | "never" | "withText" | "always" | "collapseActionView"]
          android:actionLayout="@[package:]layout/layout_resource_name"
          android:actionViewClass="class name"
          android:actionProviderClass="class name"
          android:alphabeticShortcut="string"//item的字母快捷键
          android:numericShortcut="string" //item 的数字快捷键
          android:checkable=["true" | "false"]//是否设置选择框
          android:visible=["true" | "false"]//是否可见
          android:enabled=["true" | "false"]
          android:menuCategory=["container" | "system" | "secondary" | "alternative"] //item的优先级
          android:orderInCategory="integer" />//item的顺序级别,空间不足时,级别数字大的会被优先放入overflow中
    <group     //为某些具有部分相同属性的items创建一个集合群 
           android:id="@[+][package:]id/resource name"
           android:checkableBehavior=["none" | "all" | "single"]//group的选择模式,单选或者复选
           android:visible=["true" | "false"]
           android:enabled=["true" | "false"]
           android:menuCategory=["container" | "system" | "secondary" | "alternative"]
           android:orderInCategory="integer" >
        <item />
    </group>
    <item >
        <menu>//为item创建一个子菜单(SubMenu)在点击item时会弹出子菜单
          <item />
        </menu>
    </item>
</menu>

在代码中实例化:
//创建OptionsMenu:
public boolean onCreateOptionsMenu(Menu menu) {
         getMenuInflater().inflate(R.menu.option_menu,menu);//实例化menu并作为OptionsMenu的布局
         return true;
    }
//创建ContextMenu:

 @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        getMenuInflater().inflate(R.menu.content_menu, menu);
        super.onCreateContextMenu(menu, v, menuInfo);
    }
//为view添加ContextView
     registerForContextMenu(view);
//为adapterView(如ListView GridView)添加上下文菜单
  listView.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
  @Override
  public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
                getMenuInflater().inflate(R.menu.content_menu, menu);
            }
        });  
//为ContextMenu添加点击事件
  @Override
    public boolean onContextItemSelected(MenuItem item) {
     AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();//注册上下文菜单的是adapterView时
     int position = menuInfo.position;//长按跳出上下文菜单的item的index值,可以对该item进行操作
         return super.onContextItemSelected(item);
        }
    }


optionsMenu的具体类容见ToolBar和ActionBar内容


  • res/mipmap/:放置程序图片和drawable一样(建议放在drawable里面),很少用到

  • res/raw/:原生文件存放的目录(会被编译成二进制,映射在R.class中,可以存较大文件,不可以再有子目录)

  • res/transition/

  • res/values/:定义一些简单的值如String,color,styles,attrs,arrays等(每个resource中的单个项目都表示 一个类型的resource,因此可以混合定义,也可以把相同的类型资源放在一个单独的文件里
style为attrs的集合用于设置view的属性集(宽高,背景,字体等),theme为设置给activity或者application的style


(1).自定义属性attrs
     在res/values/目录下新建一个attrs.xml文件用于统一定义attrs属性
     <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="com.example.wendy.MyView">//declare-styleable节点是为了在自定
                                                           义view时方便通过typearray来找到该属性
            <attr name="showText" format="color"/>//format为属性值得类型,可有以下几种取值
                                                    (color(十六进制的颜色
                                                    值),boolean,dimension(测量长度值),enum(需要
                                                    有enum子节点),flag(需要有子节
                                                    点),float,fraction(百分
                                                    比),integer,reference(资源引用res文件夹下的
                                                    资源),string)

        </declare-styleable>
    </resources>

 (2). 自定义的attrs在layout中使用时,需要制定命名空间

    xmlns:android="http://schemas.android.com/apk/res/android"//系统内建attrs的命名空间
    xmlns:app="http://schemas.android.com/apk/res-auto"//自定义或support包中定义的attrs的命名空间
        <com.example.wendy.notification.MyView  //MyView为自定义的控件
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:showText="false"/>  //showText为自定义的属性


(3).自定义style属性值集   
    在res/values/styles.xml中定义style
    <resources>
    <!-- parent为父类,子类继承了父类所有的attrs,并可以通过item来override覆盖父类的attrs的值 -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        /*<!--每一个item代表一个attr, name为attrs(属性)的名称,item之间的为attrs的value值(取值类别有定义attrs的format决定) -->*/
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        ————————系统内建的attrs name前面必须加上命名空间android:  自定义的attrs则可以不用加前缀 ————————
        <item name="android:textColor">#FF0000</item>
    </style>
</resources>

style的继承关系除了用parent属性,同一命名空间的style还可以通过“.后缀”来指明(tip:只有拥有统一命名空间的style才可以用“.后缀”的方法指明继承关系,若自定义的style继承于系统内建的style则只能用parent属性来指明继承关系)

    <style name="CodeFont.Red">
        <item name="android:textColor">#FF0000</item>
    </style>
 <!-- 以下表明CodeFont.Red.Big的父类时CodeFont.Red, (既CodeFont.Red.Big拥有CodeFont.Red的所有属性,并且还有自己增加的属性)-->
    <style name="CodeFont.Red.Big">
        <item name="android:textSize">30sp</item>
    </style>


(4).style的使用(自定义的style可以直接用"@style/",系统内建的style引用格式为"@android:style/"
    a.作用于application和activity上:
       通过在manifest中的属性  android:theme="@style/XXX "来应用style,应用于application和 
       activity上的style又叫做theme,作用范围是activity(application)中的所有view控件,若控件不支持
       style中的部分属性,则view会应用支持的那部分属性,忽略不支持的那部分属性
    b.作用于单独的view上:
       在res/layout/文件中view的节点下
        <ImageButton
        style="@style/MyStyle"   //应用自定义的style
        //style="@android:style/Widget.Material.ImageButton" 应用系统内建的style的格式 @android:style/...
        android:layout_width="wrap_content"
        android:layout_height="50dp"/>




  • res/drawable/:定义包括多种drawable资源
    放置在res/drawable文件下的bitmap会被系统自动优化来减少占用内存,如果是通过取读原始的二进制图像的字节流来转化为bitmap,不希望被优化应该放在res/raw文件夹下
drawable 资源分类:
*Bitmap File: .jpg/.png/.gif 位图图片文件,代码中实例化:
                 drawable = getResources().getDrawable(R.drawable.picture);
                 Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.picture);
*Nine-Patch File:九点图(可以指定拉伸的位置拉伸时可以使图片不失真)以".9.png"结尾,在代码中实例化:和Bitmapfile一样

*Layer-List Drawable:xml文件(根据index排列分层的array-drawables,index最大的drawable排在最上面可见)
*State-List Drawable:xml文件(不同状态下显示不同的drawable图片)
*Level-List Drawable:xml文件(提供多个可选择的drawable图片,根据setLevel(int)来选择显示处于该level的图片)
*Transition Drawable:xml文件(提供两张图片,提供图片交替出现时的淡入淡出效果)
*Insert Drawable:xml文件(将该图片嵌入到另一张图片,如imageView中将src嵌入到background图片中)
*Clip Drawable:xml文件(裁切图片,通过setLever(int)[010000]来显示和隐藏裁切图片,默认为0不显示,10000为完全显示})
*Scale Drawable:xml文件(通过setLevel(int)来显示缩放图片)
*Shape Drawable :xml文件(几何形状,椭圆,直线,环形,长方形(默认))
*Animation Drawable:xml文件 (ValueAnimation中的FrameAnimation帧动画)通过切换序列图片而形成的动画
*Vector Drawable:xml文件(矢量静态图,可以在任何分辨率下很好的兼容(不受分辨率影响))v7兼容包兼容到API7
*AnimatedVector Drawable:xml文件(矢量动态图,可以在任何分辨率下很好的兼容(不受分辨率影响))v7兼容包兼容到API11

Nine-Patch File:这里写图片描述
.9图的作用范围:1,用于图标需要适配不同得分辨率时(图标会有拉伸); 2,图片有圆角需要拉伸时
制作方法:android Studio 自带的工具 Draw 9-patch tool 或自己下载软件,也可以用PS来制作
PS制作.9图的方法:

  • A、首先将画布四周放大一个像素。
  • B、然后在四周绘制黑色像素(即画出top,left,right,bottom线的区域)。
  • C、保存的时候改成.9图片的后缀名。

LayerDrawable:这里写图片描述

//属性值介绍
<?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>

demo:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/grass"/> //可以在属性节点中添加图片
     <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>

在代码中实例化
        Drawable drawable = getResources().getDrawable(R.drawable.layer);
        imageView.setImageDrawable(drawable);

State-List Drawable 这里写图片描述 这里写图片描述

//属性介绍:系统从上往下匹配的,如果匹配到一个item那么它就将采用这个item,而不是采用的最佳匹配的规则,所以设置缺省的状态,一定要写在最后,如果缺省写在前面,后面所有的item就都不会起作用了,还会因此找不着哪里出了问题。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
    android:constantSize=["true" | "false"]    //state-listDrawable的尺寸是否随着drawable变化,默认为false
    android:dither=["true" | "false"]       //是否使用颜色抖动(当颜色位数不同时,如#RGB,#RRGGBB),默认为true
    android:variablePadding=["true" | "false"] > //组件被selected的时候,比如某一个list的item被
                                                  selected,如果设置为true的话,那么被选的item的填
                                                  充就会变大(大小为最大的Padding值),使得看上去与
                                                  其它的item不一样。
    <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"] //被选择状态(多用于list的item和导航的item)
        android:state_checkable=["true" | "false"]//组件能否被check的状态(用于单选框和多选框)
        android:state_checked=["true" | "false"]//组件被选择的状态(用于单选框和多选框)
        android:state_enabled=["true" | "false"]//组件能否处理touch或click事件(既可点击于不可点击的图片不同)
        android:state_activated=["true" | "false"]//当前组件实否处于活跃状态
        android:state_window_focused=["true" | "false"] />//当前activity是否获得焦点
</selector>

demo
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <bitmap android:gravity="center"
                android:src="@mipmap/ic_launcher"/>
    </item>
    <item>
        <bitmap android:gravity="center"
                android:src="@mipmap/ic_launcher_round"/>
    </item>
</selector>

在代码中实例化
         Drawable drawable = getResources().getDrawable(R.drawable.state_list);
        imageButton.setImageDrawable(drawable);

Level-List Drawable这里写图片描述 这里写图片描述

//属性介绍: 当minLevel <=drawable.setLevel(int)中的int <=maxLevel时显示该item中的drawable
<?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>

demo
<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/sunflower"
          android:maxLevel="2"
          android:minLevel="1"/>
    <item android:minLevel="3"
          android:maxLevel="4"
          android:drawable="@drawable/grass"/>
</level-list>

在代码中实例化:
 drawable = getResources().getDrawable(R.drawable.level_list);
        imageButton.setImageDrawable(drawable);
        drawable.setLevel(4); //通过setLevel(int)来控制该显示哪张图片(电池充电小姑就是设置的这个属性)
        imageButton.setImageDrawable(drawable);

Transition Drawable

//属性介绍:只能有两个item,且两个item交换显示时的动画为fade
<?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>

demo
        drawable = getResources().getDrawable(R.drawable.transition);
        imageButton.setImageDrawable(drawable);
        ((TransitionDrawable)drawable).startTransition(500);//通过transitionDrawable.startTransition(duration)来启动图片过渡切换

Insert Drawable 这里写图片描述

//属性介绍:
<?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" />

demo
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
       android:drawable="@drawable/sunflower"
       android:insetBottom="50dp"
       android:insetLeft="50dp"
       android:insetRight="50dp"
       android:insetTop="50dp">
</inset>
在代码中实例化:           
          //  将imageView的src图片插入到Background图片中
        drawable = getResources().getDrawable(R.drawable.insert);
        imageView.setBackgroundResource(R.drawable.beauty);
        imageView.setImageDrawable(drawable);

Clip Drawable 这里写图片描述

//属性介绍:通过clipDrawable.setLevel(int)来控制裁切的多少,默认为0全部裁切调不显示了,10000为没有裁切全部显示
<?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"] />

demo
<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/sunflower" 
    android:clipOrientation="horizontal"  //横向切
    android:gravity="left">              //保留切片左边的部分
</clip>

在代码中实例化
        drawable = getResources().getDrawable(R.drawable.clip);
        imageView.setImageDrawable(drawable);
        ClipDrawable clipDrawable = (ClipDrawable) drawable;
        clipDrawable.setLevel(clipDrawable.getLevel() + 6000);

Scale Drawable 这里写图片描述

//属性介绍:与setLevel(int)配合比例缩放
<?xml version="1.0" encoding="utf-8"?>
<scale
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/drawable_resource"
    android:scaleGravity=["top" | "bottom" | "left" | "right" | "center_vertical" | //缩放后的图片中心
                          "fill_vertical" | "center_horizontal" | "fill_horizontal" |
                          "center" | "fill" | "clip_vertical" | "clip_horizontal"]
    android:scaleHeight="percentage"  //图片边界缩放的大小
    android:scaleWidth="percentage" />

demo
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/sunflower"
    android:scaleGravity="left|bottom"
    android:scaleHeight="30%"
    android:scaleWidth="30%">
</scale>

在代码中实例化
        imageView.setImageDrawable(scaleDrawable);
        scaleDrawable.setLevel(2);//同过setLevel(int)来联合控制图片的显示比例

Shape Drawable这里写图片描述

//属性介绍:
<?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="float"      //内半径与环形宽度的比率
    android:thickness="dimension"         //环形的厚度
    android:thicknessRatio="float"      //环形厚度与环形宽度的比率
    android:useLevel=["true" | "false"]>//环形是否作为level-listDrawable,默认为true(形状不显示)
    <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"] />//是否用作level-listDrawable,通常为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>

demo
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="oval">
    <gradient
        android:endColor="@color/colorAccent"
        android:gradientRadius="30dp"
        android:startColor="#ffffff"
        android:type="radial"/>
</shape>

在代码中实例化
        Drawable drawable = getResources().getDrawable(R.drawable.shape6);
        imageView5.setImageDrawable(drawable);

这里写图片描述
画线时,有几点特性必须要知道的:

  • 只能画水平线,画不了竖线;
  • 线的高度是通过stroke的android:width属性设置的;
  • size的android:height属性定义的是整个形状区域的高度;
  • size的height必须大于stroke的width,否则,线无法显示;
  • 线在整个形状区域中是居中显示的;
  • 线左右两边会留有空白间距,线越粗,空白越大;
  • 引用虚线的view需要添加属性android:layerType,值设为”software”,否则显示不了虚线。
    这里写图片描述
    画环形,注意:在 root节点上设置android:useLevel=”false”,否则图形不可见

Animation-List:帧动画,开始后自动一帧一帧切换

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false"  //动画是否只播放一次
    android:variablePadding="false" //是否同意边距
    android:visible="true"> //是否可见
    <item android:drawable="@drawable/icon1" android:duration="200"/>
    <item android:drawable="@drawable/icon2" android:duration="200"/>
    <item android:drawable="@drawable/icon3" android:duration="200"/>
</animation-list>

在xml中引用
    <ImageButton
        android:id="@+id/ib_animation"
        android:src="@drawable/animation_list"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
 在代码中初始化并开启动画
      ImageButton imageButton = (ImageButton) findViewById(R.id.ib_animation);
      AnimationDrawable animationDrawable = (AnimationDrawable) imageButton.getDrawable();
     animationDrawable.start();//开启动画
     animationDrawable.stop();//停止动画

Vector Drawable:android5.0加入的,通过V7:23.2兼容包可以完美向下兼容
这里写图片描述这里写图片描述

//属性介绍
<?xml version="1.0" encoding="utf-8"?>
<vector android:name="VectorDrawableName"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="200dp"          //VectorDrawable的宽度
        android:height="200dp"         //VectorDrawable的高度
        android:viewportHeight="500"   //将VectorDrawable的高度值分为的等份(例如例子中的500,即把
                                          200dp大小的图像划分成500份,后面Path标签中的坐标,就全部使
                                          用的是这里划分后的坐标系统。)
        android:viewportWidth="500"    //宽度划分的等份同上
        android:alpha="0.5"            //VectorDrawable的透明度,1为完全不透明,0为完全透明
        android:autoMirrored="false" //是否需要镜像,当布局是从右向左时才会用到,默认为false
        android:tint="#00ffff"         //着色颜色
        android:tintMode="add">//混合模式:add\multiply\screen\src_over\src_in、src_atop 默认为src_in.
    <group  //定义变化信息(如缩放,旋转,位移,按照)
        android:name=""    //用来在使用动画时指定动画要驱动的对象 
        android:pivotX=""  //旋转缩放的中心,默认为0
        android:pivotY=""  //旋转缩放的中心,默认为0
        android:scaleX="" //X轴向上的缩放,默认为1,大于1为放大,小于1为缩小
        android:scaleY="" //Y轴向上的缩放 ,默认为1,大于1为放大,小于1为缩小
        android:rotation="20f"旋转的角度,默认为0f
        android:translateX="200dp" //向X轴上的位移,默认为0
        android:translateY="100dp"> //在Y轴方向上的位移,默认为0
        <path //图像的外轮廓
            android:name="name"//用来在使用动画时指定动画要驱动的对象 
            android:fillAlpha=""//填充的透明度
            android:fillColor=""//填充颜色
            android:fillType="" //填充类型
            android:pathData=""//路径信息
            android:strokeAlpha=""//描边的透明度
            android:strokeColor=""//描边颜色
            android:strokeLineCap=""//描边笔触形状
            android:strokeLineJoin=""//描边拐角处的形状
            android:strokeMiterLimit=""//设置转角个数限制,默认为4
            android:strokeWidth=""//秒变宽度
            android:trimPathStart=""//修建路径的起始比例位置(绘制图像的起始点比例)默认为0,最大为1
            android:trimPathEnd=""//修剪路径结束比例(绘制图像的结束点比例),默认为1,【0~1之间】
            android:trimPathOffset=""/>
        <clip-path //定义当前修剪的路径,只能是group的子节点,不能单独使用
            android:name=""
            android:pathData=""
    </group>
</vector>

demo:
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="200dp"
        android:height="200dp"
        android:viewportHeight="500"
        android:viewportWidth="500">
    <path
        android:name="square"
        android:fillColor="#000000"
        android:pathData="M100,100 L400,100 L400,400 L100,400 z"/>//与SVG的path语法相同
</vector>
应用VectorDrawable
在xml中
  <ImageView
      app:srcCompat="@drawable/vector"//必须要通过兼容包的srcCompat才能让vector图像向下兼容
      android:layout_width="match_parent"
      android:layout_height="match_parent"/>


Path指令解析如下所示:
支持的指令:
M = moveto(M X,Y) :将画笔移动到指定的坐标位置
L = lineto(L X,Y) :画直线到指定的坐标位置
H = horizontal lineto(H X):画水平线到指定的X坐标位置
V = vertical lineto(V Y):画垂直线到指定的Y坐标位置
C = curveto(C X1,Y1,X2,Y2,ENDX,ENDY):三次贝赛曲线
S = smooth curveto(S X2,Y2,ENDX,ENDY)
Q = quadratic Belzier curve(Q X,Y,ENDX,ENDY):二次贝赛曲线
T = smooth quadratic Belzier curveto(T ENDX,ENDY):映射
A = elliptical Arc(A RX,RY,XROTATION,FLAG1,FLAG2,X,Y):弧线
Z = closepath():关闭路径

使用原则:
坐标轴为以(0,0)为中心,X轴水平向右,Y轴水平向下
所有指令大小写均可。大写绝对定位,参照全局坐标系;小写相对定位,参照父容器坐标系
指令和数据间的空格可以省略
同一指令出现多次可以只用一个

利用Android Studio的Vector Asset,可以非常方便的创建Vector图像,甚至可以直接通过本地的SVG图像来生成Vector图像
这里写图片描述这里写图片描述这里写图片描述

AnimatedVector Drawable这里写图片描述
矢量动画包含四部分内容:

  • Vector:图像资源
  • ObjectAnimator:动画资源
  • Animated-vector:动画、图像粘合剂
  • 代码:启动动画

上面矢量动图中有三个路径分别是这里写图片描述

1.定义矢量动画的vector图像,在res/drawable/文件下新建文件
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="120dp"
        android:height="120dp"
        android:viewportHeight="24"
        android:viewportWidth="24">
    <path     //斜线部分的路径
        android:name="line"
        android:pathData="M5.705,5.705 L18.295,18.295"
        android:strokeColor="#000000"
        android:strokeWidth="2"
        android:trimPathEnd="1"
        android:trimPathStart="0.45"/>
    <path   //上半圆加左下直线的路径
        android:name="circle1"
        android:pathData="M5.705,5.705 A 4 4 0 1 1 12,12 L5.705,18.295"
        android:strokeColor="#000000"
        android:strokeWidth="2"
        android:trimPathEnd="0.6"
        android:trimPathStart="0"/>
    <path //下半圆加右上直线路径
        android:name="circle2"
        android:pathData="M18.295,5.705 L12,12 A 4 4 0 1 1 5.705,5.705"
        android:strokeColor="#000000"
        android:strokeWidth="2"
        android:trimPathEnd="1"
        android:trimPathStart="0.4"/>
</vector>
2.定义属性动画资源,在res/animator/目录下新建多个文件

<!--为circle1定义的属性动画-->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="2000"
        android:propertyName="trimPathStart"
        android:valueType="floatType"
        android:valueFrom="0"
        android:valueTo="0.6"/>
    <objectAnimator
        android:duration="2000"
        android:propertyName="trimPathEnd"
        android:valueFrom="0.6"
        android:valueTo="1"
        android:valueType="floatType"/>
</set>

<!--为circle2定义的属性动画-->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="2000"
        android:propertyName="trimPathStart"
        android:valueType="floatType"
        android:valueFrom="0.4"
        android:valueTo="0"/>
    <objectAnimator
        android:duration="2000"
        android:propertyName="trimPathEnd"
        android:valueFrom="1"
        android:valueTo="0.4"
        android:valueType="floatType"/>
</set>

<!--为line定义的属性动画-->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:startOffset="2000"
        android:duration="1000"
        android:propertyName="trimPathStart"
        android:valueType="floatType"
        android:valueFrom="0.45"
        android:valueTo="0"/>

</set>
3.将动画与vector图像结合
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
                 android:drawable="@drawable/vector_drawable_on">
    <target
        android:name="circle1"//namevectorDrawable中的grouppath中的name一致
        android:animation="@animator/animator_circle1"/>
    <target
        android:name="circle2"
        android:animation="@animator/animator_circle2"/>
    <target
        android:name="line"
        android:animation="@animator/animator_line"/>
</animated-vector>
将动画赋值给view,并在代码中启动动画
在xml中通过app:srcCompat属性
<android.support.v7.widget.AppCompatImageView
    android:id="@+id/imv"
    android:layout_width="368dp"
    android:scaleType="centerInside"
    android:layout_height="495dp"/>

或者imageView.setImageResource(R.drawable.animator_vector);

启动矢量动画
 drawable = (AnimatedVectorDrawable) imageView.getDrawable();
 drawable.start();

矢量动画的兼容性问题:
1.需要引入兼容包

    compile 'com.android.support:appcompat-v7:25.1.1'

2.需要在 build.gradle 文件中新增如下配置:

//For Gradle Plugin 2.0+
 android {
   defaultConfig {
     vectorDrawables.useSupportLibrary = true
    }
 }
//For Gradle Plugin 1.5 or below
android {
  defaultConfig {
    // Stops the Gradle plugin’s automatic rasterization of vectors
    generatedDensities = []
  }
  // Flag notifies aapt to keep the attribute IDs around
  aaptOptions {
    additionalParameters "--no-version-vectors"
  }
}

还有一种方式是用单一的xml文件来描述整个矢量动画资源,需要Build Tools 版本在24及以上:

< ?xml version="1.0" encoding="utf-8"?>
<animated-vector
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:aapt="http://schemas.android.com/aapt">
    <aapt:attr name="android:drawable">   //创建单独的资源文件并在同一个文件中引用他们
        <vector xmlns:android="http://schemas.android.com/apk/res/android"
            android:width="64dp"
            android:height="64dp"
            android:viewportWidth="600"
            android:viewportHeight="600">
            <group
                android:name="rotationGroup"
                android:pivotX="300"
                android:pivotY="300"
                android:roation="45.0" >
                <path
                    android:name="vectorPath"
                    android:fillColor="#000000"
                    android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
            </group>
        </vector>
    </aapt:attr>
    <target android:name="rotationGroup">
        <aapt:attr name="android:animation">
            <objectAnimator
                android:propertyName="rotation"
                android:valueFrom="0"
                android:valueTo="360"
                android:duration="6000"
                android:interpolator="@android:interpolator/fast_out_slow_in" />
        </aapt:attr>
    </target>
</animated-vector>

因为AnimatedVectorDrawable改变的是vector中各元素的属性值,所以极大的增添了动画的实现手段及效果。

向下兼容,当API < 21时,扩展包中的AnimatedVectorDrawableCompat会有一些限制:

  • Path Morphing,即路径变换动画,在Android pre-L版本下是无法使用的。
  • Path Interpolation,即路径插值器,在Android pre-L版本只能使用系统的插值器,不能自定义。
  • Path Animation,即路径动画,这个一般使用贝塞尔曲线来代替,所以没有太大影响。

    向上兼容问题

除了在低版本上的兼容性问题,在L版本以上,也存在兼容性问题,即继承了AppCompatActivity的界面,如果直接设置ImageView的srcCompat,那么Path Morphing动画是无法生效的,因为默认的AppCompatActivity已经默认使用ImageViewCompat给转换了,但是AnimatedVectorDrawableCompat是不支持Path Morphing动画的,所以,在AppCompatActivity界面里面就无效了。

解决办法很简单,即使用代码来给ImageView添加动画:

ImageView imageView = (ImageView) view;
AnimatedVectorDrawable morphing = (AnimatedVectorDrawable) getDrawable(morphing);
imageView.setImageDrawable(morphing);
if (morphing != null) {
    morphing.start();
}

注意不要使用AnimatedVectorDrawableCompat即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值