您不知道的Android UI样式大全

112 阅读9分钟
title: Android UI样式详解
lang: zh
date: 2018-04-20 14:47:01
permalink: /pages/0101002/
sidebar: auto
comments: true
categories:
  - Android
tags:
  - Android
author:
  name: Leo
  link: https://github.com/leo94666

Android 样式采用xml文件,本篇文章主要对res目录作详细解释,包括了layout布局文件、menu菜单文件、style样式文件、string字符串资源等等

--res
    |--anim        存放tween animation(补间动画)和frame animation(逐帧动画)
    |--animator    存放property animation(属性动画)
    |--transition  过渡动画
    |--drawable    管理图片资源和xml资源,xml资源包括selector、shape、vector等等
    |--layout      管理UI布局
    |--menu        管理菜单布局
    |--mipmap      App启动图标
    |--navigation  Jetpack navigation导航
    |--raw         打包后会原封不动的保存在apk包中,不会被编译成二进制,与assets一样,但又有所区别
    |--values      颜色、像素、字符串、样式等资源
    |--xml         偶尔用到,会被编译成二进制格式

anim(View动画)

anim主要存放逐帧动画(frame animation)和补间动画(tween animation)

逐帧动画(frame animation)

在res下anim文件夹下创建一个animation-list标签的文件frame_anim.xml,内容如下

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@drawable/a_0"
        android:duration="100" />
    <item
        android:drawable="@drawable/a_1"
        android:duration="100" />
    <item
        android:drawable="@drawable/a_2"
        android:duration="100" />
</animation-list>

让逐帧动画动起来

​
ImageView mImageView = findViewById(R.id.animation_frame_anim);
​
mImageView.setImageResource(R.anim.frame_anim);
​
AnimationDrawable mAnimationDrawable = (AnimationDrawable) mImageView.getDrawable();
​
mAnimationDrawable.start()
​
  • 在animtion-list中使用item定义动画的全部帧,并指定各帧的持续时间
  • 在需要的ImageView上设置xml动画资源
  • 获取该Imageiew的AnimationDrawable类,并调用它的方法start即可

补间动画(tween animation)

补间动画有两种使用方式,静态加载动态加载,其五个动画标签,与其对应的Java类,如下

java类名xml健功能描述
ScaleAnimationscale缩放
RotateAnimationrotate旋转
TranslateAnimationtranslate移动
AlphaAnimationalpha淡入淡出
AnimationSetset组合动画

:::: el-tabs

::: el-tab-pane label=scale

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromXScale="0.0"
    android:fromYScale="0.0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toXScale="1.0"
    android:toYScale="1.0"/>
​

:::

::: el-tab-pane label=rotate

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:toDegrees="360"
    android:duration="1000"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"/>

:::

::: el-tab-pane label=translate

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="300"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:toXDelta="300"
    android:toYDelta="300" />

:::

::: el-tab-pane label=alpha

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromAlpha="1.0"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:toAlpha="0.0" />

:::

::: el-tab-pane label=set

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:interpolator="@android:anim/decelerate_interpolator">
    <scale
        android:fromXScale="0.1"
        android:fromYScale="0.1"
        android:pivotX="50%p"
        android:pivotY="50%p"
        android:toXScale="1.0"
        android:toYScale="1.0" />
    <alpha
        android:fromAlpha="0.1"
        android:toAlpha="1.0" />
    <translate  
        android:duration="2000"  
        android:fromXDelta="0"  
        android:fromYDelta="0"  
        android:toXDelta="320"  
        android:toYDelta="0" />  
    <rotate  
        android:duration="1000"  
        android:fromDegrees="0"  
        android:repeatCount="1"  
        android:repeatMode="reverse"  
        android:toDegrees="360" />  
</set>

:::

::::

xml静态加载方式会经过系统解析成动态方式,这五个类均继承Animation类,下面表格详细介绍了Animation的方法

xml属性java方法说明
android:durationsetDuration(long)动画持续时间,单位为ms
android:detachWallpapersetDetachWallpaper(boolean)是否在壁纸上运行
android:fillAftersetFillAfter(boolean)控件结束时候是否保持动画的最后状态
android:fillBeforesetFillBefore(boolean)控件动画结束时是否还原到开始动画前的状态
android:fillEnabledsetFillEnabled(boolean)与android:fillBefore效果相同
android:interpolatorsetInterpolator(Interpolator)设定插值器
android:repeatCountsetRepeateCount(int)重复次数
android:repeatModesetRepeatMode(int)重复类型,2个值,reverse表示倒序回放,restart表示顺序播放
android:startOffsetsetStartOffset(long)调用start函数之后等待开始运行的时间,单位ms
android:zAdjustmentsetZAdjustment(int)表示被设置动画的内容运行在Z轴上的位置(3个值,top/bottom/normal,默认为normal)

