The solution I'm going to detail makes use of ActionLayout
of MenuItem
, which is available from both Android 11+ and earlier versions, but with the use of the support library v7% with%. Soon the solution can be applied to all devices.
Configuration of AppCompat
in AndroidManifest
<activity
android:name=".app.activity.MenuActivity"
android:label="Exemplo Menu"
android:uiOptions="splitActionBarWhenNarrow"
/>
As you mentioned, you must set Activity
to android:uiOptions="splitActionBarWhenNarrow"
to appear.
Menu ( SplitActionBar
)
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/ed_save1"
android:title="@string/action_save"
android:icon="@drawable/ic_save_dark"
android:actionLayout="@layout/menu_item_layout"
app:actionLayout="@layout/menu_item_layout"
android:showAsAction="withText|ifRoom"
app:showAsAction="withText|ifRoom" />
<item
android:id="@+id/ed_save2"
android:title="@string/action_save"
android:icon="@drawable/ic_save_dark"
android:actionLayout="@layout/menu_item_layout"
app:actionLayout="@layout/menu_item_layout"
android:showAsAction="withText|ifRoom"
app:showAsAction="withText|ifRoom" />
<item
android:id="@+id/ed_save3"
android:title="@string/action_save"
android:icon="@drawable/ic_save_dark"
android:actionLayout="@layout/menu_item_layout"
app:actionLayout="@layout/menu_item_layout"
android:showAsAction="withText|ifRoom"
app:showAsAction="withText|ifRoom" />
<item
android:id="@+id/ed_save4"
android:title="@string/action_save"
android:icon="@drawable/ic_save_dark"
android:actionLayout="@layout/menu_item_layout"
app:actionLayout="@layout/menu_item_layout"
android:showAsAction="withText|ifRoom"
app:showAsAction="withText|ifRoom" />
</menu>
In it we see some repeated attributes, with schema menu_activity.xml
and schema app
. I do this because the attributes with schema android
are for app
and those with schema AppCompat
for android
native. If you do not use ActionBar
you can remove it without any problems.
Definition of AppCompat
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:focusable="true"
android:paddingTop="4dip"
android:paddingBottom="4dip"
android:paddingLeft="8dip"
android:paddingRight="8dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="6pt"
android:textColor="@color/white"
style="?attr/actionButtonStyle" />
Common layout, just a menu_item_layout.xml
, where we will configure the icon and text. If you want, you can customize it as needed.
MenuActivity
/**
* Created by wakim on 28/09/14.
*/
public class MenuActivity extends ActionBarActivity implements View.OnClickListener {
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_activity, menu);
for(int i = 0, c = menu.size(); i < c; ++i) {
MenuItem item = menu.getItem(i);
// A linha abaixo é para quem usa o AppCompat.
//TextView actionLayout = (TextView) MenuItemCompat.getActionView(item);
// Recuperando a View que representa o Menu
TextView actionLayout = (TextView) item.getActionView();
// Atribuo o text baseado no title do Menu
actionLayout.setText(item.getTitle());
// Atribuo o drawable de acordo com o ícone.
// Estou usando o drawableTop, mas poderá usar qualquer um dos:
// drawableLeft, drawableTop, drawableRight, drawableBottom
actionLayout.setCompoundDrawablesWithIntrinsicBounds(null, item.getIcon(), null, null);
// Somos obrigados a configurar manualmente o OnClickListener
// Ja que estamos configurando uma View Customizada para o Menu
actionLayout.setOnClickListener(this);
}
return super.onCreateOptionsMenu(menu);
}
@Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.ed_save1:
// Tratamento para click no item ed_save1
break;
case R.id.ed_save2:
// Tratamento para click no item ed_save2
break;
case R.id.ed_save3:
// Tratamento para click no item ed_save3
break;
case R.id.ed_save4:
// Tratamento para click no item ed_save4
break;
}
}
}
My TextView
inherits from Activity
because I'm using ActionBarActivity
, which forces me to inherit it to have access to AppCompat
. If you are using only the native ActionBar
, you can inherit from ActionBar
without any problems.
Result
Edit
InthecaseofthemenubuiltinActivity
,youmustadaptthesolutiontostorethestateofActionMode
anduseittoretrievetheActionMode
createdandMenu
clicked.SobycallingtheMenuItem
method,keepingthesamelogic.
MenuActivity
/***Createdbywakimon28/09/14.*/publicclassMenuActivityextendsActionBarActivityimplementsView.OnClickListener,ActionMode.Callback{ActionModemActionMode;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);startActionMode(this);//SeestiverusandoabibliotecaAppCompat,parainiciaroActionMode//éprecisochamarométodoabaixo,emvezdométodoacima.//startSupportActionMode(this);}@OverridepublicbooleanonCreateOptionsMenu(Menumenu){//OmenuserácriadonoActionMode...returnsuper.onCreateOptionsMenu(menu);}/***MétodoqueconfiguraoActionLayoutdomenu,comosatributosdopróprioMenuItem*/voidconfigureActionLayout(Menumenu){for(inti=0,c=menu.size();i<c;++i){MenuItemitem=menu.getItem(i);TextViewactionLayout=(TextView)MenuItemCompat.getActionView(item);//TextViewactionLayout=(TextView)item.getActionView();actionLayout.setText(item.getTitle());actionLayout.setCompoundDrawablesWithIntrinsicBounds(null,item.getIcon(),null,null);actionLayout.setOnClickListener(this);}}@OverridepublicvoidonClick(Viewv){//TentafazerotratamentocasosejaumMenuItemdeummenucriadonoActionModeif(handleActionModeIfPossible(v.getId())){return;}//Tratamentopadrão,casonãosejaumMenuItemdoActionModeswitch(v.getId()){caseR.id.ed_save1://TratamentoparaclicknomenuLog.i("tag", "ed_save1");
break;
case R.id.ed_save2:
// Tratamento para click no menu
Log.i("tag", "ed_save2");
break;
case R.id.ed_save3:
// Tratamento para click no menu
Log.i("tag", "ed_save3");
break;
case R.id.ed_save4:
// Tratamento para click no menu
Log.i("tag", "ed_save4");
break;
}
}
boolean handleActionModeIfPossible(int menuId) {
// Se nao temos um ActionMode no momento podemos parar
if(mActionMode == null) {
return false;
}
// Recupero o possível MenuItem do Menu atual do ActionMode
MenuItem menuItem = mActionMode.getMenu().findItem(menuId);
// Se nao existe um MenuItem com id "menuId", não podemos continuar.
if(menuItem == null) {
return false;
}
onActionItemClicked(mActionMode, menuItem);
return true;
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.am_menu_activity, menu);
configureActionLayout(menu);
mActionMode = mode;
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
mActionMode = mode;
return true;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
mActionMode = mode;
return true;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
}
}