<item android:id="@+id/share" android:orderInCategory="45" android:showAsAction="ifRoom" android:actionProviderClass="android.widget.ShareActionProvider" android:title="share"></item>
2、获取ShareActionProvider对象
3、调用Intent进行数据分享
4、调用setShareIntent()方法
package com.abc.action; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.widget.ShareActionProvider; import android.widget.Toast; public class CActionBar1Activity extends Activity { /** Called when the activity is first created. */ ShareActionProvider provider=null; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } public boolean onCreateOptionsMenu(Menu menu) { // TODO 自动生成的方法存根 getMenuInflater().inflate(R.menu.menu, menu); //1、获取ShareActionProvider对象 provider=(ShareActionProvider) menu.findItem(R.id.share).getActionProvider(); /*等价于 * MenuItem menuItem_share = menu.findItem(R.id.share); provider = (ShareActionProvider) menuItem_share.getActionProvider();*/ //2、调用Intent进行数据分享 Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TEXT, "This is ShareActionProvider"); //3、调用setShareIntent()方法 provider.setShareIntent(intent); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { // TODO 自动生成的方法存根 switch (item.getItemId()) { case R.id.share: Toast.makeText(getApplicationContext(), "share icon selected", Toast.LENGTH_LONG).show(); break; default: } return super.onOptionsItemSelected(item); } }
package com.abc.provider; import com.abc.action.R; //重写三个方法并构造一个方法 import android.content.Context; import android.view.ActionProvider; import android.view.MenuItem; import android.view.SubMenu; import android.view.View; import android.view.MenuItem.OnMenuItemClickListener; public class MyActionProvider extends ActionProvider { private Context context; public MyActionProvider(Context context) { super(context); this.context = context; } @Override public View onCreateActionView() { return null;//只有当它返回null时才会调用onPrepareSubMenu方法的子菜单首先是创建了一个构造方法,然后重写了onCreateActionView()方法,并且返回值必须是null,只有返回值是null的时候, onPrepareSubMenu() 才会弹出子菜单,而我们显示的带有图标的overflow其实就是通过这种方法来实现的,然后在onPrepareSubMenu通过调用SubMenu的add()方法添加子菜单,并设置图片和点击事件。
} @Override public void onPrepareSubMenu(SubMenu subMenu) { subMenu.clear(); subMenu.add("拍照").setIcon(R.drawable.camera) .setOnMenuItemClickListener(new OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { return true; } }); subMenu.add("视频").setIcon(R.drawable.video) .setOnMenuItemClickListener(new OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { return false; } }); } @Override public boolean hasSubMenu() { return true; //为了表示这个Action Provider是有子菜单的,需要重写hasSubMenu()方法,并返回true } }
<item android:id="@+id/share" android:orderInCategory="45" android:showAsAction="ifRoom" android:icon="@drawable/add" android:actionProviderClass="com.abc.provider.MyActionProvider" android:title="share"></item>添加属性 android:actionProvider Class="com.abc.provider.MyActionProvider",而里面的属性值是 包名+类名的完整路径,千万不要写错了。
当用户在支持上下文菜单的View上执行长按动作的时候,菜单以一种悬浮列表的方式出现,类似于对话框。用户可以每次选择一个菜单项,执行一个上下文相关的动作。
为了便于大家看的更仔细,我重新建立一个项目,不过我上传的资源还是原项目,里面仍然包括contextual,只是为了让大家看的更仔细
Contextual.java
package ff.gh; import android.os.Bundle; import android.app.Activity; import android.view.ContextMenu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ContextMenu.ContextMenuInfo; import android.widget.EditText;
import android.widget.Toast; public class Contextual extends Activity { private EditText editText= null;
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); editText = (EditText) findViewById(R.id.editText); // 1、注册要弹出ContextMenu的View,没有此操作将不会显示弹出框 registerForContextMenu(editText); }
//2、加载资源文件 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { // 第二个参数为当前点击的view super.onCreateContextMenu(menu, v, menuInfo); MenuInflater inflater = getMenuInflater(); // 把布局inflate进menu对象 inflater.inflate(R.menu.main, menu); } @Override
//3、创建选项 public boolean onContextItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.edit: Toast.makeText(BbbActivity.this, "Edit", Toast.LENGTH_LONG).show(); break; case R.id.help: Toast.makeText(BbbActivity.this, "Help", Toast.LENGTH_LONG).show(); break; case R.id.setting: Toast.makeText(BbbActivity.this, "Setting", Toast.LENGTH_LONG).show(); break; default: break; } return true; } }main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".HelloContextMenuMainActivity" >
<EditText
android:id="@+id/editText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="请长按选择内容"/>
</LinearLayout>
menu.xml
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/edit" android:showAsAction="ifRoom" android:title="edit"/> <item android:id="@+id/help" android:title="help"/> <item android:id="@+id/setting" android:title="setting"/> </menu>
本项目效果图,其中的列表是可以选择的
效果图
实现代码如下
ContextualActivity.java:
import android.app.Activity; import android.os.Bundle; import android.view.ActionMode; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.View.OnLongClickListener; import android.widget.Button; import android.widget.Toast; public class ContextualActivity extends Activity { private Button button1; private ActionMode actionMode; //使用 ActionMode 完成菜单操作 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); button1 = (Button)findViewById(R.id.button1); //绑定用户的动作,注意这个事件必须是一个长按事件
//1、设置监听事件并判空及调用startActionMode()方法main.xml
button1.setOnLongClickListener(new OnLongClickListener() { public boolean onLongClick(View v) { //ActionMode的判断是为了确保在它活动期间不会被重复的再创建,通过在创建实例的时候判断其是否为空。 if(actionMode != null) { return false; } actionMode = startActionMode(mActionModeCallBack); //当你调用startActionMode()方法的时候,系统就会返回一个ActionMode的实例,保存在成员变量中,就可以通过改变上下文条栏来触发对应的事件 return true; } }); } //private ActionMode.Callback mActionModeCallBack1 = new ActionMode.Callback(){}; //2、实现 ActionMode.Callback 接口,这里面是一个匿名内部类 private ActionMode.Callback mActionModeCallBack = new ActionMode.Callback() { //添加四种未实现的方法 public boolean onPrepareActionMode(ActionMode mode, Menu menu) { // TODO Auto-generated method stub return false; } //表示我们要加载菜单,从XML中加载菜单 public boolean onCreateActionMode(ActionMode mode, Menu menu) { // 等价于onCreateOptionsMenu(Menu menu),或者onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
MenuInflater inflate = getMenuInflater(); inflate.inflate(R.menu.menu, menu); return true; //返回true 表示加载成功。 } //处理用户的相应动作 //表示从点击菜单选项中捕获用户的操作 public boolean onActionItemClicked(ActionMode mode, MenuItem item) { //等价于 onOptionsItemSelected(MenuItem item) switch (item.getItemId()) { case R.id.edit: Toast.makeText(ContextualActivity.this, "Edit", 3).show(); break; case R.id.share: Toast.makeText(ContextualActivity.this, "share", 3).show(); break; case R.id.delete: Toast.makeText(ContextualActivity.this, "delete", 3).show(); break; } return false; } public void onDestroyActionMode(ActionMode mode) { //当我们不在使用菜单的时候, actionMode = null 在菜单销毁的时候置空 actionMode = null; } }; }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="请长按次按钮》》》》》" android:id="@+id/button1" /> </LinearLayout>
menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/share" android:showAsAction="never" android:title="Share"/> <item android:id="@+id/edit" android:showAsAction="never" android:title="Edit"/> <item android:id="@+id/delete" android:showAsAction="never" android:title="Delete"/> </menu>
既然讲的上下文
(3) 创建弹出菜单(PopupMenu)
PopupMenuActivity.java
创建一个PopupMenu对象,通过 popupMenu.setOnMenuItemClickListener 设置该对象点击菜单中各个选项的监听事件package com.abc.popup; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.PopupMenu; import android.widget.PopupMenu.OnMenuItemClickListener; import android.widget.Toast; public class PopupMenuActivity extends Activity { private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); button = (Button)findViewById(R.id.button); //这种就不需要长按事件 button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //1、创建PopupMenu对象 PopupMenu popupMenu = new PopupMenu(PopupMenuActivity.this, v); //2、对popup设置监听事件 popupMenu.setOnMenuItemClickListener(new OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { // TODO Auto-generated method stub switch (item.getItemId()) { case R.id.edit: Toast.makeText(PopupMenuActivity.this, "Edit", 3).show(); break; case R.id.share: Toast.makeText(PopupMenuActivity.this, "share", 3).show(); break; case R.id.delete: Toast.makeText(PopupMenuActivity.this, "delete", 3).show(); break; } return false; } }); //3、加载菜单资源 //使用 MenuInflater 来加载菜单资源,通过 PopupMenu.getMenuflater() 得到一个 Menuflater 对象, //如果是在 API 14 或者更高级,你可以通过 PopupMenu.inflate() 来代替了。 MenuInflater inflater = popupMenu.getMenuInflater(); inflater.inflate(R.menu.menu, popupMenu.getMenu()); //popupMenu.getMenuInflater().inflate(R.menu.menu, popupMenu.getMenu()); popupMenu.show(); } }); } }
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/share"
android:orderInCategory="100"
android:showAsAction="never"
android:title="Share"/>
<item
android:id="@+id/edit"
android:orderInCategory="100"
android:showAsAction="never"
android:title="Edit"/>
<item
android:id="@+id/delete"
android:orderInCategory="100"
android:showAsAction="never"
android:title="Delete"/>
</menu>
效果图:
5、实现下拉导航与进度条刷新(Spinner,Progress)
Spinner.xml
<?xml version="1.0" encoding="utf-8"?> <Spinner xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/pspinner" android:layout_width="wrap_content" android:layout_height="wrap_content"> </Spinner>
<?xml version="1.0" encoding="utf-8"?> <ProgressBar xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/progressBar" android:layout_width="wrap_content" android:layout_height="wrap_content"> </ProgressBar>
ActionBArActivity.java
package com.abc.action; import javax.net.ssl.HandshakeCompletedListener; import android.app.ActionBar; import android.app.ActionBar.OnNavigationListener; import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.os.HandlerThread; import android.view.Menu; import android.view.MenuItem; import android.view.ViewConfiguration; import android.widget.ArrayAdapter; import android.widget.Toast; public class ActionBArActivity extends Activity { String[] actions = new String[] { "孟小仙", "张三石", "王水", "门三", "育小胖", "负责" }; private MenuItem menuItem = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, actions); // ActionBar actionBar = getActionBar(); //1、 设置action bar 的 navigation mode 导航模式 getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); //2、实现ActionBar.OnNavigationListener这个接口,接口中有点击item的事件 OnNavigationListener navigationListener = new OnNavigationListener() { @Override public boolean onNavigationItemSelected(int itemPosition, long itemId) { //响应要点击的选项 Toast.makeText(getBaseContext(),"You selected : " + actions[itemPosition],Toast.LENGTH_SHORT).show(); return false; } }; //3、用 setListNavigationCallbacks()方法来实现下拉选项,并通过setListNavigationCallbacks方法绑定一个SpinnerAdapter控件, getActionBar().setListNavigationCallbacks(adapter, navigationListener); } public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu, menu); return super.onCreateOptionsMenu(menu); } public boolean onOptionsItemSelected(MenuItem item) { // TODO 自动生成的方法存根 switch (item.getItemId()) { case R.id.action_refresh: menuItem = item; menuItem.setActionView(R.layout.progressbar); // menuItem.expandActionView(); TestTask task = new TestTask(); task.execute("test"); Toast.makeText(this, "Menu Item refresh selected", Toast.LENGTH_SHORT).show(); break; default: break; } return super.onOptionsItemSelected(item); } private class TestTask extends AsyncTask<String, Void, String> { //这个方法用于处理耗时操作,其中的三个参数代表三种子方发的返回值类型,其中一种在这里没有用到 protected String doInBackground(String... params) { // TODO 自动生成的方法存根 try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } return null; } //当doInBackground(String... params)执行完毕并通过return语句进行返回时,这个方法会很快被调用 protected void onPostExecute(String result) { menuItem.collapseActionView(); menuItem.setActionView(null); super.onPostExecute(result); } } }创建一个SpinnerAdapter提供下拉选项,和Tab方式不同的是Drop-down只需要修改下setNavigationMode的模式,将ActionBar.NAVIGATION_MODE_TABS改为ActionBar.NAVIGATION_MODE_LIST
这里用到了MenuItem 类的,setActionView()和collapseActionView()这两个方法。 这个例子的效果是当我们点击refresh action button的时候会显示进度条。
为了方便在子线程中对UI进行操作,我们需要借助工具栏AsyncTask,使之可以简单的从子线程切换到主线程
三个泛型参数的用途:
Params:在执行AsyncTask时需要传人的参数,用于后台任务中使用。
Progress:使用该参数用于进度条的单位。
Result:当任务执行完之后,需要对结果进行返回。
点击前
项目源代码下载
6、显示在底部的actionbar
显示在底部的ActionBar 在AndroidManifest里的<activity>或<application>清单元素上加上属性android:uiOptions="splitActionBarWhenNarrow"后,普通ActionBar将不再显示在标题栏部分,而是显示在底部
借用前面的一张图
不太懂得朋友可以参考ActionBar之属性详解总结(一)