59 votes

Android 4.0, le texte sur la barre d'action ne montre jamais

Je suis en train d'utiliser la nouvelle api de google, plus précisément de la barre d'action.

Lorsque la construction a été mis à l'api de 10, si j'ai appuyé sur le bouton de menu, j'ai eu beau regarder les options de menu, chacun avec une image et l'icône. Lors de l'utilisation de l'api de 14 ans, peu importe ce que j'essaie, il met toujours l'icône dans la barre d'action avec AUCUN texte. J'ai essayé tout ce que je peux penser. Je lui ai donné le "texte" de la propriété, a modifié le texte à un seul personnage (dans le cas où c'était une pièce de l'émission), mais rien.

J'ai vu ce fait avant, même dans le guide du développeur sur android.développeur, mais je n'arrive pas à trouver une réponse quant à la FAÇON de l'obtenir.

83voto

dgmltn Points 1939

Je soupçonne que c'était une décision consciente par les développeurs Android de ne pas afficher un menu unique de l'élément de texte et l'icône sur une étroite barre d'action. Mais si vous voulez vraiment le faire, vous pouvez utiliser android:actionLayout dans votre menu.xml fichier. Le Android ActionBar documentation a un peu plus d'explication.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_foo"
          android:title="@string/menu_foo"
          android:icon="@drawable/ic_menu_foo"
          android:showAsAction="always"
          android:actionLayout="@layout/action_button_foo" />
</menu>

Puis de créer votre action_button_foo.xml mise en page:

<?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:paddingTop="14dp"
    android:paddingBottom="14dp"
    android:gravity="center"
    android:text="@string/menu_foo"
    android:drawableLeft="@drawable/ic_menu_foo"
    android:background="@drawable/bg_btn_action_bar"
    android:clickable="true" />

et l'utilisation d'un sélecteur pour son arrière-plan, bg_btn_action_bar.xml, de sorte qu'il change de couleur lorsque vous appuyez dessus:

<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_pressed="true"
        android:drawable="@drawable/bg_action_bar_pressed" />
    <item
        android:drawable="@color/transparent" />
</selector>

Maintenant, vous aurez besoin pour faire de votre affichage personnalisé poignée cliquez sur événements. Dans votre Activité, j'aime à le faire, afin que je puisse gérer le clic en onOptionsItemSelected avec tous mes autres articles personnalisés.

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.my_menu, menu);

    final MenuItem item = menu.findItem(R.id.menu_foo);
    item.getActionView().setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            onOptionsItemSelected(item);
        }
    });

    return super.onCreateOptionsMenu(menu);
}

10voto

Steve Liddle Points 2874

C'est certainement la même chose que j'ai observé sur mon Nexus S running 4.0.4. Mon application utilise une barre d'action avec plusieurs onglets qui sont mis en œuvre comme des fragments. Mes divers fragments de faire des ajustements pour les options de menu affichées sur la barre d'action, tandis que l'onglet est visible.

Cela semble être un bug dans ICS, car il effectue systématiquement comme suit, à la fois sur mon Nexus S et dans l'émulateur (à la fois HVGA et WVGA800):

  1. En mode portrait, mon logo/bouton apparaît sur la ligne supérieure de la barre d'action, les onglets apparaissent sur la deuxième ligne, et toutes les actions apparaissent sous forme d'icônes (pas de texte) dans la partie droite de la rangée du haut.
  2. Mais si, quand je tourne au paysage, à la barre d'action se réduit à une seule ligne, et permettent de se déplacer jusqu'à la barre du haut, comme un spinner (liste déroulante) à côté de mon bouton. Mais, notamment, le texte s'affiche à côté de mes icônes d'action.

J'ai remarqué que certains autres pépins avec l'onglet spinner qui me poussent à croire que ce petit coin de partage de connexion internet est un peu brouillon/buggy. Si je dis à l'application de diviser la barre d'action sur d'étroites affiche (par l'ajout d' android:uiOptions="splitActionBarWhenNarrow" dans le manifeste, ICS pousse toujours ces éléments à la barre du bas, même si il y a encore beaucoup de place à la partie supérieure. Et même avec la barre supplémentaire, il n'est toujours pas afficher le texte, juste l'icône.

Sur ma Xoom de course 4.0.4, les onglets et les éléments d'action apparaîtra toujours de la façon que vous attendez qu'ils apparaissent parce qu'il y a beaucoup de place.

Solution de contournement: si vous voulez vraiment de texte sur la barre d'action en mode portrait, vous avez besoin d'abandonner l'icône. Supprimer l'icône de votre élément de menu et le texte s'affiche. Ce n'est pas exactement ce que nous sommes après.

J'ai posté un rapport de bug ici: https://code.google.com/p/android/issues/detail?id=30180.

3voto

knaak Points 393

Si vous voulez que vos Options de Menu pour afficher dans votre barre d'action avec Nid d'abeille, j'ai fait ça:

