上一节http://www.jianshu.com/p/bf40b1c1d2cf 分析状态栏之后,我们要开始加上toolbar
先给布局的xml
<pre>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="8dp"
app:contentInsetLeft="@dimen/second_keyline_default"
app:contentInsetStart="@dimen/second_keyline_default"
app:popupTheme="?attr/actionBarPopupTheme"
app:theme="?attr/actionBarTheme">
<Spinner
android:id="@+id/stack"
style="@style/PopupTheme"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:layout_marginStart="4dp"
android:overlapAnchor="true" />
</android.support.v7.widget.Toolbar>
</pre>
在我们activity中 我们要怎么去处理呢?
第一步 还是先考虑版本
<pre>
mToolbar = (Toolbar) findViewById(R.id.toolbar);
mToolbar.setTitleTextAppearance(context, R.style.TextAppearance_AppCompat_Widget_ActionBar_Title);
这是设置了字体
if(Utils.hasKitKat() && !Utils.hasLollipop()) {
((LinearLayout.LayoutParams) mToolbar.getLayoutParams()).setMargins(0, getStatusBarHeight(this), 0, 0);
mToolbar.setPadding(0, getStatusBarHeight(this), 0, 0);
在4.4之上5.0以下的时候 我们设置的mToolbar 的值。
}
</pre>
为什么?
4.4是状态栏透明处理。然后去填充。所以我们要设置值
5.0 为什么不用去管? 因为我们是直接设置的颜色
<pre>
int color = Utils.getStatusBarColor(SettingsActivity.getPrimaryColor(this));
if(Utils.hasLollipop()){
getWindow().setStatusBarColor(color);
}
else if(Utils.hasKitKat()){
SystemBarTintManager systemBarTintManager = new SystemBarTintManager(this);
systemBarTintManager.setTintColor(color);
systemBarTintManager.setStatusBarTintEnabled(true);
}
</pre>
上面是设置状态栏的颜色
在最后别忘记
setSupportActionBar(mToolbar);
int color = SettingsActivity.getPrimaryColor(this);
Drawable colorDrawable = new ColorDrawable(color);
getSupportActionBar().setBackgroundDrawable(colorDrawable);
这是给toolbar设置颜色。
这样就能保持一个颜色的统一。到这里基本上就介绍完了
下面开始了解toolbar的功能方面
菜单的显示 一共有两个方法
1onCreateOptionsMenu
此方法用于初始化菜单,其中menu参数就是即将要显示的Menu实例。
返回true则显示该menu,false 则不显示; (只会在第一次初始化菜单时调用)
2onPrepareOptionsMenu
在onCreateOptionsMenu执行后,菜单被显示前调用;如果菜单已经被创建,则在菜单显示前被调用。
同样的, 返回true则显示该menu,false 则不显示;
(可以通过此方法动态的改变菜单的状态,比如加载不同的菜单等)
不重要的方法
3.public void onOptionsMenuClosed(Menu menu)
每次菜单被关闭时调用.
(菜单被关闭有三种情形,menu按钮被再次点击、back按钮被点击或者用户选择了某一个菜单项)
点击事件的方法
4onOptionsItemSelected
<pre>
@Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch(item.getItemId())//得到被点击的item的itemId
{
case R.id.menu_setting://这里的Id就是布局文件中定义的Id,在用R.id.XXX的方法获取出来
break;
case R.id.menu_info:
break;
}
return true;
}
</pre>
添加菜单
<pre>
2.1代码添加:
menu.add((int groupId, int itemId, int order, charsequence title) .setIcon(drawable ID)
add()方法的四个参数,依次是:
1、组别,如果不分组的话就写Menu.NONE,
2、Id,这个很重要,Android根据这个Id来确定不同的菜单
3、顺序,哪个菜单项在前面由这个参数的大小决定
4、文本,菜单项的显示文本
add()方法返回的是MenuItem对象,调用其setIcon()方法,为相应MenuItem设置Icon
示例:
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(Menu.NONE, Menu.First+1, 0, "设置").setIcon(R.drawable.setting);
return true;
}
</pre>
除了这个之外 还需要了解一个方法
supportInvalidateOptionsMenu
通知系统刷新菜单,系统会回调onPrepareOptionsMenu 方法,在这里面根据自己的逻辑,进行菜单的处理。这是网上的解释。 但是 我去实验。onCreateOptionsMenu
onPrepareOptionsMenu都会去从新调用! 并且原来的语句本来就有逻辑问题。大家想一下。除了第一次点击菜单调用onCreateOptionsMenu。以后每次都会调用onPrepareOptionsMenu。这样supportInvalidateOptionsMenu方法只是刷新的作用? 让我们来看看 源码
看到了把 这个方法调用之后 onCreateOptionsMenu
onPrepareOptionsMenu 都会从新调用。
下面开始写我们这个布局
<pre>
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.activity, menu);
</pre>
<pre>
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:support="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_create_file"
android:icon="@drawable/ic_menu_new_file"
support:showAsAction="always"
android:title="@string/menu_create_file"
android:visible="false"/>
<item
android:id="@+id/menu_create_dir"
android:icon="@drawable/ic_menu_new_folder"
support:showAsAction="always"
android:title="@string/menu_create_dir"
android:visible="false"/>
<item
android:id="@+id/menu_search"
support:actionViewClass="android.support.v7.widget.SearchView"
android:icon="@drawable/abc_ic_search_api_material"
support:showAsAction="ifRoom|collapseActionView"
android:title="@string/menu_search"
android:visible="false"/>
<item
android:id="@+id/menu_list"
android:icon="@drawable/ic_menu_view_list"
support:showAsAction="ifRoom"
android:title="@string/menu_list"
android:visible="false"/>
<item
android:id="@+id/menu_grid"
android:icon="@drawable/ic_menu_view_grid"
support:showAsAction="ifRoom"
android:title="@string/menu_grid"
android:visible="false"/>
<item
android:id="@+id/menu_sort"
android:icon="@drawable/ic_menu_sortby"
support:showAsAction="ifRoom"
android:title="@string/menu_sort"
android:visible="false">
<menu>
<item
android:id="@+id/menu_sort_name"
android:title="@string/sort_name"/>
<item
android:id="@+id/menu_sort_date"
android:title="@string/sort_date"/>
<item
android:id="@+id/menu_sort_size"
android:title="@string/sort_size"/>
</menu>
</item>
<item
android:id="@+id/menu_settings"
android:icon="@drawable/ic_menu_settings"
support:showAsAction="never"
android:title="@string/menu_settings"/>
<item
android:id="@+id/menu_about"
android:icon="@drawable/ic_dialog_info"
support:showAsAction="never"
android:title="About"/>
<item
android:id="@+id/menu_exit"
support:showAsAction="never"
android:title="Exit"/>
</menu>
android:visible="false" 这个作用是不显示
</pre>
效果图
超过三个选项之后 都是变成下拉
另外 我啰嗦一句supportInvalidateOptionsMenu作用。
大家 考虑过这么一种画面 在一个activity中。 你有一个侧滑菜单。 当你点击一个选项的时候 你bar菜单是变化的。 哈哈。 相信大家想到了吧。 这个方法 最大的作用是在这里。 当然还有很多作用。 比如有数据更新的时候 也是要调用这个的。 好了 下面继续。
附送一个完整的 方法
<pre>
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.activity, menu);
final MenuItem searchMenu = menu.findItem(R.id.menu_search);
//文本框输入事件
mSearchView = (SearchView) MenuItemCompat.getActionView(searchMenu);
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
//输入完成后,点击回车或是完成键
public boolean onQueryTextSubmit(String query) {
mSearchExpanded = mSearchResultShown = true;
mState.currentSearch = query;
mSearchView.clearFocus();
onCurrentDirectoryChanged(ANIM_NONE);
Bundle params = new Bundle();
params.putString("query", query);
AnalyticsManager.logEvent("search", getCurrentRoot(), params);
//添加下面一句,防止数据两次加载
searchView.setIconified(true);
return true;
}
//查询文本框有变化时事件
@Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
MenuItemCompat.setOnActionExpandListener(searchMenu, new MenuItemCompat.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
mSearchExpanded = true;
updateActionBar();
return true;
}
//TODO 添加关闭事件
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
mSearchExpanded = mSearchResultShown = false;
if (mIgnoreNextCollapse) {
mIgnoreNextCollapse = false;
updateActionBar();
return true;
}
mState.currentSearch = null;
onCurrentDirectoryChanged(ANIM_NONE);
return true;
重要的事情说三遍 三遍 三遍 这个响应事件 你想成功 那么onMenuItemActionCollapse 返回值true
}
});
//TODO 添加关闭事件
mSearchView.setOnCloseListener(new SearchView.OnCloseListener() {
@Override
public boolean onClose() {
mSearchExpanded = mSearchResultShown = false;
if (mIgnoreNextClose) {
mIgnoreNextClose = false;
updateActionBar();
return false;
}
mState.currentSearch = null;
onCurrentDirectoryChanged(ANIM_NONE);
return false;
}
});
return true;
}
</pre>
searchView.setIconified(true); 作用。原来是search键,在按下和松开时,分别运行了,action_down和 action_up两个方法,这两方法又都运行了这个查询事件,这怎么办呢,我们知道,如果查询框为空的话,它不会运行,所以我们在运行我们的代码之后加上
invalidateMenu 好了 暂时到这里 我们明天继续完善