最近一直在研究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依然会显示出来





Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