Android应用源码(物理)
应用资源概述
Android应用资源类型和存储方式
- 无法通过R资源清单类访问的原生资源,保存在assets目录下
- 可通过R资源清单类访问的资源,保存在res目录下
- res目录下资源存储资源说明
- /res/animator/:存放定义属性动画的XML文件
- /res/anim/:存放定义补间动画的XML文件
- /res/color/:存放定义不同状态下颜色列表的XML文件
- /res/drawable/:存放各种位图文件,编译成各种Drawable对象的XML文件(BitmapDrawable、NinePatchDrawable、StateListDrawable、ShapeDrawable、AnimationDrawable、Drawable的其它各种子类对象)
- /res/layout/:存放用户界面布局文件
- /res/menu/:存放为应用程序定义的各种菜单资源(选项菜单、子菜单、上下文菜单)
- /res/raw/:存放任意类型原生资源(音频、视频等),使用时通过调用Resource对象的openRawResource(int id)方法获取该资源的二进制输入流进而进行使用。
- /res/values/:存放各种简单的XML文件(字符串值、整数值、颜色值、数组、尺寸、样式等),一般根据不同文件来存储不同类型的值。
- /res/xml/:存放原生XML文件,通过Resource对象的getXML()方法进行访问。
资源使用
- Java代码中使用资源清单项:[package_name.]R.resource_type.resource_name
// 获取图片资源
getWindow().setBackgroundDrawableResource(R.drawable.back);
// 获取字符串资源
getWindow().setTitle(getResources().getText(R.string.main_title))
- Java代码中访问实际资源(通过Resources类对象调用下述方法)
- getXXX(int id):根据资源清单ID来获取实际资源
- getAssets():获取访问/assets/目录下资源的AssetManager对象
// 获取Resource对象
Resource res = Activity.this.getResources();
// 获取字符串资源
String titile = res.getText(R.string.main_title);
// 获取图片资源
Drawable logo = res.getDrawable(R.drawable.logo);
// 获取数组资源
int[] arr = res.getIntArray(R.array.books);
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="pickerview_day">hello</string>
<color name="pickerview_topbar_title">#000000</color>
</resources>
<Button
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.1"
android:cursorVisible="false"
android:editable="false"
android:gravity="center"
android:background="@drawable/bg"
android:onClick="schemeHostPort"
android:textColor="@color/back"
android:text="@string/hello" />
字符串、颜色、尺寸资源
颜色值定义
- Android颜色值常见的4种形式
- #RGB:分别指定红、绿、蓝三原色的值(只支持0~f 16级颜色)来代表颜色
- #ARGB:分别指定红、绿、蓝三原色的值(只支持0~f 16级颜色)及透明度(只支持0~f 16级颜色)来代表颜色
- #RRGGBB:分别指定红、绿、蓝三原色的值(只支持00~ff 256级颜色)来代表颜色
- #AARRGGBB:分别指定红、绿、蓝三原色的值(只支持00~ff 256级颜色)及透明度(只支持00~ff 256级颜色)来代表颜色
定义字符串、颜色、尺寸资源
- 字符串定义(/res/values/strings.xml)
<string name="phone_number">手机号</string>
- 颜色定义(/res/values/colors.xml)
<color name="colorPrimary">#Fda222</color>
- 尺寸定义(/res/values/dimens.xml)
<dimen name="activity_vertical_margin">16dp</dimen>
使用字符串、颜色、尺寸资源
- 字符串、颜色、尺寸等资源使用前面已经说明,此处不做赘述。
数组资源
数组资源定义
<array name="pics">
<item>@drawable/ic_search_24dp</item>
<item>@drawable/ic_search_24dp</item>
<item>@drawable/ic_search_24dp</item>
</array>
<string-array name="names">
<item>张三</item>
<item>李四</item>
<item>王五</item>
</string-array>
<integer-array name="ages">
<item>21</item>
<item>35</item>
<item>11</item>
</integer-array>
数组资源使用
- 使用方法同字符串、颜色、尺寸等资源的使用类似,此处不做赘述。
Drawable资源
图片资源(XXX.png、XXX.jpg、XXX.gif)
- 使用方法同字符串、颜色、尺寸等资源的使用类似,此处不做赘述。
StateListDrawable资源
- StateListDrawable用于组织多个Drawable对象,当使用StateListDrawable作为目标组件的背景、前景图片时,StateListDrawable对象所显示的Drawable对象会随目标组件状态的改变而自动切换。
- StateListDarwable对象的XML文件根元素为 select 元素。该元素可以包含多个 item 子元素。该元素一般具有如下两种属性:
- android:color 或者 android:drawable :指定颜色或者Drawable对象
- android:state_xxx :指定一个特定状态
- StateListDrawable的 item 子元素所支持的状态有如下几种:
- android:state_active:代表是否处于激活状态
- android:state_checkable:代表是否处于可勾选状态
- android:state_checked:代表是否处于已经选状态
- android:state_enabled:代表是否处于可用状态
- android:state_first:代表是否处于开始状态
- android:state_focused:代表是否处于已得到焦点状态
- android:state_last:代表是否处于结束状态
- android:state_middle:代表是否处于中间状态
- android:state_pressed:代表是否处于已被按下状态
- android:state_selected:代表是否处于已被选中状态
- android:state_window_focused:代表窗口是否处于已得到焦点状态
- 示例:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- StateListDrawable 资源 -->
<!-- 指定特定状态下的颜色 -->
<item android:state_focused="true" android:color="#ffaaff"/>
<item android:state_focused="false" android:color="#00ffaa"/>
</selector>
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- StateListDrawable 资源 -->
<!-- 指定特定状态下的背景图片 -->
<item android:state_focused="true" android:drawable="@drawable/meinv04"/>
<item android:state_focused="false" android:drawable="@drawable/shilipic"/>
</selector>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:textColor="@drawable/state_list_drawable_color"
android:background="@drawable/state_list_drawable"
android:hint="请点击获取焦点"
android:layout_width="match_parent"
android:layout_height="45dp" />
<EditText
android:textColor="@drawable/state_list_drawable_color"
android:background="@drawable/state_list_drawable"
android:hint="请点击获取焦点"
android:layout_width="match_parent"
android:layout_height="45dp" />
</LinearLayout>
LayerDrawable资源
- LayerDrawable与StateListDarwable类似,也是包含一个Drawable数组,因此系统会按这些Drawable对象的数组顺序来绘制它们,索引最大的Drawable对象将会被绘制在最上面。
- LayerDarwable对象的XML文件的根元素为 layer-list ,该元素可以包含多个 item 元素,一般可以指定如下属性:
- android:drawable:指定作为LayerDrawable元素之一的Drawable对象。
- android:id:为该Drawable对象指定一个标识。
- android:buttom|top|left|button:它们用于指定一个长度值,用于指定该Drawable对象绘制到目标组件的指定位置。
- 示例:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 定义轨道背景 -->
<item android:id="@android:id/background" android:drawable="@drawable/shilipic"/>
<!-- 定义轨道上面已完成部分的外观 -->
<item android:id="@android:id/progress" android:drawable="@drawable/nvshengtouxiang"/>
</layer-list>
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:src="@drawable/nvshengtouxiang" android:gravity="center"/>
</item>
<item android:top="100dp" android:left="100dp">
<bitmap android:src="@drawable/nvshengtouxiang"
android:gravity="center" />
</item>
<item android:top="200dp" android:left="200dp">
<bitmap android:src="@drawable/nvshengtouxiang" android:gravity="center"/>
</item>
</layer-list>
ShapeDrawable资源
- ShapeDrawable用于定义一个基本的几何图形(如矩形、圆等),定义ShapeDrawable的根元素是 shape ,shape可指定如下属性:
- android:shape = [“rectangle”|“oval”|“line”|“ring”]
- 定义ShapeDrawable对象的完整语法:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- 定义几何图形的四个角弧度 -->
<corners
android:radius="Integer"
android:topLeftRadius="Integer"
android:topRightRadius="Integer"
android:bottomLeftRadius="Integer"
android:bottomRightRadius="Integer"/>
<!-- 定义使用渐变色填充 -->
<gradient
android:angle="Integer"
android:centerX="Integer"
android:centerY="Integer"
android:centerColor="Integer"
android:endColor="color"
android:gradientRadius="Integer"
android:startColor="color"
android:type="linear"
android:useLevel="true"/>
<!-- 定义几何图像内边距 -->
<padding
android:left="Integer"
android:right="Integer"
android:top="Integer"
android:bottom="Integer"
/>
<!-- 定义几何形状的大小 -->
<size
android:width="Integer"
android:color="color"
android:dashWidth="Integer"
android:dashGap="Integer"
/>
<!-- 定义使用单色填充 -->
<solid
android:color="color"/>
<!-- 定义为几何形状绘制边框 -->
<stroke
android:width="Integer"
android:color="color"
android:dashWidth="Integer"
android:dashGap="Integer"
/>
</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- 填充单色 -->
<solid android:color="@color/colorAccent"/>
<padding
android:left="@dimen/dp_5"
android:top="@dimen/dp_5"
android:right="@dimen/dp_5"
android:bottom="@dimen/dp_5"
/>
<!-- 边距 -->
<stroke
android:width="@dimen/dp_10"
android:color="@color/bg_page"/>
</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- 填充渐变色 -->
<gradient
android:startColor="@color/colorAccent"
android:endColor="@color/c"
android:angle="45"
/>
<padding
android:left="@dimen/dp_5"
android:top="@dimen/dp_5"
android:right="@dimen/dp_5"
android:bottom="@dimen/dp_5"
/>
<!-- 设置圆角 -->
<corners
android:radius="@dimen/dp_25"/>
</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<!-- 填充渐变色 -->
<gradient
android:startColor="@color/colorAccent"
android:endColor="@color/c"
android:angle="45"
android:type="sweep"
/>
<padding
android:left="@dimen/dp_5"
android:top="@dimen/dp_5"
android:right="@dimen/dp_5"
android:bottom="@dimen/dp_5"
/>
<stroke
android:width="@dimen/dp_5"
android:color="@color/bg_page"/>
</shape>
<style name="list_item_top">
<item name="android:clickable">true</item>
<item name="android:focusable">true</item>
<item name="android:paddingTop">10dip</item>
<item name="android:paddingBottom">10dip</item>
<item name="android:paddingLeft">10dip</item>
<item name="android:paddingRight">10dip</item>
<item name="android:gravity">center_vertical</item>
<item name="android:background">@drawable/background_view_rounded_top</item>
</style>
<?xml version="1.0" encoding="UTF-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="1.0px"
android:insetRight="1.0px" >
<selector>
<item android:state_pressed="true">
<shape>
<gradient
android:angle="270.0"
android:endColor="@color/base_end_color_pressed"
android:startColor="@color/base_start_color_pressed" />
<corners
android:bottomLeftRadius="0.0dip"
android:bottomRightRadius="0.0dip"
android:radius="2.0dip"
android:topLeftRadius="10.0dip"
android:topRightRadius="10.0dip" />
<stroke
android:width="1dp"
android:color="#eededede" />
</shape>
</item>
<item>
<shape>
<gradient
android:angle="270.0"
android:endColor="@color/base_end_color_default"
android:startColor="@color/base_start_color_default" />
<corners
android:bottomLeftRadius="0.0dip"
android:bottomRightRadius="0.0dip"
android:radius="2.0dip"
android:topLeftRadius="11.0dip"
android:topRightRadius="11.0dip" />
<stroke
android:width="1dp"
android:color="#eededede" />
</shape>
</item>
</selector>
</inset>
ClipDrawable资源
- ClipDrawable代表从其它位图上截取一个“图片片段”,在XML文件中定义ClipDrawable对象使用 clip 元素。一般可以指定如下属性:
- android:drawable:指定截取的源Drawable对象
- android:clipOrientation:指定截取方向,可设置水平截取或者竖直截取
- android:gravity:指定截取时的对齐方式
- clip元素的完整语法:
<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/drawer_shadow"
android:clipOrientation="vertical"
android:gravity="center"
>
</clip>
AnimationDrawable资源
- AnimationDrawable代表一个动画,Android即支持传统的逐帧动画,也支持通过平移、变换计算出来的补间动画。定义补间动画的XML资源文件以 set 元素作为根元素,该元素有如下四个子元素:
- alpha:设置透明度的改变
- scale:设置图片进行缩放变换
- translate:设置图片进行位移变换
- rotate:设置图片进行旋转
- 定义补间动画的XML资源一般放置在/res/anmi/路径下。定义思路比较简单:设置一张图片的开始状态(透明度、位置、缩放比、旋转角度等),结束状态(类似开始状态的设置),动画的持续时间。Android系统会使用动画效果把这张图片从开始状态变换的结束状态。
- 补间动画语法:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="true"
android:duration="30"
android:interpolator="@android:anim/linear_interpolator"
>
<!-- android:duration="30" 持续时间设置 -->
<!-- android:interpolator="@android:anim/linear_interpolator" 匀速变换 -->
<!-- android:interpolator="@android:anim/accelerate_interpolator" 加速变换 -->
<!-- android:interpolator="@android:anim/decelerate_interpolator" 减速变换 -->
<!-- 透明度变换 -->
<alpha
android:fromAlpha="2.0"
android:toAlpha="3.0"
/>
<!-- 缩放变换 -->
<scale
android:fromXScale="25"
android:toXScale="36"
android:fromYScale="25"
android:toYScale="36"
android:pivotX="25"
android:pivotY="36"
/>
<!-- android:pivotX="25" android:pivotY="36" 指定变换中心点 -->
<!-- 平移变换 -->
<translate
android:fromXDelta="25"
android:toXDelta="36"
android:fromYDelta="25"
android:toYDelta="36"
/>
<!-- 旋转变换 -->
<rotate
android:fromDegrees="25"
android:toDegrees="36"
android:pivotX="25"
android:pivotY="36"
/>
</set>
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator"
android:duration="5000">
<!-- 定义缩放变换 -->
<scale
android:fromXScale="1.0"
android:toXScale="1.4"
android:fromYScale="1.0"
android:toYScale="0.6"
android:pivotY="50%"
android:pivotX="50%"
android:fillAfter="true"
android:duration="2000"/>
<!-- 定义位移变换 -->
<translate
android:fromXDelta="10"
android:toXDelta="130"
android:fromYDelta="30"
android:toYDelta="-80"
android:duration="2000"/>
</set>
private void initViewAnim() {
// 加载动画资源
animation = AnimationUtils.loadAnimation(this, R.anim.animation_drawable_example);
// 设置动画结束后保留结束状态
animation.setFillAfter(true);
}
case R.id.btn_anim:
// 开始动画
ivAnim.startAnimation(animation);
break;
属性动画资源
- Animator代表一个属性动画,但它只是一个抽象类,通常会使用它的子类:AnimatorSet、ValueAnimator、ObjectAnimator、TimeAnimator等。
- 属性动画的XML文件以下述三个元素中的任意一个作为根元素:
- set:它是一个父元素,用于包含 objectAnimator、animator、set 子元素,该元素定义的资源代表AnimatorSet对象。
- objectAnimator:用于定义ObjectAnimator动画。
- animator:用于定义ValueAnimator动画。
- 定义属性动画语法:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together">
<!-- 定义ObjectAnimator动画 -->
<objectAnimator
android:propertyName="string"
android:duration="int"
android:valueFrom="float|int|color"
android:valueTo="float|int|color"
android:startOffset="int"
android:repeatCount="int"
android:interpolator=""
android:repeatMode=["repeat"|"reverse"]
android:valueType=["intType"|"floatType"]/>
<!-- 定义ValueAnimator动画 -->
<animator
android:duration="int"
android:valueFrom="float|int|color"
android:valueTo="float|int|color"
android:startOffset="int"
android:repeatCount="int"
android:interpolator=""
android:repeatMode=["repeat"|"reverse"]
android:valueType=["intType"|"floatType"]/>
<set>
</set>
</set>
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:propertyName="backgroundColor"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:valueFrom="#ff8080"
android:valueTo="#8080ff"
android:valueType="intType" ><!-- 定义ObjectAnimator动画 -->
</objectAnimator>
private class MyAnimationView extends View {
public MyAnimationView(Context context){
super(context);
// 加载动画资源
ObjectAnimator objectAnimator = (ObjectAnimator) AnimatorInflater.loadAnimator(
ResourceActivity.this,R.animator.property_animation_example);
objectAnimator.setEvaluator(new ArgbEvaluator());
// 对该View本身应用属性动画
objectAnimator.setTarget(this);
// 开始指定动画
objectAnimator.start();
}
}
private void initViewPropertyAnim() {
llAnim.addView(new MyAnimationView(this));
}
XML资源
定义原始XML资源
- 原始的XML资源一般保存在/res/xml/文件夹下,在Java程序中获取实际的XML文件,使用Resources的如下方法来获取:
- XmlResourceParser getXml(int id):获取XML文档,并使用一个XmlPullParser来解析XML文档,该方法返回的是一个解析器对象(XmlResourceParser 是XmlPullParser的子类对象)。
- InputStream openRawResource(int id):获取XML文档对应的输入流。
- 获取XML文档一般直接调用getXml(int id)方法获取,并对XML文档进行解析。Android默认使用内置的Pull解析器来解析XML文档。处理使用Pull解析器外,还可以使用DOM或者SAX对XML文档进行解析。
使用原始XML资源
<?xml version="1.0" encoding="utf-8"?>
<books>
<book price="24" 出版日期="2008">java</book>
<book price="25" 出版日期="2009">android</book>
<book price="23" 出版日期="2010">javaee</book>
</books>
// 根据 XML 资源的ID获取解析该资源的解析器
// XmlResoureParser是XmlPullParser的子类
XmlResourceParser xrp = getResources().getXml(R.xml.books);
StringBuilder sb = new StringBuilder("");
// 还没有到xml文档的结尾处
try {
while (xrp.getEventType() != XmlResourceParser.END_DOCUMENT) {
// 如果遇到开始标签
if (xrp.getEventType() == XmlResourceParser.START_TAG) {
// 获取该标签的标签名
String tagName = xrp.getName();
// 如果遇到book标签
if (tagName.equals("book")) {
// 根据属性名来获取属性值
String bookName = xrp.getAttributeValue(null, "price");
sb.append("价格:");
sb.append(bookName);
// 根据属性索引来获取属性值
String bookPrice = xrp.getAttributeValue(1);
sb.append(" 出版日期:");
sb.append(bookPrice);
sb.append(" 书名:");
// 获取文本节点的值
sb.append(xrp.nextText());
}
sb.append("\n");
}
// 获取解析器的下一个事件
xrp.next();
}
etXml.setText(sb.toString());
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
布局资源
- Layout资源文件保存在/res/layout/文件夹下,在Java代码中和XML中的使用同其它资源类似。
菜单资源
- 菜单资源一般保存在/res/menu/文件夹下,以 menu 为根元素,子元素有如下两种:
- item:定义菜单项
- group:将多个item元素包装成一个菜单组。
- item元素可以指定如下属性:
- android:id:为菜单指定一个唯一标识
- title:指定菜单项的标题
- icon:指定菜单的图标
- alphabeticShortcut:为菜单项指定字符串快捷键
- numericShortcut:为菜单项指定数字快捷键
- checkable:设置该菜单项是否可选
- checked:设置该菜单项是否已经被选中
- visible:设置该菜单项是否可见
- enable:设置该菜单项是否可用
- group元素可以指定如下属性:
- checkableBehavier:指定该组菜单的选择行为,可指定为none(不选)、all(多选)、single(单选)三个值。
- menuCategory:对菜单进行分类,指定菜单的优先级,有效值为container、system、secondary、alternative。
- visible:指定改组菜单是否可见。
- enable:指定改组菜单是否可用。
- 在程序中定义了菜单项资源后,接下来是重写onCreateOptionsMenu(用于创建选项菜单)、onCreateContextMenu(用以创建上下文菜单)方法,在这些方法中调用MenuInflater对象的inflate方法加载指定资源对应的菜单即可。
- 示例:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group
android:checkableBehavior="single">
<!-- 定义三个菜单项 -->
<item
android:id="@+id/red"
android:title="red"
android:alphabeticShortcut="r"/>
<item
android:id="@+id/green"
android:title="green"
android:alphabeticShortcut="g"/>
<item
android:id="@+id/blue"
android:title="blue"
android:alphabeticShortcut="b"/>
</group>
</menu>
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:title="@string/app_name"
android:icon="@drawable/meinv04">
<menu>
<!-- 定义一组单选菜单项 -->
<group android:checkableBehavior="single">
<!-- 定义多个菜单项 -->
<item
android:id="@+id/menu_01"
android:title="按钮01"/>
<item
android:id="@+id/menu_02"
android:title="按钮02"/>
<item
android:id="@+id/menu_03"
android:title="按钮03"/>
</group>
</menu>
</item>
<item
android:id="@+id/plain_item"
android:title="plain_item" />
<item
android:id="@+id/app_bar_search"
android:actionViewClass="android.widget.SearchView"
android:icon="@drawable/ic_search_black_24dp"
android:title="Search" />
<item
android:id="@+id/app_bar_switch"
android:title=""
app:actionLayout="@layout/switch_item" />
<menu />
</menu>
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// 装填R.menu.menu_main的菜单,并添加到menu中
MenuInflater inflater = new MenuInflater(this);
inflater.inflate(R.menu.menu_main,menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
// 装填R.menu.context对应的菜单,并添加到menu中
MenuInflater inflater = new MenuInflater(this);
inflater.inflate(R.menu.context,menu);
menu.setHeaderIcon(R.drawable.nvshengtouxiang);
menu.setHeaderTitle("请选择背景颜色");
}
/**
* 上下文菜单中菜单项被点击是触发该方法
* @param item
* @return
*/
@Override
public boolean onContextItemSelected(MenuItem item) {
// 勾选该菜单项
item.setChecked(true);
switch (item.getItemId()){
case R.id.red:
item.setChecked(true);
tvMenu.setBackgroundColor(Color.RED);
break;
case R.id.green:
item.setChecked(true);
tvMenu.setBackgroundColor(Color.GREEN);
break;
case R.id.blue:
item.setChecked(true);
tvMenu.setBackgroundColor(Color.BLUE);
break;
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.isCheckable()){
// 勾选该菜单项
item.setChecked(true);
}
// 判断单击的是那个菜单项,并有针对性的作出响应
switch (item.getItemId()){
case R.id.menu_01:
tvMenu.setText("menu_01");
break;
case R.id.menu_02:
tvMenu.setText("menu_02");
break;
case R.id.menu_03:
tvMenu.setText("menu_03");
break;
case R.id.plain_item:
tvMenu.setText("plain_item");
break;
}
return true;
}
样式资源
- Style资源保存在/res/style/文件夹下,其根元素为 resource 元素,该元素可包含多个 style 子元素,每个 style 元素定义一个样式。style 一般可指定如下两个属性:
- name:样式名
- parent:指定该样式所继承的父样式,此时的继承符合Java的继承规则。
- style元素可以包含多个 item 元素,每一个 item 元素定义一个格式项。
- 示例:
<!-- 定义一个样式,指定文字颜色、文字大小 -->
<style name="text_style1">
<item name="android:textColor">#999999</item>
<item name="android:textSize">15sp</item>
</style>
<!-- 定义一个新的样式,继承上述样式,指定边距等 -->
<style name="text_style2" parent="text_style1">
<item name="android:padding">5dp</item>
<item name="android:maxLines">1</item>
</style>
主题资源
- 与样式资源非常类似,保存在/res/values/目录下,以 resource 元素为根元素,style 元素为子元素。
- 其与样式资源的区别主要体现在:
- 主题不能作用于单个View,主题应对整个应用中的所有Activity起作用,或者对指定的Activity起作用。
- 主题定义的格式应该是改变窗口外观的格式,例如窗口标题、窗口外观等。
属性资源
- 属性资源文件保存在/res/values/文件夹下,其根元素也是 resource 元素,resource 元素包含下述两个子元素:
- attr 子元素:定义一个属性
- declare-styleable子元素:定义一个styleable对象,每个styleable对象就是一组attr属性集合
- 在自定义组件的构造器中通过AttributeSet对象来获取属性。
- 示例:
<!-- 定义一个属性 -->
<attr name="duration"></attr>
<!-- 定义一个styleable对象来组合多个属性 -->
<declare-styleable name="AlphaImageView">
<attr name="duration"/>
</declare-styleable>
package com.fpp.status.customview;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.widget.ImageView;
import com.fpp.status.R;
import java.util.Timer;
import java.util.TimerTask;
/**
* @author fupengpeng
* @description 描述
* @data 2018/4/18 0018 15:26
*/
public class AlphaImageView extends ImageView {
// 图片透明度每次改变的大小
private int alphaDelta = 0;
// 记录图片当前的透明度
private int curAlpha = 0;
// 每隔多少毫秒透明度改变一次
private final int SPEED = 300;
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
if (msg.what == 0x123){
// 每次增加curAlpha的值
curAlpha += alphaDelta;
if (curAlpha > 255){
curAlpha = 255;
}
// 修改该ImageView的透明度
AlphaImageView.this.setAlpha(curAlpha);
}
}
};
public AlphaImageView(Context context, AttributeSet attrs){
super(context,attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.AlphaImageView);
// 获取duration参数
int duration = typedArray.getInt(R.styleable.AlphaImageView_duration,0);
// 计算图片透明度每次改变的大小
alphaDelta = 255 * SPEED / duration;
}
@Override
protected void onDraw(Canvas canvas) {
this.setImageAlpha(curAlpha);
super.onDraw(canvas);
final Timer timer = new Timer();
// 按固定间隔发送消息,通知系统改变图片的透明度
timer.schedule(new TimerTask() {
@Override
public void run() {
Message msg = new Message();
msg.what = 0x123;
if (curAlpha >= 255){
timer.cancel();
}else {
handler.sendMessage(msg);
}
}
},0,SPEED);
}
}
<com.fpp.status.customview.AlphaImageView
app:duration="5000"
android:src="@drawable/nvshengtouxiang"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
原始资源
- 除了上述各资源以外,Android可能还用到其他资源(例如声音等),而这些资源一般保存在下述两个目录下:
- 位于 /res/raw/ 目录下,Android SDK 会处理该目录下的原始资源,Android SDK 会在R清单类中为该目录下的资源生成一个索引项。其在Java代码中和XML中使用同上述资源类似。
- 位于 /assets/ 目录下,该目录下是更加彻底的原始资源,Android应用通过AssetManager来管理该目录下的原始资源。AssetManager是一个专门管理 /assets/ 目录下的原始资源的管理器类,一般使用 InputStream open(String fileName)方法(获取资源文件的输入流)和AssetFileDescriptor openFd(String fileName)方法(获取对资源文件进行描述的对应的AssetFileDescriptor对象,再通过AssetFileDescriptor对象获取原始资源。)来获取对应的资源文件。
- 示例:
// 播放assets文件夹下的声音文件
public void assets(View resource) {
// 获取应用的AssetManager
AssetManager am = getAssets();
try {
// 获取指定文件对应的AssetFileDescriptor
AssetFileDescriptor afd = am.openFd("haojiubujian.mp3");
MediaPlayer mediaPlayer2 = new MediaPlayer();
// 使用MediaPlayer加载指定的声音文件
mediaPlayer2.setDataSource(afd.getFileDescriptor());
mediaPlayer2.prepare();
// 播放声音
mediaPlayer2.start();
} catch (IOException e) {
e.printStackTrace();
}
}
// 播放raw文件夹下的声音文件
public void raw(View resource) {
// 直接根据声音文件的id来创建MediaPlayer
MediaPlayer mediaPlayer1 = MediaPlayer.create(this, R.raw.haojiubujian);
// 播放声音
mediaPlayer1.start();
}
/**
* 播放raw文件夹下视频文件
*/
private void playRawVideo() {
mVideoView.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/raw/" + R.raw.massif));
mVideoView.start();
}