編輯:關於Android編程
一、ToolBar
1、在build.gradle中添加依賴,例如:
compile 'com.android.support:appcompat-v7:23.4.0'
2、去掉應用的ActionBar。可以是修改主題theme為“NoActionBar”,例如:
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
或者不修改主題為"NoActionBar",而在主題的style下,添加:
<item name="windowNoTitle">true</item> <item name="windowActionBar">false</item>
第二個屬性代表是否用ActionBar代替TitleBar。
其實,剛學的時候,感覺很納悶,怎麼又多了個TitleBar?後來查了很久才發現,3.0以前,狀態欄下面的是標題欄(只能顯示標題等少量信息),3.0以後就變成了應用欄,也就是ActionBar。
另外,我測試的時候,activity是繼承於AppCompatActivity,主題是AppCompat類型的。這種情況下,必須要像上面那樣寫才有效果,少寫或值不同的話,要麼沒效果,要麼報錯。
最後,上面兩個屬性的說明可在android.R.attr這個類中查看。
3、在xml中為ToolBar添加屬性
android:fitsSystemWindows="true" android:minHeight="?attr/actionBarSize"
fitsSystemWindows是ToolBar實現沉浸式狀態欄的關鍵,其大概情況是,如果設為true,就會調整這個view去留一些空間給系統窗口,如果不設置或設為false,ToolBar就會和狀態欄重疊在一起。
而第二個屬性中,它的值全寫是"?android:attr/actionBarSize",其意思是引用當前主題中的actionBarSize這個屬性。更多相關說明可查看官方文檔中Accessing Resources的部分。
上面兩個屬性可在android.view.View這個類中查看。
4、在java中添加判斷sdk版本的代碼並在用戶的系統是4.4及以上時設置狀態欄為透明
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); }
無論是ToolBar,還是自定義導航欄,這個操作都是實現沉浸式狀態欄的關鍵。
因為設置狀態欄為透明的這個屬性,要4.4以上才能使用,所以4.4以下的系統是不能夠實現沉浸式狀態欄的。而在4.4到5.0的系統中,狀態欄是全透明的,也就是它的顏色會跟你的ToolBar和自定義導航欄的顏色一樣。而在5.0以上的系統中,則是半透明的,也就看起來會比較深暗。
而我在6.0的系統上測試時,發現這一步沒設置和設置了的,從效果上看,區別就是沒設置時狀態欄顏色淺一點,而且ToolBar的padding top為0,而設置了的顏色就深一點,padding top為狀態欄的高度。具體有什麼影響,還不清楚。但這會讓自定義導航的外觀變形,它會增加狀態欄的高度,但又沒有讓這部分與狀態欄重疊,就導致效果變形。
5、最後在java中添加
setSupportActionBar(mToolbar);
ToolBar的布局代碼:
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/tool_bar" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/colorPrimary" android:elevation="4dp" android:fitsSystemWindows="true" android:minHeight="?android:attr/actionBarSize" app:title="ToolBar" app:subtitle="toolbar"/>
效果圖(Android 6.0):
二、自定義導航欄TopBar
1、設置窗口為無標題,上面第2步中的兩個方法都可以實現,或者是在java中添加如下代碼:
requestWindowFeature(Window.FEATURE_NO_TITLE);
注意在添加這句代碼時,確保是在加載布局內容之前,也就是onCreate的setContentView之前。在《Android群英傳》“Android控件架構”,這一節中解釋了為什麼requestWindowFeature()需要在setContentView()之前。
另外,我發現如果該activity是繼承AppCompatActivity的話,只寫上面的這句代碼是沒有變化的,顯示的還是ActionBar。但如果是繼承FragmentActivity的話,就有效果,也就說上面第2步中的第二個方法,只添加其中任意一個屬性都是可以的。至於是什麼原因,我還沒弄清楚。
2、同上面第4步,判斷系統版本並按需設置狀態欄為透明
3、獲取狀態欄的高度
protected int getStatusHeight() { try { Class<?> c = Class.forName("com.android.internal.R$dimen"); // 獲得與字符串對應的Class對象 Object object = c.newInstance(); // 創建這個Class的實例對象 Field field = c.getField("status_bar_height"); // 拿到字符串對應的變量 int x = Integer.parseInt(field.get(object).toString()); // 通過這個實例對象拿到這個變量的值,再轉換類型,最後轉為整型,變為一個資源id return getResources().getDimensionPixelSize(x); } catch (Exception e) { e.printStackTrace(); } return 0; }
這部分代碼是利用Java的反射機制來實現的,因為這個internal包默認會被sdk/platforms/android-version中的android.jar給移除掉,所以無法直接調用或查看這個包中的類。如果要使用的話,可以借助這個開源項目https://github.com/anggrayudi/android-hidden-api。
4、獲取自定義TopBar的高度並修改布局參數
protected void setStatusBar() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { final ViewGroup viewGroup = (ViewGroup) findViewById(R.id.top_bar); final int statusHeight = getStatusHeight(); viewGroup.post(new Runnable() { @Override public void run() { int topBarHeight = viewGroup.getHeight(); LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) viewGroup.getLayoutParams(); layoutParams.height = statusHeight + topBarHeight; viewGroup.setLayoutParams(layoutParams); } }); } }
因為在include這個TopBar的布局文件中,其父布局是LinearLayout,而TopBar的父布局是RelativeLayout,所以這裡先要轉成ViewGroup,等getLayoutParams時,再轉成LinearLayout.LayoutParams。
TopBar的布局:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/top_bar" android:layout_width="match_parent" android:layout_height="49dp" android:background="@color/colorPrimary" android:gravity="bottom"> <RelativeLayout android:layout_width="match_parent" android:layout_height="49dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="@string/app_name" android:textSize="24sp" android:textColor="#ffffff"/> </RelativeLayout> </RelativeLayout>
因為這個布局的高度會在代碼中動態地修改,即49dp加上狀態欄的高度,所以只有一個層級的結構的話,那導航欄的內容就會往上偏。所以要嵌套多一層來維持導航欄的高度,同時在最外層的布局中,添加android:gravity="bottom"這個屬性來保證導航欄不往上偏。
效果圖(Android 6.0):
以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持本站!
Chapter1 ViewsView管理指的就是管理view的層次.而view的層次為其他許多功能提供支持, 如responder鏈.View可以從nib加載, 也可以直
天天P圖作為圖像處理類APP,內部集成了很多功能,包括濾鏡、人臉檢測、美白、磨皮、美妝、拼圖、相機等,而且這些功能多是用底層算法依靠GPU實現,如何保證這些功能在眾廠商生
logcat日志的等級劃分 等級從低到高排列verbose :冗余,最低等級。 黑色debug:調試信息 藍色info: 普通信息 綠色w
最近項目中要做一個帶進度條的上傳文件的功能,學習了AsyncTask,使用起來比較方便,將幾個方法實現就行,另外做了一個很簡單的demo,希望能對大家有幫助,在程序中設好