薄荷 Toolbar(ActionBar)的适配方案

发布于 2024-08-15 03:35:13 字数 5904 浏览 9 评论 0

在 Toolbar 刚出来不久,我就准备尝鲜并准备在薄荷 Android 版把 ActionBar 全部替换到 Toolbar。至于 Toolbar 的优势以及它的使用方法我这里就不一一介绍了,网上一大堆。这里经过评估发现 Toolbar 的适配有以下几个难点:

遵循各版本的 Android 设计

我们的 App 一向是尽量遵循 Android 的设计,比如顶部的导航栏,我们知道在 4.4 版本之前 Android 是不可以自定义状态栏的,在 4.4 版 本 Android 推出了一个透明状态栏的概念,使手机最顶部的状态栏的颜色全透明,并且颜色可以定义,而 5.0 推出了 Material Design,这个时候的状态栏就变成了半透明的颜色,具体可见下图。

4.4 版本

5.0 版本

而 4.4 之前版本顶部的状态栏默认是黑色的,这里就不截图了,看微信 Android 版就知道了

全局替换 ActionBar

我们知道 ActionBar 默认在是每个页面包含了,而 Toolbar 是需要你手动写一个布局然后 include 进去的,如果想要全部替换成 Toolbar,则需要改动每一个布局文件,这样改动难免太大了。

一键适配所有版本的状态栏

我们先来解决第一个问题,这里也是经过自己研究利用的一个小技巧。废话不多说,直接上代码与解决方案。

1、首先 Toolbar 是在 appcompact-v7 包下面,所以第一步需要依赖该库,方式很简单,gradle 依赖加入如下代码:

compile 'com.android.support:appcompat-v7:22.2.1'

2、之后我们创建一个 Toolbar 的布局文件 toolbar_layout.xml

<?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/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingTop="@dimen/toolbar_padding_top"
    android:background="@color/primary_color"
    android:minHeight="?attr/actionBarSize"
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

这里给它设一个 id 与你 app 的主颜色,然后关于其他属性 android:minHeight、app:theme、 app:popupTheme 等就不在解释,关键是在这里加了一个 paddingTop 的属性。看到这里可能已经有同学猜到我的解决方案了,是的解决方案 就是利用状态栏的高度,在 4.4 以上的版本给 Toolbar 设置一个 paddingTop 的属性为 status_bar 的高度,然后让他“全屏”, Toolbar 就自然的延伸到了 status_bar 的位置,而且在 4.4 系统 status_bar 默认就是透明,在 5.0 以上 status_bar 是半 透明。而至于 status_bar 的高度从源码查看得知为 25dp,不信的话大家可以通过以下代码获取像素转成 dp 试试

public int getStatusBarHeight() {  
    int result = 0;
    int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = getResources().getDimensionPixelSize(resourceId);
    }  
  return result;
}  

然后我们还需要在 values, values-v19 两个文件夹下分别声明 toolbar_padding_top 变量,values 文件夹下值为 0,而 values-v19 文件夹下值为 25.

3、最后在 values-v19 文件夹下声明 AppTheme 为透明状态栏,代码如下

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="android:windowTranslucentStatus">true</item>
</style>

这句话意为在 api 大于等于 19 以上版本为状态栏透明

以上便解决了第一个问题,那么接下来第二个问题的解决方案就是抽象成一个 BaseActivity,直接上代码相信大家就明白了。

package com.stormzhang.booheetoolbar;

import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.LinearLayout;

public class BaseActivity extends AppCompatActivity {

    private LinearLayout rootLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 这句很关键,注意是调用父类的方法
        super.setContentView(R.layout.activity_base);
        // 经测试在代码里直接声明透明状态栏更有效
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            WindowManager.LayoutParams localLayoutParams = getWindow().getAttributes();
            localLayoutParams.flags = (WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | localLayoutParams.flags);
        }
        initToolbar();
    }

    private void initToolbar() {
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        if (toolbar != null) {
            setSupportActionBar(toolbar);
        }
    }

    @Override
    public void setContentView(int layoutId) {
        setContentView(View.inflate(this, layoutId, null));
    }

    @Override
    public void setContentView(View view) {
        rootLayout = (LinearLayout) findViewById(R.id.root_layout);
        if (rootLayout == null) return;
        rootLayout.addView(view, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        initToolbar();
    }
}

而 activity_base.xml 的布局内容如下

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

    <include layout="@layout/toolbar_layout" />

</LinearLayout>

这里需要强调的是 BaseActivity 里的这段内容

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    WindowManager.LayoutParams localLayoutParams = getWindow().getAttributes();
    localLayoutParams.flags = (WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | localLayoutParams.flags);
}

其实和在主题样式里声明

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="android:windowTranslucentStatus">true</item>
</style>

是一个意思,但是实际测试中发现在国产某些 rom 上,xml 声明的会不起作用,所以建议在代码里直接声明更有效。最后每一个 Activity 或者 Fragment 只需要调用 getSupportActionBar() 方法,均和 ActionBar 的使用方法一致。最后我这边写了一个完整的 demo 放在 GitHub 供大家理解使用。

GitHub 地址: https://github.com/stormzhang/BooheeToolbar

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

七婞

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

内心激荡

文章 0 评论 0

JSmiles

文章 0 评论 0

左秋

文章 0 评论 0

迪街小绵羊

文章 0 评论 0

瞳孔里扚悲伤

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文