actionbar的各种坑

来源:互联网 发布:java中文怎么读 编辑:程序博客网 时间:2024/06/01 08:07

尽量用support包里的actionbar 

actionBar = getSupportActionBar();


//设置左上角的按钮可以点击

actionBar.setDisplayHomeAsUpEnabled(true);


//顶部默认图标使用了AndroidManifest.xml里面的Application里面的icon,如果不想用这个,也可以用其他的

actionBar.setIcon(getResources().getDrawable(R.drawable.ic_action_previous_item));//左箭头


//在图标左侧默认效果会有一个<,特别讨厌,如果想去掉,可以用一个透明图片代替,这样把图标换成一个大的左箭头就可以实现常见的左箭头导航的效果

//坑爹的谷歌加了一个默认效果,还以为设置为null就不显示了,结果正好相反,nnd

actionBar.setHomeAsUpIndicator(getResources().getDrawable(R.drawable.bg_transparent));


//如果想设置下背景图片,比较容易,但是要注意你的app整体风格是黑的(holo)还是白的(holo.light)

//如果是holo,那么标题栏上的文字是白的,你再设置一个浅色背景图,文字就看不出来了,反之亦反。

actionBar.setBackgroundDrawable(getResources().getDrawable(R.drawable.bg_actionbar_white));


//是否显示标题

actionBar.setDisplayShowTitleEnabled(true);


//设置导航模式,默认的就是NAVIGATION_MODE_STANDARD,

actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);


//如果是列表:NAVIGATION_MODE_LIST,注意这个列表是在页面标题的右边显示一个下拉列表,而不是在右侧的按钮点击后出现的下拉列表,坑!

//类似浏览器的回退按钮的下拉列表,可以选择后退到某一页


//如果是页签NAVIGATION_MODE_TABS,这个还比较有用,然后还可以设置隐藏标题栏,这样就成了一个纯粹的页签效果。一般是上页签,效果也不错。

//类似微信的那样效果可以比较轻松的实现

//如果你只想显示Navigation Tabs,不想显示actionbar上面的标题等布局,你可以调用下面两行代码来实现

actionBar.setDisplayShowHomeEnabled(false);

actionBar.setDisplayShowTitleEnabled(false);


//构造一个自定义的Adapter,使将Fragment作为一个页面,放入到viewpager中,并且使viewpageractionbar相关联起来。

mTabsAdapter = new TabsAdapter(this,mViewPager);

mTabsAdapter.addTab(bar.newTab().setText("Simple"),

TestFragment.class,null);

mTabsAdapter.addTab(bar.newTab().setText("List"),

TestFragment.class,null);

mTabsAdapter.addTab(bar.newTab().setText("Cursor"),

TestFragment.class,null);

加页签的具体代码这里不写了,网上例子很多。


//设置标题文字(显示在左边,不能显示在中间,如果想在中间,得用自定义视图)

actionBar.setTitle(R.string.app_name);


//在actionbar上显示的各种按钮或者下拉菜单什么的,可以用下面的方法创建,也可以用代码

@Override

public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {

inflater.inflate(R.menu.menu1, menu);  //global是你的菜单

super.onCreateOptionsMenu(menu, inflater);

}


那个menu1.xml如下

<menuxmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:yourapp="http://schemas.android.com/apk/res-auto">

    <item

        android:id="@+id/action_search"

        android:icon="@drawable/ic_action_search"

        android:orderInCategory="1"

        yourapp:showAsAction="always"

        android:title="Search"/>

    <item

        android:id="@+id/action_settings"

        android:icon="@drawable/ic_action_settings"

        android:orderInCategory="1"

        yourapp:showAsAction="ifRoom|withText"

        android:title="settings"/>

    <item

        android:id="@+id/action_camera"

        android:icon="@drawable/ic_action_camera"

        android:orderInCategory="1"

        yourapp:showAsAction="ifRoom|withText"

        android:title="camera"/>

    <item

        android:id="@+id/action_about"

        android:icon="@drawable/ic_action_about"

        android:orderInCategory="1"

        yourapp:showAsAction="ifRoom|withText"

        android:title="about"/>

    <item

        android:id="@+id/action_cloud"

        android:icon="@drawable/ic_action_cloud"

        android:orderInCategory="1"

        yourapp:showAsAction="ifRoom|withText"

        android:title="cloud"/>

    <item

        android:id="@+id/action_download"

        android:icon="@drawable/ic_action_download"

        android:orderInCategory="1"

        yourapp:showAsAction="ifRoom|withText"

        android:title="download"/>

    <item

        android:id="@+id/action_favorite"

        android:icon="@drawable/ic_action_favorite"

        android:orderInCategory="1"

        yourapp:showAsAction="ifRoom|withText"

        android:title="favorite"/>

    <item

        android:id="@+id/action_help"

        android:icon="@drawable/ic_action_help"

        android:orderInCategory="1"

        yourapp:showAsAction="ifRoom|withText"

        android:title="help"/>

