溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Android中關(guān)于CoordinatorLayout的一些實用布局技巧

發(fā)布時間:2020-10-16 14:23:24 來源:腳本之家 閱讀:1034 作者:cpacm 欄目:移動開發(fā)

介紹

CoordinatorLayout是一個“加強版”的 FrameLayout,它主要有兩個用途:

(1) 用作應(yīng)用的頂層布局管理器

(2) 通過為子View指定 behavior 實現(xiàn)自定義的交互行為。

在我們做 Material Design 風格的app時通常都使用 CoordinatorLayout 作為布局的根節(jié)點,以便實現(xiàn)特定的UI交互行為。
那么現(xiàn)在我們來看看如何用已有的一些控件實現(xiàn)一些常見的布局。

Toolbar + TabLayout 實現(xiàn) TabLayout 置頂效果

很常見的一種模式是 TabLayout 放在 ToolBar 布局中與其一起置頂在界面上方,而現(xiàn)在的效果是將ToolBar 隱藏而 TabLayout一直置頂在界面上方。

Android中關(guān)于CoordinatorLayout的一些實用布局技巧
tablayout

如何實現(xiàn)呢?首先所在的 Activity 要使用 AppTheme.NoActionBar 風格主題,之后再編寫布局文件。

<android.support.design.widget.CoordinatorLayout
 android:layout_width="match_parent"
 android:layout_height="match_parent">

 <android.support.design.widget.AppBarLayout
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:theme="@style/AppTheme.AppBarOverlay">

 <android.support.v7.widget.Toolbar
  android:id="@+id/toolbar"
  android:layout_width="match_parent"
  android:layout_height="?attr/actionBarSize"
  android:background="?attr/colorPrimary"
  app:layout_scrollFlags="scroll|enterAlways|snap"
  app:popupTheme="@style/AppTheme.PopupOverlay">

  <!-- toolbar內(nèi)部布局文件 -->

 </android.support.v7.widget.Toolbar>

 <android.support.design.widget.TabLayout
  android:id="@+id/tab_layout"
  android:layout_width="match_parent"
  android:layout_height="@dimen/tab_height"
  app:tabIndicatorColor="@color/white"
  app:tabTextColor="@color/white_normal">

 </android.support.design.widget.TabLayout>


 </android.support.design.widget.AppBarLayout>

 <!-- 主界面布局文件 -->

</android.support.design.widget.CoordinatorLayout>

很重要的兩點:

  • 設(shè)置 Toolbar 的 layout_scrollFlags="scroll|enterAlways|snap" 保證 Toolbar 能隨界面滑動向上隱藏。
  • TabLayout 與 Toolbar 同級,父節(jié)點為 AppBarLayout ,保證 TabLayout 能夠能夠顯示在 Toolbar 外面而不隨其一起隱藏。

浸入式 + CollapsingToolbarLayout

CollapsingToolbarLayout 可以包裹 Toolbar , 當其顯示完收縮動畫時使 Toolbar 顯示在頂端。而我們可以再加入浸入式的效果讓 CollapsingToolbarLayout 的背景圖突破系統(tǒng)的狀態(tài)欄使界面更加美觀同時也不影響 Toolbar 的顯示效果。

Android中關(guān)于CoordinatorLayout的一些實用布局技巧
浸入式布局

在實現(xiàn)布局文件前要賦予當前的Activity主題為AppTheme.Immersive。

其樣式要在 v19 與 v21 分別處理,至于v19之前的 android 版本那就無能為力了。

v19

<style name="AppTheme.Immersive" parent="AppTheme.NoActionBar">
 <item name="android:windowTranslucentStatus">true</item>
</style>

v21

<style name="AppTheme.Immersive" parent="AppTheme.NoActionBar">
 <!--透明導航欄-->
 <item name="android:statusBarColor">@android:color/transparent</item>
 <item name="android:windowDrawsSystemBarBackgrounds">true</item>
</style>

之后再來看布局文件,包括了 AppBarLayout,CollapsingToolbarLayout 和 Toolbar 這些控件。

同樣也是要分為 v19 和 v21 兩種布局

