当前位置: 首页 > news >正文

(Forward) Music Player: From UI Proposal to Code

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

 

 

转载于:https://www.cnblogs.com/mukekeheart/p/5718005.html

相关文章:

  • 【leetcode】经典算法题-Counting Bits
  • SQL--常用命令
  • JDK1.7新特性(1):Switch和数字
  • ios开发图片轮播器以及定时器小问题
  • Ubuntu里面软件的安装与卸载
  • ubuntu 设置DNS
  • jquery ajax 传数据到后台乱码的处理方法
  • CSS样式
  • NuGet 学习笔记(1)--Nuget安装使用
  • Part5核心初始化_lesson2---设置svc模式
  • 几个常用的CSS3样式代码以及不兼容的解决办法
  • 报个到
  • iOS: NSArray的方法arrayByAddingObjectsFromArray:
  • excel转化为Json
  • dispatch_after 导致controller没有及时释放
  • [分享]iOS开发 - 实现UITableView Plain SectionView和table不停留一起滑动
  • 【跃迁之路】【669天】程序员高效学习方法论探索系列(实验阶段426-2018.12.13)...
  • 30天自制操作系统-2
  • android 一些 utils
  • Angular 2 DI - IoC DI - 1
  • C++类中的特殊成员函数
  • Cookie 在前端中的实践
  • Effective Java 笔记(一)
  • go append函数以及写入
  • iOS | NSProxy
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • Iterator 和 for...of 循环
  • Vim 折腾记
  • 不上全站https的网站你们就等着被恶心死吧
  • 对话:中国为什么有前途/ 写给中国的经济学
  • - 概述 - 《设计模式(极简c++版)》
  • 规范化安全开发 KOA 手脚架
  • 回顾 Swift 多平台移植进度 #2
  • 京东美团研发面经
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 协程
  • 用quicker-worker.js轻松跑一个大数据遍历
  • 阿里云重庆大学大数据训练营落地分享
  • 带你开发类似Pokemon Go的AR游戏
  • 哈罗单车融资几十亿元,蚂蚁金服与春华资本加持 ...
  • ​LeetCode解法汇总2808. 使循环数组所有元素相等的最少秒数
  • ​无人机石油管道巡检方案新亮点:灵活准确又高效
  • ​一帧图像的Android之旅 :应用的首个绘制请求
  • (NO.00004)iOS实现打砖块游戏(十二):伸缩自如,我是如意金箍棒(上)!
  • (Ruby)Ubuntu12.04安装Rails环境
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (力扣记录)1448. 统计二叉树中好节点的数目
  • (四)c52学习之旅-流水LED灯
  • (推荐)叮当——中文语音对话机器人
  • (详细版)Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models
  • (一)为什么要选择C++
  • (转载)深入super,看Python如何解决钻石继承难题
  • .bat批处理(十):从路径字符串中截取盘符、文件名、后缀名等信息
  • .cfg\.dat\.mak(持续补充)
  • .mysql secret在哪_MYSQL基本操作(上)