Toolbar作为ActionBar使用介绍本文介绍了在Android中将Toolbar作为ActionBar使用的方法. 使用support library的ToolbarAndroid的ActionBar每个版本都会做一些改变, 所以原生的ActionBar在不同的系统上看起来可能会不一样. 在Activity中使用Toolbar1.首先项目gradle中添加: compile 'com.android.support:appcompat-v7:23.4.0' 2.确保Activity继承 <application android:theme='@style/Theme.AppCompat.Light.NoActionBar' /> 4.把Toolbar写在布局中 <android.support.v7.widget.Toolbar android:id='@+id/my_toolbar' android:layout_width='match_parent' android:layout_height='?attr/actionBarSize' android:background='?attr/colorPrimary' android:elevation='4dp' android:theme='@style/ThemeOverlay.AppCompat.ActionBar' app:popupTheme='@style/ThemeOverlay.AppCompat.Light'/> 5.在Activity里面把Toolbar设置成为ActionBar public class ToolbarDemoActivity extends AppCompatActivity { @BindView(R.id.toolbar) Toolbar toolbar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_toolbar_demo); ButterKnife.bind(this); setSupportActionBar(toolbar); }} 然后就可以随意使用啦, 用getSupportActionBar可以获取ActionBar类型的对象, 从而使用ActionBar的方法. 添加Action Buttons定义menu: version='1.0' encoding='utf-8'?><menu xmlns:android='http://schemas./apk/res/android' xmlns:app='http://schemas./apk/res-auto'> <item android:id='@+id/action_android' android:icon='@drawable/ic_android_black_24dp' android:title='@string/action_android' app:showAsAction='always' /> <item android:id='@+id/action_favourite' android:icon='@drawable/ic_favorite_black_24dp' android:title='@string/action_favourite' app:showAsAction='ifRoom' /> <item android:id='@+id/action_settings' android:title='@string/action_settings' app:showAsAction='never' />menu> 然后在代码中inflate和处理它的点击事件: @Overridepublic boolean onCreateOptionsMenu(Menu menu) { Log.i(TAG, 'onCreateOptionsMenu()'); getMenuInflater().inflate(R.menu.menu_activity_main, menu); return super.onCreateOptionsMenu(menu);}@Overridepublic boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_android: Log.i(TAG, 'action android selected'); return true; case R.id.action_favourite: Log.i(TAG, 'action favourite selected'); return true; case R.id.action_settings: Log.i(TAG, 'action settings selected'); return true; default: return super.onOptionsItemSelected(item); }} 添加向上返回的action添加向上返回parent的action: @Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_toolbar_demo); ButterKnife.bind(this); setSupportActionBar(toolbar); // add a left arrow to back to parent activity, // no need to handle action selected event, this is handled by super getSupportActionBar().setDisplayHomeAsUpEnabled(true);} 然后只需要在manifest中指定parent: <activity android:name='.toolbar.ToolbarDemoActivity' android:parentActivityName='.MainActivity'>activity> 在Fragment中使用Toolbar在Fragment中使用Toolbar的步骤和Activity差不多. ((AppCompatActivity) getActivity()).setSupportActionBar(toolbar); 注意此处有一个强转, 必须是AppCompatActivity才有这个方法. setHasOptionsMenu(true); 此时Fragment的 @Overridepublic void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { Log.e(TAG, 'onCreateOptionsMenu()'); menu.clear(); inflater.inflate(R.menu.menu_parent_fragment, menu);} 即先clear()一下, 这样按钮就只有Fragment中设置的自己的了, 不会有Activity中的按钮. 在嵌套的子Fragment中使用Toolbar前面已经介绍过, Fragment可以嵌套使用: Android Fragment使用(二) 嵌套Fragments (Nested Fragments) 的使用及常见错误. setHasOptionsMenu(true)((AppCompatActivity) getActivity()).setSupportActionBar(toolbar); 然后根据是否需要菜单按钮, 覆写onCreateOptionsMenu()方法来inflate自己的menu文件即可. onCreateOptionsMenu()方法的调用一旦调用 ((AppCompatActivity) getActivity()).setSupportActionBar(toolbar); 就会导致Activity 假设当前Activity, Parent Fragment和Child Fragment中都设置了自己的Toolbar为ActionBar. 关于这个, 还有以下几种情况: - 如果Parent的`setHasOptionsMenu(false)`, Child为true, 则Parent的`onCreateOptionsMenu()`不会调用, 打开Child的时候Activity -> Child.- 如果Child的`setHasOptionsMenu(false)`, Parent为true, 则打开Child的时候仍然会调用Activity和Parent的onCreateOptionsMenu()方法.- 如果Parent和Child都置为false, 打开Parent和Child Fragment的时候都会调用Activity的onCreateOptionsMenu()方法. 仅仅是child Fragment的show() hide()的切换, activity和parent Fragment的onCreateOptionsMenu()也会重新进入. 上面的机制常常是导致Toolbar上面的按钮混淆错乱的原因. @Overridepublic void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { Log.e(TAG, 'onCreateOptionsMenu()'); menu.clear(); if (getChildFragmentManager().getBackStackEntryCount() == 0) { inflater.inflate(R.menu.menu_parent_fragment, menu); }} 另外, 除了 onOptionsItemSelected()方法的调用在Activity和其中的Fragment都有options menu的时候, 需要注意menu item的id不要重复. 有嵌套Fragment时 Back键处理之前没有嵌套Fragment的情况下, 只要将Fragment加入到Back Stack中, 那么按下Back键的时候pop动作是系统自动做好的. 在Activity中 @Overridepublic void onBackPressed() { Fragment fragment = getSupportFragmentManager().findFragmentById(android.R.id.content); if (fragment instanceof ToolbarFragment) { if (((ToolbarFragment) fragment).onBackPressed()) { return; } } super.onBackPressed();} 其中ToolbarFragment是直接加在Activity中作为parent fragment的. public boolean onBackPressed() { return getChildFragmentManager().popBackStackImmediate();} 本文Demo地址: Demo on github 参考资料Developer Android: |
|
来自: scxingm > 《Android 开发》