實現佈局為DrawLayout的狀態列全透明沉侵式效果
阿新 • • 發佈:2019-02-01
現在很多App都實現了沉侵式效果,之前我開發的一個專案用到了,使用的是SystemBarTintManager工具類,對狀態列進行顏色設定,但是發現一個問題,就是drawlayout的側邊選單滑出來後,狀態列的顏色並不會根據側滑選單的顏色變化,將activity的主題設定了
<item name="android:windowTranslucentStatus">true</item>
結果狀態列還是有一層淺色的陰影,視覺感還是不好,於是在網上找了找,最後總結了一套比較簡單又實用的方案。
首先,將activity的主題設定為
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <!--<item name="windowActionBar">false</item>--> <!--<item name="windowNoTitle">true</item>--> <!-- Customize your theme here. --> <!--actionbar顏色--> <item name="colorPrimary">@color/colorPrimary</item> <!--狀態列背景色--> <item name="colorPrimaryDark">@color/colorAccent</item> <!--各控制元件(如:check box、switch 或是 radoi) 被勾選 (checked) 或是選定 (selected) 的顏色--> <item name="colorAccent">@color/colorPrimaryDark</item> </style>
另外,需要新增一個針對API在19以上的styles
其中的<item name="android:windowTranslucentStatus">true</item>是將狀態列設為透明,但是效果還不是很理想。<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <!--<item name="windowActionBar">false</item>--> <!--<item name="windowNoTitle">true</item>--> <item name="android:windowTranslucentStatus">true</item> <!-- Customize your theme here. --> <!--actionbar顏色--> <item name="colorPrimary">@color/colorPrimary</item> <!--狀態列背景色--> <item name="colorPrimaryDark">@color/colorAccent</item> <!--各控制元件(如:check box、switch 或是 radoi) 被勾選 (checked) 或是選定 (selected) 的顏色--> <item name="colorAccent">@color/colorPrimaryDark</item> </style>
接著,粘出佈局檔案
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:context="com.chuji.nulubao.mystatusbar.MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <RelativeLayout android:id="@+id/relate" android:background="@color/colorAccent" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/tv_menu" android:text="選單" android:paddingLeft="10dp" android:gravity="center" android:layout_width="wrap_content" android:layout_height="50dp" /> <TextView android:text="標題" android:textSize="15sp" android:layout_centerHorizontal="true" android:gravity="center" android:layout_width="wrap_content" android:layout_height="50dp" /> </RelativeLayout> <FrameLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> <android.support.design.widget.NavigationView android:id="@+id/navigation_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" app:headerLayout="@layout/drawer_header" app:menu="@menu/menu_nav"/> </android.support.v4.widget.DrawerLayout>
其中,要使用NavigationView需要在build.grale裡面新增依賴compile 'com.android.support:design:26.0.0-alpha1'
效果如下
注意drawlayout的一定要設定android:fitsSystemWindows="true"這個屬性,否則還是有陰影。
navigationview的header就是一張背景圖
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="150dp"
android:background="@drawable/nav_header">
</LinearLayout>
menu部分也是抄的別人的介面,記住這個檔案是放在res/menu的目錄下
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
>
<group android:checkableBehavior="single">
<item android:title="首頁" android:id="@+id/mn_home" android:icon="@drawable/home"></item>
<item android:title="我的資訊" android:id="@+id/mn_information" android:icon="@drawable/myinformation"></item>
<item android:title="猜你喜歡" android:id="@+id/mn_guess" android:icon="@drawable/guess_like"></item>
<item android:title="電影" android:id="@+id/mn_movie" android:icon="@drawable/movie"></item>
<item android:title="音樂" android:id="@+id/mn_music" android:icon="@drawable/music"></item>
</group>
<item android:title="更多" android:id="@+id/mn_more">
<menu>
<item
android:id="@+id/mn_about"
android:icon="@drawable/about"
android:title="關於"/>
<item android:title="登出"
android:id="@+id/mn_out"
android:icon="@drawable/out">
</item>
</menu>
</item>
</menu>
最後就是MainActivity的程式碼
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.MenuItem;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
private DrawerLayout drawerLayout;
private NavigationView mNavigation;
private RelativeLayout relate;
private TextView tv_menu;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mNavigation = (NavigationView) findViewById(R.id.navigation_view);
relate = (RelativeLayout) findViewById(R.id.relate);
tv_menu = (TextView) findViewById(R.id.tv_menu);
mNavigation.setItemIconTintList(null);//讓menu的圖示顯示自己的顏色
mNavigation.setNavigationItemSelectedListener(this);//設定側滑選單item的監聽事件
relate.setPadding(0,getStatusBarHeight(),0,0);//設定padding值,防止佈局嵌入到狀態列裡面
drawerLayout.setFitsSystemWindows(false);//這一步很關鍵,必須要
tv_menu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
drawerLayout.openDrawer(Gravity.LEFT);
}
});
}
public int getStatusBarHeight() {//獲取狀態列的高度
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
int itemId = item.getItemId();
switch (itemId){
case R.id.mn_home: {
Toast.makeText(MainActivity.this,"首頁",Toast.LENGTH_SHORT).show();
break;
}
case R.id.mn_movie: {
Toast.makeText(MainActivity.this,"電影",Toast.LENGTH_SHORT).show();
break;
}
case R.id.mn_music: {
Toast.makeText(MainActivity.this,"音樂",Toast.LENGTH_SHORT).show();
break;
}
case R.id.mn_information:{
Toast.makeText(MainActivity.this,"我的資訊",Toast.LENGTH_SHORT).show();
break;
}
case R.id.mn_about:{
Toast.makeText(MainActivity.this,"關於",Toast.LENGTH_SHORT).show();
break;
}
case R.id.mn_out:{
Toast.makeText(MainActivity.this,"登出",Toast.LENGTH_SHORT).show();
break;
}
case R.id.mn_guess:{
Toast.makeText(MainActivity.this,"猜你喜歡",Toast.LENGTH_SHORT).show();
break;
}
}
drawerLayout.closeDrawer(GravityCompat.START);
return false;
}
}
裡面主要的部分已經加了註釋,另外提一下navigationview監聽器的返回值,如果為true,點選了對應item後,該item背景會變暗,表示選中狀態,為false就不是變。
所有的實現步驟就是這些,最後附上效果圖。
附上demo原始碼