最近一直在研究Android ActionBar和Fragment,参看Google的官方文档和网上一些demo源代码,记录一下主要的知识点,也跟大家分享一下!
具体内容请参看链接:http://developer.android.com/guide/topics/ui/actionbar.html
一、添加Action Items
在Activity或者Fragment 的 onCreateOptionsMenu方法中加载我们的menu布局文件,menu item的响应事件在 onOptionsItemSelected中进行处理。代码如下:
package com.example.example;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import com.example.android_bottomactionbar.R;
public class OverflowActionBarActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_overflow);
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.overflow_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in action bar clicked; go home
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
其中 overflow_menu.xml 布局文件如下:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/top_menu_add"
android:icon="@android:drawable/ic_menu_add"
android:showAsAction="always"
android:title="@string/menu_add"/>
<item
android:id="@+id/top_menu_save"
android:icon="@android:drawable/ic_menu_save"
android:showAsAction="always"
android:title="@string/menu_save"/>
<item
android:id="@+id/top_menu_refresh"
android:title="@string/menu_refresh"/>
<item
android:id="@+id/top_menu_share"
android:icon="@android:drawable/ic_menu_delete"
android:title="@string/menu_share"/>
<item
android:id="@+id/top_menu_delete"
android:icon="@android:drawable/ic_menu_delete"
android:title="@string/menu_delete"/>
</menu>
二、split Action Bar
package com.example.example;
import com.example.android_bottomactionbar.R;
import android.os.Bundle;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public class SplitActionBarActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_split_actionbar);
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.bottom_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in action bar clicked; go home
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
case R.id.menu_add:
Toast.makeText(getApplicationContext(), "点击了 add", 0).show();
return true;
case R.id.menu_save:
Toast.makeText(getApplicationContext(), "点击了 save", 0).show();
return true;
case R.id.menu_delete:
Toast.makeText(getApplicationContext(), "点击了 delete", 0).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
bottom_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/menu_add"
android:icon="@android:drawable/ic_menu_add"
android:showAsAction="ifRoom|withText"
android:title="@string/menu_add"/>
<item
android:id="@+id/menu_save"
android:icon="@android:drawable/ic_menu_save"
android:showAsAction="ifRoom|withText"
android:title="@string/menu_save"/>
<item
android:id="@+id/menu_delete"
android:icon="@android:drawable/ic_menu_delete"
android:showAsAction="ifRoom|withText"
android:title="@string/menu_delete"/>
</menu>
我们需要在Manifest清单文件中Activity添加 android:uiOptions="splitActionBarWhenNarrow" 属性
<activity
android:name="com.example.example.SplitActionBarActivity"
android:label="@string/app_name" android:uiOptions="splitActionBarWhenNarrow">
</activity>
三、添加 Action View
package com.example.example;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.SearchView;
import com.example.android_bottomactionbar.R;
public class SearchViewActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_searchview);
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.actionview_menu, menu);
SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
// Configure the search info and add any event listeners
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in action bar clicked; go home
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
actionview_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/menu_search"
android:title="@string/menu_search"
android:icon="@android:drawable/ic_menu_search"
android:showAsAction="ifRoom|collapseActionView"
android:actionViewClass="android.widget.SearchView" />
</menu>
四、添加 Action Provider
1、使用系统提供的ShareActionProvider
package com.example.example;
import com.example.android_bottomactionbar.R;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ShareActionProvider;
public class ShareActionProviderActivity extends Activity {
private ShareActionProvider mShareActionProvider;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shareactionprovider);
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.shareactionprovider_menu, menu);
mShareActionProvider = (ShareActionProvider) menu.findItem(
R.id.menu_share).getActionProvider();
// If you use more than one ShareActionProvider, each for a different
// action,
// use the following line to specify a unique history file for each one.
// mShareActionProvider.setShareHistoryFileName("custom_share_history.xml");
// Set the default share intent
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/*");
mShareActionProvider.setShareIntent(shareIntent);
// When you need to update the share intent somewhere else in the app,
// call mShareActionProvider.setShareIntent()
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in action bar clicked; go home
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
shareactionprovider_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/share_menu_add"
android:icon="@android:drawable/ic_menu_add"
android:showAsAction="ifRoom|withText"
android:title="@string/menu_add"/>
<item
android:id="@+id/menu_share"
android:actionProviderClass="android.widget.ShareActionProvider"
android:icon="@android:drawable/ic_menu_share"
android:showAsAction="ifRoom|withText"
android:title="@string/menu_share"/>
</menu>
2、自定义 ShareActionProvider
package com.example.example;
import com.example.android_bottomactionbar.R;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
public class CustomActionProviderActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_sap);
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuInflater inflater = new MenuInflater(this);
inflater.inflate(R.menu.custom_actionprovider_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in action bar clicked; go home
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
CustomActionProvider.java
package com.example.example.provider;
import android.content.Context;
import android.util.Log;
import android.view.ActionProvider;
import android.view.LayoutInflater;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.PopupMenu;
import android.widget.Toast;
import com.example.android_bottomactionbar.R;
public class CustomActionProvider extends ActionProvider implements android.widget.PopupMenu.OnMenuItemClickListener{
private Context mContext;
private PopupMenu mPopupMenu;
public CustomActionProvider(Context context) {
super(context);
mContext = context;
}
@Override
public View onCreateActionView() {
Log.d(this.getClass().getSimpleName(), "onCreateActionView");
// Inflate the action view to be shown on the action bar.
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
View view = layoutInflater.inflate(R.layout.custom_actionprovider, null);
ImageView popupView = (ImageView)view.findViewById(R.id.popup_view);
popupView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showPopup(v);
}
});
return view;
}
/**
* show the popup menu.
*
* @param v
*/
private void showPopup(View v) {
mPopupMenu = new PopupMenu(mContext, v);
mPopupMenu.setOnMenuItemClickListener(this);
MenuInflater inflater = mPopupMenu.getMenuInflater();
inflater.inflate(R.menu.custom_popup_up_menu, mPopupMenu.getMenu());
mPopupMenu.show();
}
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.custom_menu_download:
Toast.makeText(mContext, "select download", 0).show();
break;
case R.id.custom_menu_upload:
Toast.makeText(mContext, "select upload", 0).show();
break;
default:
break;
}
return false;
}
}
custom_actionprovider_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/menu_popup_view"
android:title="@string/custom_ap_button"
android:actionProviderClass="com.example.example.provider.CustomActionProvider"
android:showAsAction="ifRoom"/>
</menu>
注意:
在有 menu按键的手机上面,ActionBar 上的 overflow menu 默认不会出现,只有当点击了 menu按键时才会显示。我们可以通过如下方法,强制让它显示出来。
package com.example.example;
import java.lang.reflect.Field;
import com.example.android_bottomactionbar.R;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewConfiguration;
public class MoreActionBarActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_more);
forceShowActionBarOverflowMenu();
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
/**
* 强制显示 overflow menu
*/
private void forceShowActionBarOverflowMenu() {
try {
ViewConfiguration config = ViewConfiguration.get(this);
Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
if (menuKeyField != null) {
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.actionbar_menu_overflow, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in action bar clicked; go home
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
actionbar_menu_overflow.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menu_repost"
android:icon="@android:drawable/ic_menu_edit"
android:title="转发"
android:showAsAction="always" />
<item
android:id="@+id/menu_comment"
android:icon="@android:drawable/ic_menu_zoom"
android:title="评论"
android:showAsAction="always" />
<item
android:id="@+id/menu_refresh"
android:icon="@android:drawable/ic_menu_rotate"
android:title="刷新" />
<item
android:id="@+id/menu_fav"
android:title="收藏"
android:icon="@android:drawable/ic_menu_crop" />
<item
android:id="@+id/menu_share"
android:title="分享"
android:icon="@android:drawable/ic_menu_share"
android:actionProviderClass="android.widget.ShareActionProvider" />
<item
android:id="@+id/menu_copy"
android:title="复制"
android:icon="@android:drawable/ic_menu_compass" />
<item
android:id="@+id/menu_delete"
android:visible="false"
android:title="删除" />
</menu>
这样即使手机有menu 物理按键,overflow menu依然会显示出来