Interpolator

::: tip Interpolator 动画渲染器 在这些xml里有个东西:Interpolator,这个是用来控制动画的变化速度,我们可以自己实现Iinterpolator接口,自行来控制动画的变化速度, 而Android系统已经为我们提供了5个可供选择的实现类:

  • LinearInterpolator 动画以均匀的速度改变
  • AccelerateInterpolator 在动画开始的地方改变速度较慢,然后开始加速
  • AccelerateDecelerateInterpolator 在动画开始、结束的地方改变速度较慢,中间时加速
  • CycleInterpolator 动画循环播放特定次数,变化速度按正弦曲线改变: Math.sin(2 * mCycles * Math.PI * input)
  • DecelerateInterpolator 在动画开始的地方改变速度较快,然后开始减速
  • AnticipateInterpolator 反向,先向相反方向改变一段再加速播放
  • AnticipateOversshootInterpolator 开始的时候向后然后向前甩一定值后返回最后的值
  • BounceInterpolator 跳跃,快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100
  • OvershottInterpolator 回弹,最后超出目的值然后缓慢改变到目的值

我们一般是在写动画xml文件时会用到,属性是:android:interpolator, 而上面对应的值是:@android:anim/linear_interpolator,其实就是驼峰命名法变下划线而已 AccelerateDecelerateInterpolator对应:@android:anim/accelerate_decelerate_interpolator! :::

静态加载

属性解释
  • scale

    • duration 动画持续时间,单位ms
    • fromXScale 沿着X轴缩放的起始比例
    • fromYScale 沿着Y轴缩放的起始比例
    • pivotX 缩放的中轴点的x坐标
    • pivotY 缩放的中轴点的y坐标
    • toXScale 沿着X轴缩放的结束比例
    • toYScale 沿着Y轴缩放的结束比例
  • rotate

    • fromDegrees 旋转的起始角度
    • toDegrees 旋转的结束角度
    • duration 动画持续时间,单位ms
    • interpolator 动画渲染器
    • repeatCount 旋转的次数,如果值是n,则旋转n+1次,若n=-1或者infinite,表示动画永不停止
  • translate

    • duration 动画持续时间,单位ms
    • fromXDelta 动画起始位置的x坐标
    • fromYDelta 动画起始位置的y坐标
    • toXDelta 动画结束位置的x坐标
    • toYDelta 动画结束位置的y坐标
  • alpha

    • duration 动画持续时间,单位ms
    • fromAlpha 起始透明度
    • toAlpha 结束透明度,透明度范围:0-1,完全透明-完全不透明
    • interpolator 动画渲染器
  • set

    • duration 动画持续时间,单位ms
    • interpolator
    • shareInterpolator 布尔值,true: 共享一个指定的Interpolator,flase,不共享,动画效果需要单独指定Interpolator
使用方法

静态加载方式是采用xml方式来实现补间动画

// 获取要设置补间动画的控件
ImageView mImageView = findViewById(R.id.iv_alpha);
​
//加载补间动画--alpha动画
Animation animation = AnimationUtils.loadAnimation(mImageView,R.anim.anim_alpha);
​
// Animation animation = AnimationUtils.loadAnimation(mImageView,R.anim.anim_scale);// Animation animation = AnimationUtils.loadAnimation(mImageView,R.anim.anim_translate);// Animation animation = AnimationUtils.loadAnimation(mImageView,R.anim.anim_rotate);// Animation animation = AnimationUtils.loadAnimation(mImageView,R.anim.anim_set);
​
​
animation.setInterpolator(new LinearInterpolator());
​
//开始动画
mImageView.startAnimation(animation);
​
//设置动画状态监听
animation.setAnimationListener(new AnimationListener() {
      @Override
      public void onAnimationStart(Animation animation) {
          //动画开始
      }
​
      @Override
      public void onAnimationEnd(Animation animation) {
          //动画结束
      }
​
      @Override
      public void onAnimationRepeat(Animation animation) {
          //动画重复
      }
});
​

动态加载

属性解释
  • ScaleAnimation
  • RotateAnimation
  • TranslateAnimation
  • AlphaAnimation
  • AnimationSet
使用方法

动态加载是采用Java的方式

// 获取要设置补间动画的控件
ImageView mImageView = findViewById(R.id.iv_alpha);
​
//动态创建补间动画
AlphaAnimation mAlphaAnimation = new AlphaAnimation(0, 1);
mAlphaAnimation.setDuration(300);
​
//开始动画
mImageView.startAnimation(mAlphaAnimation);
​
//设置动画状态监听
mAlphaAnimation.setAnimationListener(new AnimationListener() {
      @Override
      public void onAnimationStart(Animation animation) {
          //动画开始
      }
​
      @Override
      public void onAnimationEnd(Animation animation) {
          //动画结束
      }
​
      @Override
      public void onAnimationRepeat(Animation animation) {
          //动画重复
      }
});
​

