Android标题栏ActionBar与Toolbar

ActionBar

ActionBar和Fragment、Loader等一样,都是在Android3.0及后续版本新加的技术。那么ActionBar是什么呢,它的位置在Android3.0之前就是标题栏的位置。只是ActionBar除了可以显示标题和图标外,还可以显示动作按钮和自定义视图,因此也可以将ActionBar称为扩展标题栏。

ActionBar入门

①创建menu文件夹自定义menu文件
在这里插入图片描述
②在onCreateOptionsMenu中使用该menu文件

   @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.second, menu);
    }
ActionBar的显示和隐藏

getSupportActionBar().show()
getSupportActionBar().hide()

ActionBar的使用

实现层级式导航

在这里插入图片描述

第一步:MainActivity中添加一个按钮,点击跳转到SecondActivity
第二步:SecondActivity中编写

//判断父Activity是否为空,不为空设置导航图标显示
if (NavUtils.getParentActivityName(SecondActivity.this) != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);//设置向左导航显示
}

第三步:AndroidManifest.xml中配置
<activity android:name=".SecondActivity">
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value=".MainActivity" />
</activity>
Action Provider的使用

效果如下:生成“分享”图标并在右方显示上次操作方式
在这里插入图片描述

1.使用系统自带的ShareActionProvider(注意导包问题)

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/share"
        android:title="share"
        app:showAsAction="always"
        app:actionProviderClass="android.support.v7.widget.ShareActionProvider" />
</menu>
注意:这里使用的ShareActionProvider是v7包下的,并且注意前缀不是(android:)
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main,menu);
        MenuItem menuItem = menu.findItem(R.id.share);
        //这里使用 menuItem.getActionProvider() 程序会挂掉
        //ShareActionProvider provider = (ShareActionProvider) menuItem.getActionProvider();
        ShareActionProvider provider = (ShareActionProvider) MenuItemCompat.getActionProvider(menuItem);
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setType("text/plain");
        //设置过滤分享列表的Intent对象
        provider.setShareIntent(intent);
        return true;
    }
注意:如果程序挂掉,看看是不是导入成了错的android.widget.ShareActionProvider
import android.support.v4.view.MenuItemCompat;
import android.support.v7.widget.ShareActionProvider;//这里导入的包一定要和item中定义的ShareActionProvider导入的v7包一致

2.使用自定义ShareActionProvider

实现效果如下:点击图标时,进入设置页面。
在这里插入图片描述
①编写自定义属性的xml文件(action_provider.xml)

<?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">

    <ImageButton
        android:id="@+id/imageButton"
        android:scaleType="centerInside"
        android:src="@drawable/hao"
        android:layout_marginRight="10dp"
        //自定义背景属性
        android:background="@color/background"
        android:layout_width="40dp"
        android:layout_height="40dp" />
</LinearLayout>

②自定义MyActionProvider继承ActionProvider,两个方法必须实现:
带参数的构造方法,传入一个Context上下文对象
重写方法onCreateActionView,在其中对布局进行操作

public class MyActionProvider extends ActionProvider {
    private Context mContext;

    public MyActionProvider(Context context) {
        super(context);
        mContext = context;
    }

    @Override
    public View onCreateActionView() {
    	//加载自定义View
        View view = LayoutInflater.from(mContext).inflate(R.layout.action_provider, null);
        //通过我们的View找到我们的自定义控件并为它设置监听器
        ImageButton imageButton = view.findViewById(R.id.imageButton);
        imageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            	//通过意图打开系统设置页面
                Intent intent = new Intent(Settings.ACTION_SETTINGS);
                mContext.startActivity(intent);
            }
        });
        return view;
    }
}

③编写menu下的item(myShare.xml)

<?xml version="1.0" encoding="utf-8"?>
<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/myShare"
        android:title="share"
        app:showAsAction="always"
        //这里的引入是自定义ActionProvider的具体位置,具体到包名
        app:actionProviderClass="com.example.actionbardemo.MyActionProvider" />
</menu>

④在MainActivity中重写onCreateOptionsMenu()方法

 	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.myShare, menu);
        return super.onCreateOptionsMenu(menu);
    }
!!!敲重点!!!

1.使用getSupportActionBar时,继承的Activity要是AppCompatActivity。在API21之前我们使用标题栏基本都是在ActionBarActivity的Activity中处理的,而API21之后,谷歌遗弃了ActionBarActivity,推荐我们也可以说是强制我们使用AppCompatActivity。

解释①:Activity和AppCompatActivity的区别,AppCompatActivity默认带标题,但Activity不带;
解释②:如果需要用兼容版的fragment,则需要继承support v4提供的FragmentActivity。如果需要使用兼容版的actionbar,则继承support v7提供的ActionBarActivity(它是继承FragmentActivity的)。

2.AppCompatActivity和 requestWindowFeature(Window.FEATURE_NO_TITLE)一起使用会发生冲突,程序会直接挂掉。应该使用兼容包的方法supportRequestWindowFeature(Window.FEATURE_NO_TITLE);

Toolbar

一、简介

Android3.0之后,Google引入了ActionBar,想要统一安卓应用的导航栏样式。但是由于ActionBar难以定制,很大程度上限制了开发人员。较为常见的实现是使用普通的ViewGroup来封装自己的APP Bar,或者使用JakeWharton大神的ActionBarSherlock库。
自2014年Google I/O上Material Design横空出世后,市场上的应用又逐步趋向了样式的风格统一,support library中很快就出来了ToolBar控件,一个定制化的ViewGroup,来完善ActionBar的使用。
ToolBar是ActionBar的替代品,对于像我这样的菜鸟级Android开发者来说,对怎样使用ToolBar还是感到比较困惑,那今天就来学一下如何使用吧。