v19

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent">

 <android.support.design.widget.AppBarLayout
  android:id="@+id/app_bar"
  android:layout_width="match_parent"
  android:layout_height="220dp"
  android:theme="@style/AppTheme.AppBarOverlay">

  <android.support.design.widget.CollapsingToolbarLayout
   android:id="@+id/collapsing_layout"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   app:contentScrim="?attr/colorPrimary"
   app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
   app:statusBarScrim="@android:color/transparent"
   app:titleEnabled="false">

   <RelativeLayout
    android:id="@+id/anime_root"
    android:layout_width="match_parent"
    android:layout_height="220dp"
    app:layout_collapseMode="parallax"
    app:layout_collapseParallaxMultiplier="0.7">

    <!-- 可伸縮背景圖布局文件 -->

   </RelativeLayout>

   <android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:layout_marginTop="25dp"
    app:layout_collapseMode="pin"
    app:popupTheme="@style/AppTheme.PopupOverlay"
    app:titleMarginTop="15dp" />

  </android.support.design.widget.CollapsingToolbarLayout>

 </android.support.design.widget.AppBarLayout>

 <!-- 界面布局文件 -->

</android.support.design.widget.CoordinatorLayout>

v21

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:fitsSystemWindows="true">

 <android.support.design.widget.AppBarLayout
  android:id="@+id/app_bar"
  android:layout_width="match_parent"
  android:layout_height="220dp"
  android:fitsSystemWindows="true"
  android:theme="@style/AppTheme.AppBarOverlay">

  <android.support.design.widget.CollapsingToolbarLayout
   android:id="@+id/collapsing_layout"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:fitsSystemWindows="true"
   app:contentScrim="?attr/colorPrimary"
   app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
   app:statusBarScrim="@android:color/transparent"
   app:titleEnabled="false">

   <RelativeLayout
    android:id="@+id/anime_root"
    android:layout_width="match_parent"
    android:layout_height="220dp"
    android:fitsSystemWindows="true"
    app:layout_collapseMode="parallax"
    app:layout_collapseParallaxMultiplier="0.7">

    <!-- 可伸縮背景圖布局文件 -->

   </RelativeLayout>

   <android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    app:layout_collapseMode="pin"
    app:popupTheme="@style/AppTheme.PopupOverlay"
    app:titleMarginTop="15dp" />

  </android.support.design.widget.CollapsingToolbarLayout>

 </android.support.design.widget.AppBarLayout>

 <!-- 界面布局文件 -->

</android.support.design.widget.CoordinatorLayout>

那么重點在哪里呢?

  • 設(shè)置你當前的 Activity 的狀態(tài)欄為透明,4.4之前的機型則無法適配。
  • 注意每個控件下的 fitsSystemWindows 屬性,使系統(tǒng)能夠調(diào)整 view 的 padding 值使其適配。
  • 設(shè)置 CollapsingToolbarLayout 為可滾動(scroll),滾動結(jié)束后可以設(shè)置 statusBarScrim 作為覆蓋色。
  • 背景布局與 Toolbar 同級,布局文件上可以設(shè)置滾動的模式,如視差滾動及相應(yīng)的值。
  • 注意到 v19 的布局文件上的 Toolbar ,給它賦予了一個 android:layout_marginTop="25dp"的屬性,以便在Android 4.4上時防止被系統(tǒng)的狀態(tài)欄所覆蓋。當然這個值可以在代碼中獲取到系統(tǒng)狀態(tài)欄高度再進行設(shè)置。

fitsSystemWindows詳解:這個一個boolean值的內(nèi)部屬性,讓view可以根據(jù)系統(tǒng)窗口(如status bar)來調(diào)整自己的布局,如果值為true,就會調(diào)整view的paingding屬性來給system windows留出空間。

Fragment + 不同風格布局

有時候產(chǎn)品要求在一個 Activity 上顯示不同的 Fragment 界面,且 Fragment 上的每一個頭部樣式都不一樣,比如說一個是普通情況下的 Toolbar,另一個卻是浸入式的可伸縮頭部,像簡書app的首頁

Android中關(guān)于CoordinatorLayout的一些實用布局技巧

額,我們先不提圖中的那個bug,圖中的界面主要是兩種效果,一個為普通的標題欄+正文,另一個則是浸入式的圖片背景+正文。我們也可以利用浸入式的主題來仿照出簡書的效果。

Android中關(guān)于CoordinatorLayout的一些實用布局技巧
各個頁面不同樣式

