Some developers have difficult to code when the UI proposal is a bit “sophisticated” or “complex”. Many of them strip a lot of significant portion of the UI or even the Motion when they are coding, and the result ends up quite different of the original proposal.

This post talks about how would be to code an UI proposal, skipping some basic Android details and focusing in the transition and animation approach.

MaterialUp

A great website where designers and developers can find and share resources to build apps and sites using Material Design. There is a lot of user interfaces, experiments, open-source apps, libraries and ready-to-use products in Android, Web, and iOS that you can find there.

 

Music Player transition by Anish Chandran

Exploring that website you can find this user interface resource called Music Player created by Anish Chandran.

That proposal gives us a good sample of how would be a music player app that uses Material and Motion design in a fluid and consistent manner.

Warming up

First of all we need to do something that helps us to code all these motion.

Split the motion proposal in frames

Convert the animated proposal file into individual frames. This will help us to view each step of the animations and transitions.

Separate by types

We have a lot of views transitioning and animating at same time, and think how to code this way will be very hard. We can separate those transitions and animations by type, for example: Views sliding to bottom, Views fading out, Views moving out to new Activity, etc.

The next tip is a good one to use in EVERY layout, with motion or not.

Simplify your view hierarchy

Create view hierarchy as simpler as possible, avoiding to use a lot of View Groups in the same layout. This will make easy the transition choreography, will help the maintenance, as well as improve significantly the app performance mainly during the animations.

How the magic happens

In layout files, some View Groups have the android:transitionGroup attribute set to true because they need to be treated as a single entity during the Activity Transitions as in the playlist info container (main layout file) or controls container (detail layout file).

<RelativeLayout
2     android:id="@+id/playlist"
3     android:layout_width="match_parent"
4     android:layout_height="wrap_content"
5     android:layout_below="@id/cover"
6     android:gravity="center_vertical"
7     android:padding="@dimen/activity_vertical_margin"
8     android:transitionGroup="true">
9 …
10 

11 <LinearLayout
12     android:id="@+id/controls"
13     android:layout_width="match_parent"
14     android:layout_height="wrap_content"
15     android:layout_alignParentBottom="true"
16     android:gravity="center_horizontal"
17     android:transitionGroup="true"
18     app:layout_marginBottomPercent="5%">
19 … 

In styles.xml we have the themes used in our Main Activity and Detail Activity.

  • AppTheme.Main

    windowSharedElementsUseOverlay.xml  Permalink 
    
    1 <item name="android:windowSharedElementsUseOverlay">false</item> 

Disable overlaying of shared element views. In this Music Player layouts we need to disable the overlay when shared element views is moving out from Main to Detail Activity. If it’s enabled, some shared element views could overlay other views in a wrong manner.

list_content_exit_reenter_transition.xml  Permalink 

1 <item name="android:windowExitTransition">@transition/list_content_exit_transition</item>
2 <item name="android:windowReenterTransition">@transition/list_content_reenter_transition</item> 
 
 

It has the same transition approach in both exit and reenter transition of list content.

list_content_exit_reenter_transition.xml  Permalink 

1 <?xml version="1.0" encoding="utf-8"?>
2 <transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
3     android:duration="@integer/anim_duration_default"
4
5     // 1
6     android:startDelay="@integer/anim_duration_default">
7 

8     // 2
9     <fade>
10         <targets>
11             <target android:targetId="@id/pane" />
12         </targets>
13     </fade>
14
15     // 3
16     <slide android:slideEdge="bottom">
17         <targets>
18             <target android:excludeId="@android:id/statusBarBackground" />
19             <target android:excludeId="@id/pane" />
20             <target android:excludeId="@android:id/navigationBarBackground" />
21         </targets>
22     </slide>
23 

24 </transitionSet> 
  1. Set a start delay to synchronize these transitions with the FAB morph animation.
  2. Fade just the pane view specified by targetId attribute.
  3. Slide to bottom the RecyclerView childs and playlist info container, excluding status bar, pane, and navigation bar specified by excludeId attribute.
list_shared_element_exit_reenter_transition.xml  Permalink 

1 <item name="android:windowSharedElementExitTransition">@transition/list_shared_element_exit_transition</item>
2 <item name="android:windowSharedElementReenterTransition">@transition/list_shared_element_reenter_transition</item> 
 

It has almost the same transition approach in both exit and reenter transition of list content.

 list_shared_element_exit_reenter_transition.xml  Permalink 

1 <transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
2     xmlns:app="http://schemas.android.com/apk/res-auto"
3     android:duration="@integer/anim_duration_default">
4 

