沉浸式狀態欄(二)

上一篇:沉浸式狀態欄(一)

話說上一篇沉浸式狀態欄的實現方法基本可以適用於絕大部分設備,普通項目用足夠了,但是看到QQ的的界面,效果卻略顯不同:

這裏寫圖片描述

如圖,這種沉浸式效果如果按第一篇的方法來做,就達不到這種效果了,我實際實現了下,也確實沒達到,用SystemBarTintManager的效果如下:

這裏寫圖片描述

我同樣用了一個側滑菜單(slidemenu)來模仿qq的側滑菜單,實際效果如上圖所示,這是爲什麼呢?我們只要知道SystemBarTintManager實現的原理就明白了,SystemBarTintManager實際上是修改了狀態欄的顏色,那麼這種方法帶來的一個問題就是遇到帶有側滑菜單這種界面,狀態欄顏色被固定了,也就成了上圖的效果,而無法達到qq的那種效果!

那麼,如果實現呢?其實也很簡單,我們先仔細觀察qq的狀態欄,分明就是一透明色的嗎,哈哈!如果狀態欄純透明,那麼無論界面怎麼變化,狀態欄都會顯示爲界面頭部的顏色,當然,前提是所有界面一定要設置爲充滿全屏,並且狀態欄不隱藏:方法如下:

        if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) {
            // // 全屏不隱藏狀態欄
             getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
             getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
             // 設置狀態欄透明
             getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
             getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        }

只做這些處理,當然不夠,目前的實際效果如圖所示:

這裏寫圖片描述

遇到這種情況,我們就要來想個法子了,如果還用之前的方法肯定是不行的了,因爲實現原理不同,那麼如何才能達到效果呢?我們可以用一下我們平時做佈局時的思維,只要在標題欄上部放一個控件,背景跟標題欄顏色相同,而高度爲狀態欄高度不就行了嘛?當然,所有操作都要在sdk>=4.4時進行,總的實現方法如下:

首先,依然要創建一個BaseActivity:

    @TargetApi(19)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) {
            // // 全屏不隱藏狀態欄
             getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
             getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
             // 設置狀態欄透明
             getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
             getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        }
        super.onCreate(savedInstanceState);
    }

其次,子Activity繼承:
例:

public class MainActivity extends BaseActivity

佈局xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/tv_status"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#00ccee" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#00ccee" >

        <TextView
            android:id="@+id/tv_menu"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="10dp"
            android:text="菜單"
            android:textColor="#FFFFFF"
            android:textSize="14sp" />

        <TextView
            android:id="@+id/tv_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="消息"
            android:textColor="#FFFFFF"
            android:textSize="18sp" />
    </RelativeLayout>

</LinearLayout>

注意tv_status控件就是用來設置爲狀態欄高度的。

onCreate:

    @TargetApi(19)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv_status = (TextView) findViewById(R.id.tv_status);

        if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) {
            tv_status.setHeight(getStatusHeight(this));
            tv_status.setVisibility(View.VISIBLE);
        } else {
            tv_status.setHeight(0);
            tv_status.setVisibility(View.GONE);
        }
    }

getStatusHeight方法爲計算狀態欄高度的方法:

    public int getStatusHeight(Activity activity) {
        int statusHeight = 0;
        Rect localRect = new Rect();
        activity.getWindow().getDecorView()
                .getWindowVisibleDisplayFrame(localRect);
        statusHeight = localRect.top;
        if (0 == statusHeight) {
            Class<?> localClass;
            try {
                localClass = Class.forName("com.android.internal.R$dimen");
                Object localObject = localClass.newInstance();
                int i5 = Integer.parseInt(localClass
                        .getField("status_bar_height").get(localObject)
                        .toString());
                statusHeight = activity.getResources()
                        .getDimensionPixelSize(i5);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return statusHeight;
    }

最終實現效果:

這裏寫圖片描述

當然,這只是個人的一種實現方式,如果大家有更好的實現方法,歡迎分享出來!!

發佈了101 篇原創文章 · 獲贊 492 · 訪問量 44萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章