網易雲音樂 Android 客戶端底部的播放欄是怎麼做到在各個頁面存在的?

如圖箭頭所示,這個半透明的播放欄在各個頁面都有(部分頁面沒有),我的猜測是整個頁面存在在一個Activity裡面,播放欄蓋在一個FrameLayout上面,在FrameLayout裡面實現了各個界面。但是感覺這樣做對系統性能有點影響,畢竟一個Activity裡面放了那麼多個Fragment。求大神指教。


@某澤

先說結果,activity實現

從實現上考慮,我也覺得使用Fragment會更好一些,只要在Container Activity註冊廣播監聽播放狀態就行了。

而都用Activity的話,需要封裝BaseActivity在OnResume註冊監聽、在onPause取消監聽,然後界面也每個Activity都會有一個狀態欄,實現起來感覺還是會比上一個方案麻煩。

那到底是什麼呢?

正好之前寫了個工具,可以查看當前顯示的activity,需要的同學可以自取,支持Android 5.0+

apk DemoCollections/ViewDebugHelper/apks at master · waylife/DemoCollections · GitHub

代碼DemoCollections/ViewDebugHelper at master · waylife/DemoCollections · GitHub

首頁com.netease.cloudmusic.activity.MainActivity

歌單com.netease.cloudmusic.activity.PlayListActivity

排行榜com.netease.cloudmusic.activity.UserAndProgramBillboardActivity

那有沒有可能是WindowManager呢,比如360的懸浮窗就是用它實現的,來看下。

頁面結構是這樣的,主頁面為例,還是使用Android Device Monitor

在裡面有顯示節點信息,那就不是WindowManager了。

也就是說基本可以斷定是Activity了。

至於系統性能,這個還好。那為什麼用Activity呢?

通過Jadx反編譯,看下activity聲明。

或許只是網易的開發同學比較偏好這種方式吧。


最近發現可以直接用一個懸浮窗懸浮在所有窗口的上面,然後動態控制顯示隱藏,這樣就不用所有頁面都去添加一個view。因為現在很多手機默認都是會禁用懸浮窗的,所以我修改了下type,代碼如下:

final TextView textView = new TextView(Main2Activity.this);
textView.setBackgroundColor(Color.BLACK);
textView.setText("test sdfsada");
textView.setTextSize(20);
textView.setTextColor(Color.WHITE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.TYPE_TOAST);//TYPE_TOAST 是關鍵 這樣就不需要懸浮窗許可權了
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;//禁止獲得焦點,不然下面的界面無法接收到觸摸點擊事件 無法接收onBack
params.width = 400;
params.height = 200;
params.format = PixelFormat.TRANSLUCENT;

textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("test", "test");
startActivity(new Intent(Main2Activity.this, MainActivity.class));
//textView.setVisibility(View.GONE);
}
});
WindowManager windowManager = (WindowManager)getApplication().getSystemService(getApplication().WINDOW_SERVICE);
windowManager.addView(textView, params);

WindowManager.LayoutParams(WindowManager.LayoutParams.TYPE_TOAST);這句話是關鍵,將懸浮窗的類型設置為Toast,這樣就不需要許可權就能顯示。在小米手機上親測可用。


可以參考 TabActivity 的實現方法,個人感覺用 Fragment 更合適


樓主,我按照@RxRead的思路實現了一個,效果好像還行,可以參考一下。 由於知乎不能上傳gif

地址:仿網易雲音樂 Android 客戶端底部的播放欄

演示效果在這 (可能有點大):http://pan.baidu.com/s/1qXuMQK0


tool…toolbar?


相似的知乎安卓版本的底部bar,也是每個頁面都有。但是不同於網易雲音樂的是知乎的幾乎所有頁面都是在一個MainActivity裡面,切不同的Fragment管理的。


估計是很早時候寫的,當時還沒有Fragment,不過這樣寫內存會高些吧,代碼沒有與時俱進


activity實現


activity+fragment是一種實現的方法,模仿過,不過界面太丑,不貼了!

不知道我的想法對不對,把底部欄寫在activity上,然後上面的ui就是fragment的交替了!


寫一個BaseActivity,封裝統一處理播放欄各種狀態的方法,需要顯示播放欄的子Activity都繼承這個BaseActivity就可以了


下面那個播放欄半透明,所以應該是疊在主界面上,主界面用 viewgroup應該比較方便,然後下面的播放欄在切換界面時根據不同的情況選擇visible,gone就行了


qq音樂是fragment實現


推薦閱讀:

Swift(相關構架) vs Xamarin, 那個會成為真正的廣泛接受的跨平台開發構架?
如何理解android mvp模式中的interactor?
為什麼 Android 中安裝在 SD 卡上的應用無法添加 Widget?
Android 5.0 如何實現將布局的內容延伸到狀態欄?
最近Android studio出了1.0版,但是SDK一直無法下載,請問大家是怎麼解決的?

TAG:Android開發 | 網易雲音樂 |