5     // 1
6     <transition
7         class="com.sample.andremion.musicplayer.transition.PlayButtonTransition"
8         app:mode="play|pause" />
9 

10 </transitionSet> 
  1. PlayButtonTransitionis a custom transition that wraps an AnimatedVectorDrawableand used to morph the play icon into pause icon or vice-versa, depending the mode value.
  • AppTheme.Detail
  detail_content_enter_return_transition.xml  Permalink 

1 <item name="android:windowEnterTransition">@transition/detail_content_enter_transition</item>
2 <item name="android:windowReturnTransition">@transition/detail_content_return_transition</item> 
 

It has the same transition approach in both enter and return transition of detail content.

detail_content_enter_return_transition.xml  Permalink 

1 <transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
2     android:duration="@integer/anim_duration_default">
3 

4     // 1
5     <fade>
6         <targets>
7             <target android:targetId="@id/ordering" />
8         </targets>
9     </fade>
10
11     // 2
12     <slide android:slideEdge="bottom">
13         <targets>
14             <target android:targetId="@id/controls" />
15         </targets>
16     </slide>
17 

18 </transitionSet> 
  1. Fade just the ordering container specified by targetId attribute.
  2. Slide to bottom just the controls container specified by targetId attribute.
detail_shared_element_enter_transition.xml  Permalink 

1 <item name="android:windowSharedElementEnterTransition">@transition/detail_shared_element_enter_transition</item> 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
detail_shared_element_enter_transition.xml  Permalink 

1 <transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
2     android:duration="@integer/anim_duration_default"
3
4     // 1
5     android:interpolator="@android:interpolator/accelerate_quad">
6
7     // 2
8     <transition class="com.sample.andremion.musicplayer.transition.ProgressViewTransition" />
9
10     // 3
11     <transition class="com.sample.andremion.musicplayer.transition.CoverViewTransition" />
12
13     // 4
14     <transitionSet>
15         <changeBounds />
16         <changeTransform />
17         <changeClipBounds />
18         <changeImageTransform />
19     </transitionSet>
20 

21 </transitionSet> 
  1. Define an interpolator to the rate of change of transition, allowing a non-linear motion.
  2. ProgressViewTransition is a custom transition that uses a ProgressView to “morph” an horizontal progress view to an arc progress view.
  3. CoverViewTransition is another custom transition that uses CoverView to “morph” the squared cover view to circled cover view with track lines.
  4. Use default move transitions into the others shared element views.
Raw 

  detail_shared_element_return_transition.xml  Permalink 

1 <item name="android:windowSharedElementReturnTransition">@transition/detail_shared_element_return_transition</item> 
 

In this transition was used almost the same approach of detail_shared_element_enter_transition. But it was added some delay for each part to match this transition with the proposal.

detail_shared_element_return_transition.xml  Permalink 

1 <transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
2     xmlns:app="http://schemas.android.com/apk/res-auto"
3     android:duration="@integer/anim_duration_default"
4     android:interpolator="@android:interpolator/accelerate_quad">
5 

6     // 1
7     <transitionSet>
8         <changeBounds />
9         <changeTransform />
10         <changeClipBounds />
11         <changeImageTransform />
12         <transition
13             class="com.sample.andremion.musicplayer.transition.ProgressViewTransition"
14             app:morph="1" />
15         <targets>
16             <target android:targetId="@id/progress" />
17         </targets>
18     </transitionSet>
19 

20     // 2
21     <transitionSet android:startDelay="@integer/anim_duration_short">
22         <changeBounds />
23         <changeTransform />
24         <changeClipBounds />
25         <changeImageTransform />
26         <transition
27             class="com.sample.andremion.musicplayer.transition.CoverViewTransition"
28             app:shape="circle" />
29         <targets>
30             <target android:targetId="@id/cover" />
31         </targets>
32     </transitionSet>
33 

34     // 3
35     <transitionSet android:startDelay="@integer/anim_duration_default">
36         <changeBounds />
37         <changeTransform />
38         <changeClipBounds />
39         <changeImageTransform />
40     </transitionSet>
41 

42 </transitionSet> 
  1. The reverse “morph” mode, from arc progress view to horizontal progress view.
  2. The reverse “morph” mode, from circled cover view to squared cover view.
  3. Use default move transitions into the others shared element views.

Final Result

 

Music Player coded by André Mion

The final result should be like that. Of course, some minimal details can be missed in the final project but it would be a little thing.

The entire project can be found in https://github.com/andremion/Music-Player

At link below you can read more about meaningful motion on Android

