Android 實現酷炫的頂部欄

AppBarLayout 是繼承LinerLayout實現的一個ViewGroup容器組件,它是爲了Material Design設計的App Bar,支持手勢滑動操作的,不過經常與Toolbar、CoordinatorLayout以及CollapsingToolbarLayout等一起配合使用,在說到AppBarLayout之前,我們先簡單學習一下Toolbar。和往常一樣,主要還是想總結一下我在學習過程中的一些筆記以及一些需要注意的地方。
一、Toolbar
Toolbar是在 Android 5.0 開始推出的一個 Material Design 風格的導航控件 ,Google 非常推薦大家使用 Toolbar 來作爲Android客戶端的導航欄,以此來取代之前的 Actionbar,也就是說,ActionBar能做的,Toolbar都能做 。與 Actionbar 相比, Toolbar 要靈活的多。它不像 Actionbar 一樣,一定要固定在Activity的頂部,而是可以放到界面的任意位置。除此之外,在設計 Toolbar 的時候,Google也留給我們很多可以修改的餘地

  • 設置導航欄圖標
  • 設置App的logo
  • 設置標題和子標題
  • 添加一個或多個的自定義控件
  • 設置Action Menu

爲了容易理解,我們先看看效果圖:
這裏寫圖片描述
按照效果圖,從左到右分別是導航欄圖標 、App的logo 、 標題和子標題 、 自定義控件(一個TextView和ImageView) 以及 ActionMenu

1、用Toolbar的時候,首先要隱藏原本的ActionBar
(1)通過在我們的styles.xml文件中的AppTheme標籤中設置以下屬性:

<item name="windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>

(2)通過修改我們繼承的主題爲:Theme.AppCompat.Light.NoActionBar

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">@color/blue</item>
        <item name="colorPrimaryDark">@color/blue_dark</item>
        <item name="colorAccent">@color/red</item>
        <item name="textAllCaps">false</item>
    </style>

(3)在Activity中調用下面這句,去掉了默認的導航欄

supportRequestWindowFeature(Window.FEATURE_NO_TITLE);

2、在佈局文件中添加我們需要的Toolbar控件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?android:actionBarSize"
        android:background="?attr/colorPrimary">
        <!--自定義控件-->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="點擊" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="2dp"
            android:src="@mipmap/icon" />
    </android.support.v7.widget.Toolbar>
</LinearLayout>

3、接着在 menu_main.xml 中添加 action menu 菜單項

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/add"
        android:icon="@mipmap/icon_add"
        app:showAsAction="always" />
    <item
        android:id="@+id/add_friend"
        android:title="添加朋友"
        app:showAsAction="never" />
    <item
        android:id="@+id/scace"
        android:title="掃一掃"
        app:showAsAction="never" />
</menu>

4、在Activity 中初始化Toolbar 控件,並設置相對應的屬性

package per.lijuan.appbarlayoutdome;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
import android.widget.Toast;

/**
 * Created by lijuan on 2016/8/31.
 */