</menu>


注意:

1. showasaction里面的值,如果是never 则肯定不会显示,会在隐藏的折叠菜单中,如果瞎写,把always和never写一起会报错的。

2.加 xmlns:yourapp="http://schemas.android.com/apk/res-auto"  命名空间的作用是为了保持兼容性,在低版本上可以用。

3.android:actionProviderClass=""里面写的actionprovider不起作用,不知为何,用代码来实现。

4.android:actionViewClass=""没试验,不知道行不行

never:永远不会显示。只会在溢出列表中显示。
ifRoom:会显示在Item中,但是如果已经有4个或者4个以上的Item时会隐藏在溢出列表中。
always:无论是否溢出,总会显示。
withText:Title会显示。
collapseActionView:可拓展的Item。


用代码加菜单的方法

@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

MenuInflater inflater = getMenuInflater();

MenuItem setItem = menu.add("Add").setIcon(R.drawable.ic_action_new);

 //这是可以的

MenuItemCompat.setActionProvider(setItem,new PlusActionProvider(this)); 

MenuItemCompat.setShowAsAction(setItem, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);


inflater.inflate(R.menu.menu1, menu);

//可以给指定的menu加上ActionProvider

MenuItemCompat.setActionProvider(menu.getItem(1),new AppPickActionProvider(this));

returnsuper.onCreateOptionsMenu(menu);

}

//注意加ActionProvider的方法: 

MenuItemCompat.setActionProvider(setItem, new PlusActionProvider(this));   //this是一个context,


ActionProvider的写法,效果就是点击按钮后,可以在按钮下出现一个菜单

actionbar上的按钮点击后,出现下拉菜单,在低版本(测试机系统为2.3.6)上会在屏幕中间出现,高版本在按钮下方出现,可以用它来模拟最右侧的三个点,点击后出菜单的效果。

import android.content.Context;

import android.support.v4.view.ActionProvider;

import android.view.MenuItem;

import android.view.MenuItem.OnMenuItemClickListener;

import android.view.SubMenu;

import android.view.View;

//actionbar上的按钮点击后,出现下拉菜单,在低版本(测试机系统为2.3.6)上会在屏幕中间出现,高版本在按钮下方出现

public class PlusActionProviderextends ActionProvider {

private Contextcontext;

public PlusActionProvider(Context context) {

super(context);

this.context = context;

}


@Override

public View onCreateActionView() {

returnnull;

}


@Override

public void onPrepareSubMenu(SubMenu subMenu) {

subMenu.clear();

subMenu.add("发起群聊")

.setIcon(R.drawable.ic_action_share)

.setOnMenuItemClickListener(new OnMenuItemClickListener() {

@Override

publicboolean onMenuItemClick(MenuItem item) {

returntrue;

}

});

subMenu.add("添加好友")

.setIcon(R.drawable.ic_action_share)

.setOnMenuItemClickListener(new OnMenuItemClickListener() {

@Override

publicboolean onMenuItemClick(MenuItem item) {

returnfalse;

}

});

subMenu.add("视频聊天")

.setIcon(R.drawable.ic_action_share)

.setOnMenuItemClickListener(new OnMenuItemClickListener() {

@Override

publicboolean onMenuItemClick(MenuItem item) {

returnfalse;

}

});

subMenu.add("扫一扫")

.setIcon(R.drawable.ic_action_share)

.setOnMenuItemClickListener(new OnMenuItemClickListener() {

@Override

publicboolean onMenuItemClick(MenuItem item) {

returnfalse;

}

});

subMenu.add("拍照分享")

.setIcon(R.drawable.ic_action_share)

.setOnMenuItemClickListener(new OnMenuItemClickListener() {

@Override

publicboolean onMenuItemClick(MenuItem item) {

returnfalse;

}

});

}

@Override

public boolean hasSubMenu() {

returntrue;

}

}