(Forward) Music Player: From UI Proposal to Code的更多相关文章

  1. Sound (audio file) player in java - working source code example

    转载自:http://ganeshtiwaridotcomdotnp.blogspot.com/2011/12/sound-audio-file-player-in-java-working.html ...

  2. IOS开发中UI编写方式——code vs. xib vs.StoryBoard

    最近接触了几个刚入门的iOS学习者,他们之中存在一个普遍和困惑和疑问,就是应该如何制作UI界面.iOS应用是非常重视用户体验的,可以说绝大多数的应用成功与否与交互设计以及UI是否漂亮易用有着非常大的关 ...

  3. Qt中forward declaration of struct Ui::xxx的解决

    每当你新键一个 QT设计界面, QT会自动生成yyy.ui文件,如 <?xml version="1.0" encoding="UTF-8"?> & ...

  4. 解决QT:forward declaration of &#39;struct Ui::xxx&#39;;invalid use of incomplete struct &quot;Ui::Widget&quot; 等莫名奇异错误

    今天在进行QT Widget的UI设计时,改了下Widget的对象名,然后在多次成功编译执行后,执行清理,又一次构建,就出现了好多莫名奇异的错误: widget.h:12: 错误:forward de ...

  5. MVC模式在UI里的应用

    In a similar way to other parts of a game, user interfaces usually go through several iterations unt ...

  6. 计算机视觉code与软件

    Research Code A rational methodology for lossy compression - REWIC is a software-based implementatio ...

  7. Semantic ui 学习笔记 持续更新

    这个semantic 更新版本好快~ 首先是代码的标识<code></code> 具体样式就是红框这样的 圈起来代码感觉不错 不过要在semantic.css里在加上如下样式~ ...

  8. Android Non-UI to UI Thread Communications(Part 1 of 5)

    original:http://www.intertech.com/Blog/android-non-ui-to-ui-thread-communications-part-1-of-5/ ANDRO ...

  9. [EXP]Microsoft Windows CONTACT - Remote Code Execution

    [+] Credits: John Page (aka hyp3rlinx) [+] Website: hyp3rlinx.altervista.org [+] Source: http://hyp3 ...

随机推荐

  1. candence 知识积累4

    一.PCB布局约束: 1.尺寸规划:PCB大小要合适,PCB太大印制线路长,阻抗增加.太小散热不好,易受干扰. 2.PCB尺寸确定后要确定特殊器件的位置. 3.尽可能缩短高频元器件之间的连线,设法减少 ...

  2. 跟大牛之间关于hibernate的一些探讨记录

    hibernate的工作原理!! 1.读取配置文件 2.读取并解析映射信息,创建SessionFactory 3.打开Session 4.创建事务Transcation 5.持久化操作 6.提交事务 ...

  3. join()、implode()函数

    join() 函数 join() 函数把数组元素组合为一个字符串. join() 函数是 implode() 函数的别名. 语法 join(separator,array) 参数 描述 separat ...

  4. mudOS源码 options.h配置详细选项

    /* options.h配置详细选项—————————————————————————-将 MudOS 下载解压以后可以在相应目录的根目录中找到 options.h 这个文件.如果修 改了这个文件,那 ...

  5. JSP 动作元素

    JSP动作元素 1.  动作元素分类 用来动态的包含文件.网页跳转及使用JavaBean组件等. 语法:<jsp:XXX />或者<jsp:XXX></jsp:XXX&g ...

  6. Timer和TimerTask的用法

    最近在做java课程设计的时候,我用到了timer,于是学习了一下timer的用法. java实现多线程比较常用的两种方法,一种是直接继承Thread类,另一种则是实现Runnable接口.Timer ...

  7. MongoDB学习笔记四:索引

    索引就是用来加速查询的.创建数据库索引就像确定如何组织书的索引一样.但是你的优势是知道今后做何种查询,以及哪些内容需要快速查找.比如:所有的查询都包括"date"键,那么很可能(至 ...

  8. JS特殊函数(Function()构造函数、函数直接量)区别介绍

    函数定义 函数是由这样的方式进行声明的:关键字 function.函数名.一组参数,以及置于括号中的待执行代码. 函数的构造语法有这三种: 1.function functionName(arg0, ...

  9. 使用xhprof分析php性能

    今天偶然发现 xhprof可以远程分析php代码性能,大致步骤如下 1.  进入 xhprof , 点击右上角注册 并 登陆, 网站左侧解释了如何在本地安装测试xhprof, 我用的是右侧的图表模式, ...

  10. Mysql-简单安装

    centos上安装msqyl 通过如下命令来查看我们的操作系统上是否已经安装了mysql数据库 [root@CentOS6.5 ~]# rpm -qa | grep mysql #这个命令就会查看该操 ...