public class Activity extends AppCompatActivity {
    private Toolbar toolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_second);
        toolbar = (Toolbar) findViewById(R.id.toolbar);

        /**
         * 設置標題
         */
        toolbar.setTitle("標題");
        /**
         * 設置子標題
         */
        toolbar.setSubtitle("子標題");
        /**
         * 設置App的logo
         */
        toolbar.setLogo(R.mipmap.ic_launcher);
        /**
         * 設置導航按鈕
         */
        toolbar.setNavigationIcon(R.mipmap.back);
        setSupportActionBar(toolbar);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    /**
     * 設定菜單各按鈕的動作
     *
     * @return
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                finish();
                break;
            case R.id.add:
                Toast.makeText(SecondActivity.this, "添加", Toast.LENGTH_SHORT).show();
                break;
            case R.id.add_friend:
                Toast.makeText(SecondActivity.this, "添加朋友", Toast.LENGTH_SHORT).show();
                break;
            case R.id.scace:
                Toast.makeText(SecondActivity.this, "掃一掃", Toast.LENGTH_SHORT).show();
                break;
            default:
                break;
        }
        return super.onOptionsItemSelected(item);
    }
}

二、CollapsingToolbarLayout
CollapsingToolbarLayout作用是提供了一個可以摺疊的Toolbar,它繼承至FrameLayout,給它設置layout_scrollFlags,它可以控制包含在CollapsingToolbarLayout中的控件(如:ImageView、Toolbar)在響應layout_behavior事件時作出相應的scrollFlags滾動事件(移除屏幕或固定在屏幕頂端)

三、AppBarLayout
我們來看看最終的效果圖:
這裏寫圖片描述
從效果圖來看,當設置了layout_behavior的控件響應起了CollapsingToolbarLayout中的layout_scrollFlags事件時,ImageView會有視差效果的向上滾動移除屏幕,當開始摺疊時,CollapsingToolbarLayout的背景色(也就是Toolbar的背景色)就會變爲我們設置好的背景色,Toolbar也一直會固定在最頂端

activity_main.xml

<?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.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:contentScrim="#3F51B5"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:adjustViewBounds="true"
                android:src="@mipmap/icon_bg"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.5" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="56dp"
                app:layout_collapseMode="pin"
                app:title="@string/app_name"
                app:titleTextColor="#FFFFFF" />

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

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

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

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

(1)我們在CollapsingToolbarLayout中設置了一個ImageView和一個Toolbar,並將這個CollapsingToolbarLayout作爲一個整體放在AppBarLayout中
(2)在CollapsingToolbarLayout中,我們設置了app:layout_scrollFlags="scroll|enterAlwaysCollapsed",它的值還包括:

  • scroll - 想滾動就必須設置這個,也就是說值設爲scroll的View會跟隨滾動事件一起滾動
    • enterAlways - 值設爲enterAlways的View,當RecyclerView往下滾動時,該View會直接往下滾動(效果圖和設爲enterAlwaysCollapsed有點相似)
    • exitUntilCollapsed - 值設爲exitUntilCollapsed的View,當這個View要往上逐漸“消逝”時,會一直往上滑動,直到剩下的的高度達到它的最小高度後,再響應RecyclerView的內部滑動事件。(說的那麼官方,我自己都有點蒙了,我們看下效果圖好了)
      這裏寫圖片描述
    • enterAlwaysCollapsed - 當值設爲enterAlwaysCollapsed 的View已經設置minHeight屬性又使用此標誌時,這個View只能以最小高度進入,只有當滾動視圖到達頂部時才擴大到完整高度(看下效果圖好了)
      這裏寫圖片描述

另外app:contentScrim="#3F51B5"是指當完全CollapsingToolbarLayout摺疊(收縮)後的背景顏色

(3)在ImageView控件中,我們設置了app:layout_collapseMode="parallax",layout_collapseMode (摺疊模式) - 有兩個值:

  • pin - 設置爲這個模式時,當CollapsingToolbarLayout完全收縮後,Toolbar還可以保留在屏幕上
  • parallax - 設置爲這個模式時,在內容滾動時,CollapsingToolbarLayout中的View(比如ImageView)也可以同時滾動,實現視差滾動效果,通常和layout_collapseParallaxMultiplier(設置視差因子)搭配使用

另外app:layout_collapseParallaxMultiplier="0.5"設置視差滾動因子,值爲:0~1

(4)在Toolbar控件中,我們設置了layout_collapseMode(摺疊模式):爲pin

MainActivity.class

package com.per.appbarlayout;

import android.graphics.Color;
import android.os.Bundle;
import android.support.design.widget.CollapsingToolbarLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    public Toolbar mToolbar;
    private RecyclerView mRecyclerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        mToolbar.setTitleTextColor(Color.GREEN);
        mToolbar.setTitle("AppBarLayout");
        setSupportActionBar(mToolbar);

        getSupportActionBar().setHomeButtonEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mRecyclerView.setAdapter(new ContentAdapter());

        CollapsingToolbarLayout mCollapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar_layout);
        //通過CollapsingToolbarLayout設置title
        mCollapsingToolbarLayout.setTitle("AppBarLayout");
        //通過CollapsingToolbarLayout修改字體顏色
        mCollapsingToolbarLayout.setExpandedTitleColor(Color.WHITE);//設置還沒收縮時狀態下字體顏色
        mCollapsingToolbarLayout.setCollapsedTitleTextColor(Color.RED);//設置收縮後Toolbar上字體的顏色
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                finish();
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    private class ContentAdapter extends RecyclerView.Adapter<ContentAdapter.ContentHolder> {
        @Override
        public ContentAdapter.ContentHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            return new ContentHolder(LayoutInflater.from(MainActivity.this).inflate(android.R.layout.simple_list_item_1, parent, false));
        }

        @Override
        public void onBindViewHolder(ContentAdapter.ContentHolder holder, int position) {
            holder.itemTv.setText("item");
        }

        @Override
        public int getItemCount() {
            return 35;
        }

        class ContentHolder extends RecyclerView.ViewHolder {

            private TextView itemTv;

            public ContentHolder(View itemView) {
                super(itemView);
                itemTv = (TextView) itemView.findViewById(android.R.id.text1);
            }
        }
    }
}

好了,本篇文章就這樣啦,存在總結不到位的地方還望指導,感謝^_^

參考資料:

玩轉AppBarLayout,更酷炫的頂部欄
Android5.0+(CollapsingToolbarLayout)

源碼下載

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章