上一篇:沉浸式狀態欄(一)
話說上一篇沉浸式狀態欄的實現方法基本可以適用於絕大部分設備,普通項目用足夠了,但是看到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;
}
最終實現效果:
當然,這只是個人的一種實現方式,如果大家有更好的實現方法,歡迎分享出來!!