二、Toolbar的使用(android.support.v7.widget.Toolbar

先说一下大致实现的效果图
在这里插入图片描述

2.1编写布局文件(activity_main.xml)或在Activity中编写
2.1.1 xml编写
<!--novigationIcon表示最左边的图标,logo表示第二个图标,title表示大标题,subtitle表示小标题-->
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:minHeight="?attr/actionBarSize"
        app:navigationIcon="@mipmap/wechat"
        app:logo="@mipmap/ic_launcher"
        app:title="Toolbar"
        app:subtitle="subtitle"/>

设置成系统自带的样式:
解释①android:minHeight="?attr/actionBarSize":设置标题栏最小高度为ActionBar的高度。
解释②android:background="?attr/colorPrimary":设置背景颜色

对于这些colorPrimary,colorPrimaryDark(statusBarColor默认使用该颜色)不理解的同学,这里有张图,方便大家理解Android Studio下的color.xml中设置的都是些什么。
在这里插入图片描述

2.1.2 Activity中编写
public class MainActivity extends AppCompatActivity {
    private Toolbar toolbar;

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

        toolbar.setNavigationIcon(R.mipmap.wechat);
        toolbar.setLogo(R.mipmap.ic_launcher);
        toolbar.setTitle("TitleInJava");
        toolbar.setSubtitle("subtitle");
		//这里特别注意,setSupportActionBar(toolbar)一定要放在setOnMenuItemClickListener之前
		//不然无法响应点击事件
        setSupportActionBar(toolbar);
        toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem menuItem) {
                int menuItemId = menuItem.getItemId();
                switch (menuItemId) {
                    case R.id.search:
                        Toast.makeText(MainActivity.this, "search", Toast.LENGTH_SHORT).show();
                        break;
                    // ...
                }
                return true;
            }
        });
    }
 }
2.2 编写标题栏的item(两个图标和溢出菜单)------main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/search"
        android:icon="@drawable/search"
        android:title="search"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/notify"
        android:icon="@drawable/notify"
        android:title="notify"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/sheZhi"
        android:title="@string/sheZhi"
        android:icon="@mipmap/ic_launcher"
        app:showAsAction="never" />
    <item
        android:id="@+id/guanYu"
        android:title="@string/guanYu"
        android:icon="@mipmap/ic_launcher"
        app:showAsAction="never" />
</menu>

1、always:使菜单项一直显示在ToolBar上。
2、ifRoom:如果有足够的空间,这个值会使菜单项显示在ToolBar上。
3、never:使菜单项永远都不出现在ToolBar上,在溢出菜单的子项中显示。
4、withText:使菜单项和它的图标,菜单文本一起显示。

2.3 在MainActivity的onCreateOptionsMenu中调用
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return super.onCreateOptionsMenu(menu);
    }

基本配置都已完成,运行…结果你会发现
在这里插入图片描述
为什么呢?其实我们前面已经说过,AppCompatActivity是默认有标题栏的(ActionBar),你要使用Toolbar,就得替代掉原先的ActionBar。因此开始第四步…

2.4 在Theme中隐藏现有的ActionBar

方法一:在style.xml中添加以下两句

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

但是为了防止主题原因导入设置的隐藏ActionBar无效,建议再加入以下两句预防(当然也可以不添加,笔者就没有添加)

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

方法二:直接设置主题,让他本身就不带ActionBar,也就是主题样式的后缀是“.NoActionBar”。

<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">

方法三(推荐使用,最方便):在java代码中设置,由于我们默认继承的Acivity是AppCompatActivity,使用supportRequestWindowFeature(Window.FEATURE_NO_TITLE)。这里要注意,一定要在setContentView(R.layout.activity_main)之前设置。

再次运行。程序运行起来了,但是两个图标和溢出菜单呢???网上搜索很多,感觉都没有解释到点上。自己总结了一下,ToolBar实际上是一个ViewGroup,支持在其内部放入子View,我们只是让一个视图去覆盖ActionBar,但是他没能发挥ActionBar的作用,所以Google提供了替代ActionBar功能的方法setSupportActionBar(toolbar).

2.5 在MainActivity的onCreate方法中做替代工作
setSupportActionBar(toolbar);

大功告成!可是点击溢出菜单时,弹出的菜单覆盖住了标题,一点都不美观。
在这里插入图片描述

2.6 设置溢出菜单
    <style name="popupTheme" parent="Theme.AppCompat.Light">
        <item name="overlapAnchor">false</item>
    </style>

使用该主题,在activity_main中最后添加一句app:popupTheme="@style/popupTheme"

当点击overlapAnchor时,它会自动把前缀(android:)也带上。一定要去掉,不然你会发现效果出不来。
为了让溢出菜单更加美观,我们再设置一下背景和字体颜色,颜色在color.xml里,自己定义

<item name="android:background">@color/background</item>
<item name="android:textColor">@color/textColor</item>
让溢出菜单能够带上图标,比较麻烦,要对JAVA反射机制了解,这里不讲述,可以自己上网查找。直接贴出最终效果

在这里插入图片描述

扩展:设置状态栏文本居中
在自定义的Toolbar中添加TextView,然后再设置TextView居中显示。这里贴出代码

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:minHeight="?attr/actionBarSize">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:textSize="15sp"
            android:text="MyTextView"/>
</android.support.v7.widget.Toolbar>

注意:这里如果在Toolbar中定义了TextView,那么title和subtitle的设置就会失效。

猜你喜欢

转载自blog.csdn.net/qq_41751493/article/details/88931587