Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android下多彩的StatusView的實現

Android下多彩的StatusView的實現

編輯:關於Android編程

概述

本文以學習、研究和分享為主,歡迎轉載,但必須在文章頁面明顯位置給出原文連接。願與志同道合的朋友一起成長

在上一個博文 Anroid沉浸式狀態欄中提到了,畫了一個圖,這個圖簡單將我們的狀態欄分為不同的2個維度來看狀態欄。其中涉及的概念我不在贅訴,請返到Anroid沉浸式狀態欄再去認識下這幾個概念。下文中提到的上節就是Anroid沉浸式狀態欄。

圖1

實現

由於上一講提到了基本的實現方法和一些可能會用到的方法,但是沒有實際操作和演示,那我們現在就來一步步來去實現我們提到的三種狀態欄的實現過程。

全屏模式下的透明狀態欄

全屏模式下的透明狀態欄,實現的app其實我們肯定見過,如我們的啟動頁很多情況下就是全屏模式,但是這個還是和我們說的不太一樣,不過今天我們介紹的這個是狀態欄透明,但是仍然存在。

網易新聞這種才是真正的浸入式狀態欄:

但是不是我們需要的效果,這種是全屏模式時,當前頁面獲取焦點就顯示一個有一定透明度的暗色狀態欄。


我們希望的是小米天氣的這種:

內容部分可以延伸到狀態欄,且狀態欄是透明的,無背景色,也就是我們的全屏模式。

按照我們上節拿來實踐下。

public static  void setFullSreen(Activity activity){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            // 設置透明狀態欄,這樣才能讓 ContentView 向上
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

        }
}

我將一個圖片鋪滿contentView。

這個截圖是在4.4上完成的。

但是在6.0上的效果還差強人意:

這個是在我的N5手機上跑的,上面有灰色的陰影。不是完全透明,和我們的小氣天氣不太一樣,好了還是用到上節的方法:

public static  void setFullSreen(Activity activity){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = activity.getWindow();
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                    | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.TRANSPARENT);
        }else
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            // 設置透明狀態欄,這樣才能讓 ContentView 向上
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

        }
    }

這樣就可以使得狀態欄也透明了。

彩色狀態欄

可能有些人會迷惑,為什麼我們要設置彩色狀態欄,在5.0可以直接設置主題來設置的,我要告訴你的是我們希望4.4上也有彩色的狀態欄。上節我們提到了彩色狀態欄的實現方法:就是先設置為屏幕模式下的透明狀態欄,再在透明狀態欄的垂直下方放置一個和狀態欄同樣高寬的view,我們操作他這個空白view的顏色,即可實現彩色狀態欄。

好了我們貼出來我們的代碼邏輯吧:

     /**
     *設置彩色的狀態欄
     *
     * @param activity
     * @param color 狀態欄需要設置的背景顏色
     * @param statusBarAlpha 狀態欄需要設置的背景顏色的透明度
     */
    public static void setColor(Activity activity, @ColorInt int color, int statusBarAlpha){

        //先設置的全屏模式
        setFullSreen(activity);
        //在透明狀態欄的垂直下方放置一個和狀態欄同樣高寬的view
        addStatusBarBehind(activity,color,statusBarAlpha);


    }
    /**
     * 添加了一個狀態欄(實際上是個view),放在了狀態欄的垂直下方
         */
    public static void addStatusBarBehind(Activity activity, @ColorInt int color, int statusBarAlpha) {
        //獲取windowphone下的decorView
        ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
        int       count     = decorView.getChildCount();
        //判斷是否已經添加了statusBarView
        if (count > 0 && decorView.getChildAt(count - 1) instanceof StatusBarView) {
            decorView.getChildAt(count - 1).setBackgroundColor(calculateStatusColor(color, statusBarAlpha));
        } else {
            //新建一個和狀態欄高寬的view
            StatusBarView statusView = createStatusBarView(activity, color, statusBarAlpha);
            decorView.addView(statusView);
        }
        setRootView(activity);
    }

   /**
     * 設置根布局參數
     */
    private static void setRootView(Activity activity) {
        ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
        //rootview不會為狀態欄流出狀態欄空間
        ViewCompat.setFitsSystemWindows(rootView,false);
        rootView.setClipToPadding(true);
    }


    private static StatusBarView createStatusBarView(Activity activity, int color, int alpha) {
        // 繪制一個和狀態欄一樣高的矩形
        StatusBarView statusBarView = new StatusBarView(activity);
        LinearLayout.LayoutParams params =
                new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));
        statusBarView.setLayoutParams(params);
        statusBarView.setBackgroundColor(calculateStatusColor(color, alpha));
        return statusBarView;
    }

   /**
     * 獲取狀態欄高度
     *
     * @param context context
     * @return 狀態欄高度
     */
    private static int getStatusBarHeight(Context context) {
        // 獲得狀態欄高度
        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        return context.getResources().getDimensionPixelSize(resourceId);
    }
    /**
     * 計算狀態欄顏色
     *
     * @param color color值
     * @param alpha alpha值
     * @return 最終的狀態欄顏色
     */
    private static int calculateStatusColor(int color, int alpha) {
        float a = 1 - alpha / 255f;
        int red = color >> 16 & 0xff;
        int green = color >> 8 & 0xff;
        int blue = color & 0xff;
        red = (int) (red * a + 0.5);
        green = (int) (green * a + 0.5);
        blue = (int) (blue * a + 0.5);
        return 0xff << 24 | red << 16 | green << 8 | blue;
    }

其中狀態欄的view就是一個簡單的view,貼出來的這個類吧:

public class StatusBarView extends View {


    public StatusBarView(Context context, AttributeSet attrs,int style) {
        super(context, attrs,style);
    }    

    public StatusBarView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public StatusBarView(Context context) {
        super(context);
    }

}

搞定,我們就可以來動態改變狀態欄的顏色了。

calculateStatusColor 方法中的alpha是0-255的,0的時候其實是不透明的,當設置255相當於statusview背景透明,即為默認色黑色。

可用的函數是public static void setColor(Activity activity, @ColorInt int color, int statusBarAlpha)和setFullSreen

小結

Now現在這個工具類就算是OK,對於代碼的侵入基本上為零,直接拿來當工具類,不用改主題,簡單易容用。也為大家提供一個思路,這個只是實現的基本功能,一些復雜的定制的情況,可以隨機應變,自由組合使用。

實現狀態欄,無非是將4.4-5.0 和5.0+的分別實現,當然配合decorview和 ViewCompat.setFitsSystemWindows(view,boolean)使用效果更佳。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved