How using actionBar appear icon + text of items?

Asked

Viewed 5,276 times

1

I declared in the Manifest android:uiOptions="splitActionBarWhenNarrow" for actionBar and set the items as showAsAction="ifRoom|withText" appear at the bottom of the screen, follows the figure below:

ActionBar
Even with space actionBar does not show icone + text, it only shows the icons. I wish it looked the same on the bottom: ActionBar

  • You’re using the library AppCompat to the ActionBar?

  • I don’t even know what this library does

  • android:uiOptions="splitActionBarWhenNarrow" serves to make the actionbar appear at the bottom so that even if you have space to appear icon + text does not appear, only the icon...

  • to this aew library and support ne... now I remembered I think

  • Yeah, but how are you using the ActionBar native, it is not necessary to use it.

  • hum. strange q all the examples I saw on the net to make appear use android:uiOptions="splitActionBarWhenNarrow" and in all cases only appear the icons... I wanted to know a way to force appear

  • 1

    I’ve been there. What I did to solve this was to create an Actionbar custon and use setCustomView to override the default Actionbar.

  • @Borachio but will get 2 actionbar? an overlay is the default that does not appear or will replace the default?

  • @Borachio anyway if you wish to expose how to do this custom actiobar thank you very much.

  • 1

    I think something parallel to what @Borachio quoted, would be to use a actionLayout to the menu icon. Instead of setting only one Drawable, with the actionLayout you can set an xml layout for each item (can be the same by configuring in the menu creation), including any View.

  • I’ll see how you do it. vlw for the tip

Show 6 more comments

1 answer

2


The solution I’m going to detail makes use of the ActionLayout of MenuItem, which is available both from the Android 11+, as in previous versions, but with the use of v7 support library AppCompat. Soon the solution can be applied to all devices.

Configuration of Activity on Androidmanifest

<activity
    android:name=".app.activity.MenuActivity"
    android:label="Exemplo Menu"
    android:uiOptions="splitActionBarWhenNarrow"
/>

As you mentioned, we need to define the android:uiOptions="splitActionBarWhenNarrow" so that the SplitActionBar appear.

Menu (menu_activity.xml)

<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 the schema app and the schema android. I do this because the attributes with schema app are for the AppCompat and the ones with schema android to the ActionBar native. If you do not use AppCompat can remove smoothly.

Definition of menu_item_layout.xml

<?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, only one TextView, where we will configure the icon and the text. If you want you can customize 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 Activity inherits from ActionBarActivity because I’m using the AppCompat, that forces me to inherit it it to gain access to ActionBar. If you are using only the ActionBar native, you can inherit from Activity no problem.

Upshot

inserir a descrição da imagem aqui


Edit

In the case of the menu built on ActionMode, it is necessary to adapt the solution to store the state of the ActionMode and use it to retrieve the Menu created and respectively the MenuItem clicked. Thus calling the method onActionItemClicked, maintaining the same logic.

Menuactivity

    /**
 * Created by wakim on 28/09/14.
 */
public class MenuActivity extends ActionBarActivity implements View.OnClickListener, ActionMode.Callback {

    ActionMode mActionMode;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        startActionMode(this);

        // Se estiver usando a biblioteca AppCompat, para iniciar o ActionMode
        // é preciso chamar o método abaixo, em vez do método acima.
        //startSupportActionMode(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // O menu será criado no ActionMode...
        return super.onCreateOptionsMenu(menu);
    }

    /***
        Método que configura o ActionLayout do menu,
        com os atributos do próprio MenuItem
    */
    void configureActionLayout(Menu menu) {
        for(int i = 0, c = menu.size(); i < c; ++i) {
            MenuItem item = menu.getItem(i);
            TextView actionLayout = (TextView) MenuItemCompat.getActionView(item);
            //TextView actionLayout = (TextView) item.getActionView();

            actionLayout.setText(item.getTitle());
            actionLayout.setCompoundDrawablesWithIntrinsicBounds(null, item.getIcon(), null, null);

            actionLayout.setOnClickListener(this);
        }
    }

    @Override
    public void onClick(View v) {

        // Tenta fazer o tratamento caso seja um MenuItem de um menu criado no ActionMode
        if(handleActionModeIfPossible(v.getId())) {
            return;
        }

        // Tratamento padrão, caso não seja um MenuItem do ActionMode
        switch (v.getId()) {
            case R.id.ed_save1:
                // Tratamento para click no menu
                Log.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;
    }
}
  • very good. my doubt would be on the issue in using this menu customized by the action mode that when I click on some view item it calls the method onActionItemClicked(), but when I click it calls onclick() because this set there above actionLayout.setOnClickListener(this);.. i wanted to know a way to set to call the click method of the action mode onActionItemClicked()

  • to create the menu I am not using the method onCreateOptionsMenu(Menu), but the method onCreateActionMode(Actionmode mode, Menu menu)

  • 1

    That’s a nice observation, since you didn’t mention it in the question, I took the most common route. I will include in my reply an adaptation to contemplate this case, just a time to prepare the code on my device.

  • thank you very much.. It was bad of me, because I thought the solution would be for any case.. I had not imagined that I would need to set an action for the click, just create a layout for the menu.

  • 1

    @Pedrorangel, I hope you didn’t take my comment as irony, it wasn’t the point. It was good to have quoted, because it leaves a more comprehensive answer, and in fact it would not work without proper treatment. I updated the answer.

  • In no way did I interpret with irony you were correct in your comment it went all right thank you really.. just disturbing you a little more with regard to the positioning of the items by the actionLayout method.setCompoundDrawablesWithIntrinsicBounds on top if the text below the item does not appear right I have to use the support library, Appcompat?

  • 1

    Do not need no, if the text did not appear is because it does not have enough space. Try to change the position of the Drawable for a horizontal position or decrease the size of the icon or text. The ActionBar has a fixed height, if the TextView get too high, he’ll cut.

  • hum.. blz thank you so much again.

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.