Android 实现酷炫的顶部栏

原创 2016年08月31日 22:47:46

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)

源码下载

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

[Android] 自定义顶部标题栏

思路及实现步骤1.定义标题栏布局 2.自定义TitleActivity控制标题栏按钮监听 3.在TitleActivity中实现标题栏...

Android项目中自定义顶部标题栏

Android项目中自定义顶部标题栏 先来图: 思路及实现步骤 1.定义标题栏布局 2.自定义TitleActivity控制标题栏按钮监听 3.在TitleActivity中实现标题栏以下内容切换...
  • gao_chun
  • gao_chun
  • 2015年04月25日 00:46
  • 24322

TabLayout用法,android顶部导航栏,android底部导航栏

TabLayout是android.support.design里的一个控件,使用它可以很方便的做出顶部导航和底部导航。类似于这样的,能设置选中时字体的颜色和选中时的图片。 首先我们引入comp...

Android-实现顶部+底部双导航界面功能

最近想弄一个双导航功能,查看了许多资料,总算是实现了功能,这边就算是给自己几个笔记吧! 先来看看效果 那么就开始实现了!...
  • g777520
  • g777520
  • 2016年09月06日 09:24
  • 3164

教你如何使用ViewPager+Fragment一步步打造顶部导航界面滑动效果

最近在整理以前的知识点,重新碰到了以前项目中的一个滑动分页的效果,就打算写这么一篇文章分享一下ViewPager的经典使用 在许多应用中,我们常常用到这么一个效果: 可以看到,...

android网易顶部导航栏demo

随着时间的推移现在的软件要求显示的内容越来越多,所以要在小的屏幕上能够更好的显示更多的内容,首先我们会想到底部菜单栏,但是有时候想网易新闻要显示的内容太多,而且又想在主页面全部显示出来,所以有加了顶部...

Android开发笔记(二十)顶部导航栏ActionBar

标题栏ActionBar ActionBar是在Android3.0之后引入的,所以Android2.x之前的版本不能直接使用ActionBar。现在ActionBar广泛用做APP的顶部导航栏,它在...
  • aqi00
  • aqi00
  • 2015年12月16日 17:12
  • 3748

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

Android之仿今日头条顶部导航栏效果

随着时间的推移现在的软件要求显示的内容越来越多,所以要在小的屏幕上能够更好的显示更多的内容,首先我们会想到底部菜单栏,但是有时候像今日头条新闻客户端要显示的内容太多,而且又想在主界面全部显示出来,所以...

android 自定义组合控件 顶部导航栏

在软件开发过程中,经常见到,就是APP 的标题栏样式几乎都是一样的,只是文字不同而已,两边图标不同。为了减少重复代码,提高效率, 方便大家使用,我们把标题栏通过组合的方式定义成一个控件。 例下图:...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android 实现酷炫的顶部栏
举报原因:
原因补充:

(最多只允许输入30个字)