//在只有一个左上角的大返回按钮的时候,如果点击按钮,想处理具体的事件,需要这样写。

//左上角的按钮,对应的id是android.R.id.home,注意android是小写

//关于返回和上一级的讨论,安卓官方文档有一个讨论,具体的可以去查官网资料,什么up vs back的那篇文章。

@Override

public boolean onOptionsItemSelected(MenuItem item) {

switch (item.getItemId()) {

case android.R.id.home:

this.finish(); //例如关闭当前的activity

default:

returnsuper.onOptionsItemSelected(item);

}

}


如果导航模式设置为列表,那么对应的写法是

// 将ActionBar的操作模型设置为NAVIGATION_MODE_LIST // 生成一个SpinnerAdapter

SpinnerAdapter adapter = ArrayAdapter.createFromResource(this,

R.array.student, android.R.layout.simple_spinner_dropdown_item); 

//为ActionBar设置下拉菜单和监听器 

actionBar.setListNavigationCallbacks(adapter,

newDropDownListenser());


//R.array.student:在strings.xml里面添加如下代码:

<string-array name="student">

        <item>邓名侨</item>

        <item>刘天喜</item>

        <item>其黄石</item>

        <item>蔡宏远</item>

    </string-array>


//下拉的监听器

class DropDownListenser implements OnNavigationListener {

// 得到和SpinnerAdapter里一致的字符数组

String[] listNames = getResources().getStringArray(R.array.student);


/* 当选择下拉菜单项的时候,将Activity中的内容置换为对应的Fragment */

publicboolean onNavigationItemSelected(int itemPosition,long itemId) {

// 生成自定的Fragment

StudentInfo student =new StudentInfo();

FragmentManager manager = getSupportFragmentManager();

FragmentTransaction transaction = manager.beginTransaction();

// 将Activity中的内容替换成对应选择的Fragment id:flTabContent是你的一块容器

transaction.replace(R.id.flTabContent, student,listNames[itemPosition]);

transaction.commit();

returntrue;

}

}


//学生的fragment代码

private class StudentInfoextends Fragment {

// Fragment对应的标签,当Fragment依附于Activity时得到

private Stringtag;


@Override

publicvoid onAttach(Activity activity) {

super.onAttach(activity);

tag =getTag();

}


@Override

public View onCreateView(LayoutInflater inflater,ViewGroup container,

Bundle savedInstanceState) {

TextView textView = new TextView(getActivity());

textView.setText(tag);

return textView;

}

}


actionbar最坑爹的部分是在菜单xml里面的按钮设置了never或者ifroom后,按理说应该就在右上角的三个点按钮里面出现一个下拉菜单,安卓的官方文档也是这么写的。

可是实际上很多机器是出不来的,有一个哥们研究了好久,说大概是因为有物理menu键,就不出来,如果没有,就出来,后来国内外的很多人都被坑了

当菜单项过多时,Android会分两种情况进行处理:

1、手机有MENU实体键:则按下Menu键后会显示剩余菜单项

2、手机没有MENU实体键:则会在最左边显示一个Action OverFlow按钮,按下后会显示剩余项菜单,如图:


有一老外后来给了个解决办法,用反射直接把里面的变量值改了,任何时候都出来了,代码如下:

//force to show overflow menu in actionbar for android 4.4 below

//一直显示那个三个点按钮

public void getOverflowMenu() {

    //在2.3.6上不起作用

         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();

        }

    }

可惜在2.3.6机器上测试的时候,还是出不来,估计是低版本没有那个字段,但是也没关系,如果这样,那么就在最右侧加一个按钮,图标显示成那三个点,点击它后用actionprovider来模拟一个下拉菜单。


出现菜单后,菜单里面设置好的图标也出不来,还是用反射的方法强行改。

//显示下拉菜单上的图标

@Override

public boolean onMenuOpened(int featureId, Menu menu) {

if (featureId == Window.FEATURE_ACTION_BAR && menu !=null) {

if (menu.getClass().getSimpleName().equals("MenuBuilder")) {

try {

Method m = menu.getClass().getDeclaredMethod(

"setOptionalIconsVisible", Boolean.TYPE);

m.setAccessible(true);

m.invoke(menu,true);

catch (Exception e) {

}

}

}

returnsuper.onMenuOpened(featureId, menu);

}

原创粉丝点击