animator(属性动画)

animator文件夹下存放属性动画(Property Animation),属性动画可以做到View动画做不到的情况,比如3D旋转动画; 属性动画实现原理就算改变控件的属性值实现的动画 Android 3.0, API 11之后才有属性动画。默认帧率10ms/帧,动画默认时间间隔300ms。 xml文件里有三个标签

  • animator

  • objectAnimator

    • valueFrom
    • valueTo
    • propertyName
    • startOffset
    • duration
    • interpolator
  • set

transition

drawable & mipmap

Android 有多种存放图片资源的方式,最常用的就是drawable和mipmap两种方式,两者都可以添加图片,不过官方建议mipmap存放App应用图标,可见Android官方建议,两者有以下区别:

  • mipmap不能放9patch图片
  • mipmap支持多尺度缩放效果更好,更多用来存放应用图标
  • png、jpeg、gif、.9图、xml均放在drawable
  • drawable里图片需要准备多种密度的图片,以应对Android的碎片化问题

图片资源分类

图片资源最常用的是drawable资源,格式有png(推荐)、jpg(可接受)、gif(不建议),使用图片资源需要根据不同屏幕密度提供多张不同尺寸的图片,如下表:

密度分类密度值范围代表分辨率图标尺寸图片比例
mdpi120~160dpi320x480px48✖48px1
hdpi160~240dpi480x480px72x72px1.5
xhdpi240~320dpi720x1280px96x96px2
xxhdpi320~480dpi1080x1920px144x1443
xxxhdpi480~640dpi1440x2560px192x192px4

应用图标规范

Android官方建议将应用图标存放在mipmap目录中,而不是drawable目录中,与drawable不同,所有mipmap目录都会保留在APK中,即使基于构建特定密度的APK 也是如此,这样,起动器应用便可选取要显示在主屏幕上的最佳分辨率图标。


res/
    mipmap-xxxhdpi/
        launcher.png
    mipmap-xxhdpi/
        launcher.png
    mipmap-xhdpi/
        launcher.png
    mipmap-hdpi/
        launcher.png
    mipmap-mdpi/
        launcher.png

xml资源

selector

shape

  • rectangle
  • oval
  • line
  • ring
属性描述
android:color填充的颜色

layout

该目录主要存放UI布局,由于Android的碎片化问题,布局设计要十分灵活,主要有以下几种技巧

  • 使用允许布局调整大小的视图尺寸

  • 根据屏幕配置创建备用布局界面

      1. 使用最小宽度限定符 ::: tip -sw600dp: 希望在屏幕宽度至少为 600dp 时使用该布局 ::: ::: tip 下面是最小宽度值与典型屏幕尺寸的对应关系

      • 320dp:典型手机屏幕(240x320 ldpi、320x480 mdpi、480x800 hdpi等等)
      • 480dp:约5英寸的大手机屏幕(480x800 mdpi)
      • 600dp:7英寸平板电脑(600x1024 mdpi)
      • 720dp:10英寸平板电脑(720x1280 mdpi、800x1280 mdpi)

      最小宽度限定符最小宽度限定符 :::

      1. 使用可用宽度限定符 ::: tip -w600dp: 希望在屏幕宽度至少为 600dp 时使用该布局 :::
      1. 使用可用高度限定符 ::: tip -h600dp: 希望在屏幕高度至少为 600dp 时使用该布局 :::
      1. 使用屏幕方向限定符 ::: tip -land: 横向布局、-port:纵向布局 -sw600dp-land: 希望在屏幕宽度至少为 600dp 且为横向布局时使用该布局 :::
      1. 使用Fragment将界面组件模块化
  • 提供可以随试图一起拉伸的位图

    • .9.png 图片

menu

菜单是Android应用中非常重要的组成部分,主要分为以下三类:

  • 选项菜单
  • 上下文菜单
  • 上下文操作模式以及弹出菜单

menu 也有两种方式设置,即xml静态方式和java动态方式

Java类名xml关键字功能描述
menumenu菜单项的容器
groupgroupitem的不可见容器
MenuItemitem菜单项
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <group>
        <item
            android:id="@+id/nav_one"
            android:enabled="true"
            android:icon="@drawable/icon_elab_select"
            android:title="@string/e_lab"
            app:showAsAction="ifRoom" />
    </group>
    
    <item
        android:id="@+id/nav_two"
        android:enabled="true"
        android:icon="@drawable/icon_mail_select"
        android:title="@string/maillist"
        app:showAsAction="ifRoom" />
</menu>

navigation

raw

values

colors.xml

dimens.xml

strings.xml

styles.xml

xml