Dans votre activité, remplacer cette fonction:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.actionbar_universe, menu);
    return true;
}

où R. menu.actionbar_universe définir votre élément de menu comme ceci:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/crossholdings" android:showAsAction="always|withText"
      android:title="Cross Holdings" android:icon="@drawable/actionbar_cross"/>
</menu>

Remarque le showAsAction="always|withText" et de préciser android:title.

Si vous avez et sa ne fonctionne pas, veuillez copier|coller votre ressource de menu ici.

EDIT: Ceci répond à la mauvaise question, mais c'est le texte original.

J'utilise ce bout de code pour définir le titre de la barre d'action, et de le peindre en rouge avec mon sociétés logo. Il fonctionne bien dans la version 3.0.

public ActionBar setActionBarStyle(String title) {
    ActionBar actionBar = setActionBarStyle();
    actionBar.setTitle(title);
    return actionBar;
}

public ActionBar setActionBarStyle() {
    ActionBar actionBar = getActionBar();
    ShapeDrawable actionBackground = new ShapeDrawable();
    actionBackground.getPaint().setColor(Color.RED);
    actionBackground.setBounds(0, 0, 5, 5);
    actionBar.setBackgroundDrawable(actionBackground);
    actionBar.setDisplayUseLogoEnabled(true);
    actionBar.setDisplayHomeAsUpEnabled(true);

    return actionBar;
}

3voto

Lukos Points 21

Le "withText" propriété fonctionne avec la plupart des tablettes, mais un moyen facile d'obtenir des icônes et du texte sur les appareils de petite taille est d'ajouter le texte à côté de l'icône comme une image (fichier PNG). De cette façon, à la fois le texte et l'icône sera considérée comme une icône et le tout s'affiche.

Vous pouvez utiliser l'icône d'origine pour les tablettes à l'aide de la withText de la propriété.

  • Vous devez créer un menu supplémentaire de dossier dans le répertoire res intitulé "menu-w600dp".

  • L'optionmenu.xml dans ce dossier s'appliqueront uniquement aux largeurs d'écran plus grand que 600dp (ceux qui affichera les icônes et le texte avec pas de problèmes).

0voto

Timmmm Points 9909

Voici une autre option, basée seulement sur dgmltn. Les avantages:

  • Plus de contrôle - par exemple, j'ai remplacé le texte et l'image dans ma mise en page.
  • Plus facile à utiliser, ne nécessite que deux lignes supplémentaires dans vos activités et de vos fragments.
  • Ne nécessite que deux fichiers supplémentaires.
  • Peut-être légèrement plus correct, mais il est encore un peu un hack de l'OMI.

J'ai supposé que vous utilisez ActionBarSherlock dans cet exemple. Tout d'abord, créer la vue de mise en page que vous voulez. Celui-ci est basé sur ActionBarSherlock. Tous j'ai changé, c'est la permutation de l'image/vue, réduire les partagé margin/padding à 0, de sorte qu'ils sont plus proches, et de résolution de tous les ABS styles.

<com.example.views.ActionMenuTextItemView xmlns:android="http://schemas.android.com/apk/res/android"
    style="@android:style/Widget.Holo.ActionButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:addStatesFromChildren="true"
    android:focusable="true"
    android:gravity="center"
    android:clickable="true"
    android:paddingLeft="4dip"
    android:paddingRight="4dip" >

    <com.actionbarsherlock.internal.widget.CapitalizingButton
        android:id="@+id/abs__textButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:background="@null"
        android:ellipsize="none"
        android:focusable="false"
        android:minHeight="48dip"
        android:minWidth="48dip"
        android:paddingBottom="4dip"
        android:paddingLeft="4dip"
        android:paddingRight="0dip"
        android:paddingTop="4dip"
        android:singleLine="true"
        android:textAppearance="@android:style/TextAppearance.Holo.Widget.ActionBar.Menu"
        android:textColor="#fff3f3f3" />

    <ImageButton
        android:id="@+id/abs__imageButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginBottom="4dip"
        android:layout_marginLeft="0dip"
        android:layout_marginRight="4dip"
        android:layout_marginTop="4dip"
        android:adjustViewBounds="true"
        android:background="@null"
        android:focusable="false"
        android:scaleType="fitCenter"
        android:visibility="gone" />

</com.example.views.ActionMenuTextItemView>

Puis de créer le correspondant View classe. Vous pouvez copier CapitalizingButton si vous êtes inquiet à propos de l'utilisation interne des choses. Ah, aussi, je n'ai jamais fixe la largeur minimale des trucs. Ne pense pas que cela importe vraiment bien.

package com.example.views;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.accessibility.AccessibilityEvent;
import android.widget.ImageButton;
import android.widget.LinearLayout;