第一步要做的是給 Fragment 所在的 Activity 套上 AppTheme.Immersive 浸入式主題樣式,之后為 Activity 加上布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 android:layout_width="match_parent"
 android:layout_height="match_parent">

 <com.ashokvarma.bottomnavigation.BottomNavigationBar
  android:id="@+id/bottom_navigation_bar"
  android:layout_width="match_parent"
  android:layout_height="56dp"
  android:layout_gravity="bottom"
  android:fitsSystemWindows="true">

 </com.ashokvarma.bottomnavigation.BottomNavigationBar>

 <android.support.v4.view.ViewPager
  android:id="@+id/viewpager"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:layout_marginBottom="56dp" />

</android.support.design.widget.CoordinatorLayout>

無他,就是一個 ViewPager 容器用來加載 Fragment。

書城所在的 Fragment 布局如下:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:fitsSystemWindows="true">

 <android.support.design.widget.AppBarLayout
  android:id="@+id/app_bar"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:fitsSystemWindows="true"
  android:theme="@style/AppTheme.AppBarOverlay">

  <android.support.design.widget.CollapsingToolbarLayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:fitsSystemWindows="true"
   app:contentScrim="?attr/colorPrimary"
   app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
   app:statusBarScrim="@android:color/transparent"
   app:titleEnabled="false">

   <!-- 背景布局 -->

   <android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="36dp"
    android:minHeight="36dp"
    app:layout_collapseMode="pin"
    app:popupTheme="@style/AppTheme.PopupOverlay">
    <!-- 搜索框布局 -->

   </android.support.v7.widget.Toolbar>

  </android.support.design.widget.CollapsingToolbarLayout>

 </android.support.design.widget.AppBarLayout>

 <!-- 界面主布局 -->

</android.support.design.widget.CoordinatorLayout>

布局跟之前的浸入式布局相同,但單單這樣布局是有問題的,此時的 Toolbar 會顯示在系統(tǒng)的狀態(tài)欄下。所以我們要修正 Toolbar 的擺放位置,即人為的為其設(shè)置 MarginTop 距離。

/**
 * 修正 Toolbar 的位置
 * 在 Android 4.4 版本下無法顯示內(nèi)容在 StatusBar 下,所以無需修正 Toolbar 的位置
 *
 * @param toolbar
 */
protected void fixToolbar(Toolbar toolbar) {
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  int statusHeight = getStatusBarHeight(getActivity());
  ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams();
  layoutParams.setMargins(0, statusHeight, 0, 0);
 }
}

/**
 * 獲取系統(tǒng)狀態(tài)欄高度
 *
 * @param context
 * @return
 */
public int getStatusBarHeight(Context context) {
 Class<?> c = null;
 Object obj = null;
 Field field = null;
 int x = 0, statusBarHeight = 0;
 try {
  c = Class.forName("com.android.internal.R$dimen");
  obj = c.newInstance();
  field = c.getField("status_bar_height");
  x = Integer.parseInt(field.get(obj).toString());
  statusBarHeight = context.getResources().getDimensionPixelSize(x);
 } catch (Exception e1) {
  e1.printStackTrace();
 }
 return statusBarHeight;
}

在每個 Fragment 初始化 Toolbar 時都需要調(diào)用這個方法來修正位置。

重點又來了:

  • 修改為浸入式樣式主題,要點見上一個案例。
  • 人為修正 Toolbar 的距離,保證位置擺放正確。
  • 注意 Fragment 切換時偶爾出現(xiàn)的一些 Toolbar 問題。

Fragment 與 Toolbar 的選項菜單問題

在 Fragment 之間切換的時候很容易遇到 Toolbar 上的菜單無法正確的顯示的問題,解決方法也很簡單,在 Fragment 的 onCreateView() 方法中添加一行代碼:

toolbar.setTitle("title");
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
fixToolbar(toolbar);
setHasOptionsMenu(true); //重要的一行代碼,防止選項菜單錯亂

總結(jié)

自從 Google 出了 com.android.support:design 包之后,其多樣化的定制給 App 應(yīng)用帶來更加酷炫的效果,布局的變化只不過是其中的一部分而已。文章的開頭也說了, CoordinatorLayout 不止是帶來了布局的變化,也帶給了控件更多的UI交互動作。

好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對億速云的支持。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI