项目地址
Google最近开源了一款播放器,android-UniversalMusicPlayer,可以在phones, tablets, Auto, Wear and Cast devices提供一致的用户体验。
而且项目不算复杂,再加上编译起来很简单,就是Android Studio直接导入就可以了,很适合我这种新手学习。
总体UI分析
UI比较重要的类有MusicPlayerActivity, PlaceholderActivity, MediaBrowserFragment, FullScreenPlayerActivity, PlaybackControlsFragment。
其中MusicPlayerActivity, PlaceholderActivity都是继承BaseActivity, FullScreenPlayerActivity是继承ActionBarCastActivity,而BaseActivity是ActionBarCastActivity的子类。
ActionBarCastActivity主要实现了DrawLayout, Toolbar之类的功能,而BaseActivity在此之上又添加了与PlaybackControlsFragment交互的功能。
DrawerLayout
值得注意的是,这里的DrawerLayout是在不同的Activity之中进行切换,而不是在fragment之间。主要实现的方法主要是通过继承一个含有DrawLayout的Activity,在这里即是ActionBarCastActivity。可以参考该问题。
还有一个比较奇特的效果是,DrawerLayout原本被status bar 和 actionbar挡住的部分可以显示出来了。
具体做法分析可以参考源码和文章如何将DrawerLayout显示在ActionBar/Toolbar和status bar之间。
Animation
Drawble Animation
在播放时listview图标会有变动的效果。这个主要是在MediaItemViewHolder.java通过Drawble Animation实现的。
官方文档
主要实现代码:
AnimationDrawable animation = (AnimationDrawable)activity.getDrawable(R.drawable.ic_equalizer_white_36dp);
holder.mImageView.setImageDrawable(animation);
holder.mImageView.setImageTintList(sColorStatePlaying);
holder.mImageView.setVisibility(View.VISIBLE);
animation.start();
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
<item android:drawable="@drawable/ic_equalizer1_white_36dp" android:duration="200"/>
<item android:drawable="@drawable/ic_equalizer2_white_36dp" android:duration="200"/>
<item android:drawable="@drawable/ic_equalizer3_white_36dp" android:duration="200"/>
</animation-list>
切换Drawer Activity Fragment的动画效果
ActionBarCastActivity.java
Bundle extras = ActivityOptions.makeCustomAnimation(ActionBarCastActivity.this, R.anim.fade_in, R.anim.fade_out).toBundle();
Class activityClass = mDrawerMenuContents.getActivity(position);
startActivity(new Intent(ActionBarCastActivity.this, activityClass), extras);
MusicPlayerActivity.java
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.animator.slide_in_from_right, R.animator.slide_out_to_left, R.animator.slide_in_from_left, R.animator.slide_out_to_right);
transaction.replace(R.id.container, fragment);
小技巧
tools:xxx
在显示布局时,TextView可能需要文字填充来看看效果,但是又嫌调试后删去android:text=”…”麻烦,就可以用tools:text=”…”。
其中tools:xxx在用来预览界面方面还是很方便的。比如在看activity_player.xml预览时会提示fragment可能动态布局,请选择一个布局进行显示。进行选择后,就会在fragment里添加tools:layout=”@layout/fragment_playback_controls”,这样在预览时就可以看到PlaybackControlsFragment的具体布局,但对运行时又没有影响。
关于tools:xxx的用法可参考http://tools.android.com/tech-docs/tools-attributes。
android:tint
在播放器里,像播放按钮一共有两种颜色,白色和蓝色。我们可以使用两个不同的图标来完成这种效果,也可以通过android:tint来使图标简单地变色,有点像ps里添加蒙版的感觉。
xml里的用法是android:tint,可参考fragment_playback_controls.xml里的ImageButton。
Java里的用法setImageTintList(),可参考MediaItemViewHolder.java里相关代码。
sColorStateNotPlaying = ColorStateList.valueOf(ctx.getResources().getColor(R.color.media_item_icon_not_playing));
holder.mImageView.setImageTintList(sColorStatePlaying);