Toolbar透明沉浸背景-善用FrameLayout

還是先放圖吧:

 

最近做個小東西,寫到了音樂播放界面,顏值這方面網易雲音樂絕對是佼佼者呀。於是就像弄出一個類似的效果,然後全屏都是歌曲圖片高斯模糊的背景,包括toolbar。

我的佈局主要有兩層是這個層級結構:

RelativeLayout->Toolbar,ImageView

我最初的思路有兩個:

一是把RelativeLayout的background直接設置模糊後的背景;

二是把ImageView的高度設置爲match_parent,然後把模糊好的圖片設置爲它的背景。

可是這麼一來,不管是RelativeLayout還是ImageView,我上面的toolbar的所有內容都被這個鋪滿窗口的背景給覆蓋了,我的返回圖標,文字,顏色都被覆蓋住不能顯示出來。

搞了大概幾個星期,就在今天,給公司項目加新界面的時候,要用到FrameLayout,於是突然來了靈感,也許我只是少了個FrameLayout呢?FrameLayout可以使得兩個控件重疊顯示,如果我在佈局最外層嵌套一個FrameLayout,那可不可以解決呢?

順着這個思路,我把FrameLayout放在佈局最外層,現在層級結構變成了

FrameLayout->RelativeLayout->Toolbar,ImageView

然後現在再按照上面的兩種方法之一設置背景,就實現了Toolbar跟下面整體統一背景了。

曾經被framelayout設置fragment時的重疊問題困擾,現在又能用它的這一特性來解決問題,真好!

下面把主要代碼貼上:

佈局:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".view.activity.MusicPlayActivity">
        <RelativeLayout
            android:id="@+id/rlMusicPlay"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:background="@color/white">
        <include
            layout="@layout/include_music_play_toolbar"/>
        <ImageView
            android:id="@+id/ivBg"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="fitXY"/>
        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true">
            <pers.ll.likenews.ui.CircleImageView
                android:id="@+id/ivMusicPic"
                android:layout_width="260dp"
                android:layout_height="260dp"
                tools:src="@mipmap/ic_launcher"
                />
        </FrameLayout>
        
        <RelativeLayout
            android:id="@+id/rlSeek"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_above="@id/rlMusicCtrl"
            android:layout_marginBottom="20dp"
            android:orientation="horizontal">
            <TextView
                android:id="@+id/tvCurTime"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="12sp"
                tools:text="00:49"
                android:textColor="@color/colorAccent"
                android:layout_alignParentLeft="true"
                android:layout_marginLeft="20dp"/>
            <SeekBar
                android:id="@+id/seekBar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:layout_marginRight="10dp"
                android:layout_centerVertical="true"
                android:layout_toLeftOf="@+id/tvMusicDuration"
                android:layout_toRightOf="@+id/tvCurTime"/>
            <TextView
                android:id="@+id/tvMusicDuration"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="12sp"
                tools:text="03:49"
                android:textColor="@color/colorAccent"
                android:layout_alignParentRight="true"
                android:layout_marginRight="20dp"/>
        </RelativeLayout>
        
        <RelativeLayout
            android:id="@+id/rlMusicCtrl"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_marginBottom="20dp">
            <ImageView
                android:id="@+id/ivPause"
                android:layout_width="55dp"
                android:layout_height="55dp"
                android:src="@drawable/ic_pause_circle"
                android:layout_centerHorizontal="true"/>
            <ImageView
                android:id="@+id/ivPrevious"
                android:layout_width="40dp"
                android:layout_height="40dp"
                android:src="@drawable/ic_skip_previous"
                android:layout_toLeftOf="@+id/ivPause"
                android:layout_marginRight="20dp"
                android:layout_centerVertical="true"/>
            <ImageView
                android:id="@+id/ivNext"
                android:layout_width="40dp"
                android:layout_height="40dp"
                android:src="@drawable/ic_skip_next"
                android:layout_toRightOf="@+id/ivPause"
                android:layout_marginLeft="20dp"
                android:layout_centerVertical="true"/>
        </RelativeLayout>
        
        <ImageView
            android:id="@+id/ivRecycle"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:src="@drawable/ic_repeat_one"
            android:layout_above="@+id/rlSeek"
            android:layout_alignParentRight="true"
            android:layout_marginRight="20dp"
            android:layout_marginBottom="7dp"/>
        </RelativeLayout>
</FrameLayout>

java:


這裏順便再記錄一下:這個頁面的全屏效果的實現,即狀態欄和底部導航欄與窗體內容同色。

一開始狀態欄是顯示的app主題中的colorPrimary顏色,後來我按照一位大神的記錄實現了狀態欄與窗體內容同色,在此要感謝一下:在有ToolBar的activity中實現標題欄透明,網易雲音樂播放頁面效果

其實重點就在一句話:

window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)

FLAG_LAYOUT_NO_LIMITS是允許窗口擴展到屏幕之外。各個Flag的功能在:WindowManager.LayoutParams詳解裏面有介紹。 

但是我寫了以後,會出現Toolbar被頂到狀態欄裏面去。這時候就需要給它設置一個marginTop高度等於狀態欄高度就行了,同理,底部也是如此,在我開頭第一張圖中底部的播放按鈕一行也被擠到了導航欄裏面,給這一行的RelativeLayout設置marginBottom,高度爲導航欄高度。如下:

下面是獲取狀態欄高度和導航欄高度的方法:

    /**
     * 獲取狀態欄高度的方法
     * */
    public static int getStatusBarHeight(Resources resource) {

        int statusBarHeight = -1;
        //獲取status_bar_height資源的ID
        int resourceId = resource.getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            //根據資源ID獲取響應的尺寸值
            statusBarHeight = resource.getDimensionPixelSize(resourceId);
        }
        Log.v("-------", "status bar height:"+ statusBarHeight);
        return statusBarHeight;
    }

    /**
    *獲取導航欄高度的方法
    */
    public static int getNavigationBarHeight(Resources resources) {

        int resourceId = resources.getIdentifier("navigation_bar_height","dimen","android");

        int height = resources.getDimensionPixelSize(resourceId);

        Log.v("navigation bar>>>", "height:" + height);

        return height;

    }

這是最終效果:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章