import com.actionbarsherlock.R;
import com.actionbarsherlock.app.SherlockActivity;
import com.actionbarsherlock.app.SherlockFragment;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.app.SherlockListActivity;
import com.actionbarsherlock.app.SherlockListFragment;
import com.actionbarsherlock.internal.widget.CapitalizingButton;
import com.actionbarsherlock.view.MenuItem;

@SuppressLint({ "NewApi" })
public class ActionMenuTextItemView extends LinearLayout implements OnClickListener
{
    private ImageButton mImageButton;
    private CapitalizingButton mTextButton;
    private Object mTarget;
    private MenuItem mItem;

    // Set up all the data. Object must be a sherlock activity or fragment with an onMenuItemSelected().
    public void initialise(MenuItem item, Object target)
    {
        mItem = item;
        mTarget = target;
        setIcon(mItem.getIcon());
        setTitle(mItem.getTitle());
    }

    public ActionMenuTextItemView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }
    public ActionMenuTextItemView(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }

    @Override
    public void onFinishInflate()
    {
        super.onFinishInflate();
        mImageButton = (ImageButton) findViewById(R.id.abs__imageButton);
        mTextButton = (CapitalizingButton) findViewById(R.id.abs__textButton);
        mImageButton.setOnClickListener(this);
        mTextButton.setOnClickListener(this);
        setOnClickListener(this);
    }

    @Override
    public void setEnabled(boolean enabled)
    {
        super.setEnabled(enabled);
        mImageButton.setEnabled(enabled);
        mTextButton.setEnabled(enabled);
    }

    public void setIcon(Drawable icon)
    {
        mImageButton.setImageDrawable(icon);
        if (icon != null)
            mImageButton.setVisibility(VISIBLE);
        else
            mImageButton.setVisibility(GONE);
    }

    public void setTitle(CharSequence title)
    {
        mTextButton.setTextCompat(title);
        setContentDescription(title);
    }

    @Override
    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event)
    {
        onPopulateAccessibilityEvent(event);
        return true;
    }

    @Override
    public void onPopulateAccessibilityEvent(AccessibilityEvent event)
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
            super.onPopulateAccessibilityEvent(event);
        final CharSequence cdesc = getContentDescription();
        if (!TextUtils.isEmpty(cdesc))
            event.getText().add(cdesc);
    }

    @Override
    public boolean dispatchHoverEvent(MotionEvent event)
    {
        // Don't allow children to hover; we want this to be treated as a single component.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
            return onHoverEvent(event);
        return false;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int minWidth = 0;

        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        final int specSize = MeasureSpec.getSize(widthMeasureSpec);
        final int oldMeasuredWidth = getMeasuredWidth();
        final int targetWidth = widthMode == MeasureSpec.AT_MOST ? Math.min(specSize, minWidth) : minWidth;

        if (widthMode != MeasureSpec.EXACTLY && minWidth > 0 && oldMeasuredWidth < targetWidth)
        {
            // Remeasure at exactly the minimum width.
            super.onMeasure(MeasureSpec.makeMeasureSpec(targetWidth, MeasureSpec.EXACTLY), heightMeasureSpec);
        }
    }
    @Override
    public void onClick(View v)
    {
        if (mTarget == null)
            return;
        else if (mTarget instanceof SherlockActivity)
            ((SherlockActivity)mTarget).onOptionsItemSelected(mItem);
        else if (mTarget instanceof SherlockFragmentActivity)
            ((SherlockFragmentActivity)mTarget).onOptionsItemSelected(mItem);
        else if (mTarget instanceof SherlockListActivity)
            ((SherlockListActivity)mTarget).onOptionsItemSelected(mItem);
        else if (mTarget instanceof SherlockListFragment)
            ((SherlockListFragment)mTarget).onOptionsItemSelected(mItem);
        else if (mTarget instanceof SherlockFragment)
            ((SherlockFragment)mTarget).onOptionsItemSelected(mItem);
        else
            throw new IllegalArgumentException("Target must be a sherlock activity or fragment.");
    }

}

Ok, maintenant vous êtes prêt à l'utiliser. Dans vos éléments de menu que vous souhaitez que le texte, vous faites la même chose que ce que dgmltn dit:

<item
    android:id="@+id/menu_foo"
    android:icon="@drawable/..."
    android:showAsAction="always|withText" // Doesn't do anything really.
    android:title="Sell"
    android:titleCondensed="Sell"
    android:actionLayout="@layout/view_action_menu_text_item"/> // Or whatever you called it.

Et enfin, il suffit d'ajouter ce code à votre activité/fragment:

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    super.onCreateOptionsMenu(menu);
    getSupportMenuInflater().inflate(R.menu.activity_main, menu);

    // The magic lines.
    MenuItem it = menu.findItem(R.id.menu_foo);
    ((ActionMenuTextItemView)it.getActionView()).initialise(it, this);

Et c'est tout!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X