42 votes

Barre d'action - vue personnalisée avec ImageView centrée, éléments d'action sur les côtés

J'ai besoin de centrer un logo personnalisé (à l'aide d'une ImageView) dans la barre d'action de l'activité "Accueil". J'utilise ABS pour ce projet. Cette question est très similaire à une autre question postée sur S.O. ( Logo ActionBar centré et éléments d'action sur les côtés ), mais je ne suis pas sûr que l'ImageView ou le menu de recherche fasse une différence, car je n'obtiens pas les résultats que je recherche (une image centrée), ou si je me suis simplement trompé. En fait, je place une icône sur la gauche, j'insère la vue personnalisée au centre et j'ai une icône de recherche sur la droite (menu Options). L'image apparaît un peu à droite de l'icône, mais elle n'est toujours pas centrée. Toute indication sur la façon de centrer une ImageView dans la barre d'action serait très appréciée.

Home.java :

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);

    LayoutInflater inflater = (LayoutInflater) getSupportActionBar().getThemedContext()
            .getSystemService(LAYOUT_INFLATER_SERVICE);

    final View customActionBarView = inflater.inflate(
            R.layout.actionbar_custom_view_home, null);

    /* Show the custom action bar view and hide the normal Home icon and title */
    final ActionBar actionBar = getSupportActionBar();
    actionBar.setHomeButtonEnabled(true);
    actionBar.setDisplayHomeAsUpEnabled(false);
    actionBar.setDisplayShowTitleEnabled(false);
    actionBar.setIcon(R.drawable.ic_ab_som);
    actionBar.setCustomView(customActionBarView);
    actionBar.setDisplayShowCustomEnabled(true);

}

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

res/layout/actionbar_custom_view_home.xml :

<?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="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center">

<ImageView
    android:id="@+id/actionBarLogo"
    android:contentDescription="@string/application_name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:clickable="false"
    android:duplicateParentState="false"
    android:focusable="false"
    android:longClickable="false"
    android:padding="@dimen/padding_small"
    android:src="@drawable/logo_horizontal" />

</LinearLayout>

res/menu/search.xml :

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item 
        android:id="@id/search_item"
        android:icon="?attr/action_search"
        android:title="@string/search_label"
        android:showAsAction="ifRoom|collapseActionView">
    </item>
</menu>

0 votes

Jetez un coup d'œil à ma question ici : stackoverflow.com/questions/23783381/

69voto

Si vous voulez que l'image soit au centre de la barre d'action, utilisez :

enter image description here

remplacez simplement getActionBar(); à getSupportActionBar(); dans le code ci-dessous

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final ActionBar actionBar = getActionBar();
        actionBar.setCustomView(R.layout.actionbar_custom_view_home);
        actionBar.setDisplayShowTitleEnabled(false);
        actionBar.setDisplayShowCustomEnabled(true);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

votre actionbar_custom_view_home.xml

<?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="wrap_content"
    android:gravity="center"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/actionBarLogo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:clickable="false"
        android:focusable="false"
        android:longClickable="false"
        android:src="@drawable/ic_launcher" />

</LinearLayout>

Masquer l'icône de la barre d'action

enter image description here

final ActionBar actionBar = getActionBar();
actionBar.setCustomView(R.layout.actionbar_custom_view_home);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setDisplayUseLogoEnabled(false);
actionBar.setDisplayShowHomeEnabled(false);

Remarque : pour les API < 11, utilisez getSupportActionBar() et pour les API > 11, utilisez getActionBar().


EDITION : 02/03/16 pour Barre d'outils

<android.support.v7.widget.Toolbar
   style="@style/ToolBarStyle"
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:background="?attr/colorPrimary"
   android:minHeight="@dimen/abc_action_bar_default_height_material">

    <ImageView
        android:layout_width="wrap_content"
        android:contentDescription="@string/logo"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:src="@drawable/ic_launcher"/>

 </android.support.v7.widget.Toolbar>

1 votes

Cela n'a pas fonctionné dès que j'ai défini l'option .setDisplayHomeAsUpEnabled(true);

0 votes

L'ordre est très important actionBar.setDisplayShowCustomEnabled(true); doit être appelé après actionBar.setCustomView pour maintenir des paramètres de mise en page corrects

0 votes

J'ai un NullPointerException sur actionBar.setCustomView(R.layout.actionbar_custom_view_home)‌​; . Et oui, j'ai remplacé R.layout.actionbar_custom_view_home avec mon propre nom

18voto

Expliqué :

enter image description here

Le conteneur rose, est le véritable espace où vous ajouterez la vue.

L'astuce consiste à faire quelques calculs, pour centrer la vue (ou autre) au milieu.

Dans mon cas, la vue était un TextView. Voici ma méthode complète :

public void addTextToActionBar( String textToSet )
{
    mActionbar.setDisplayShowCustomEnabled( true );

    // Inflate the custom view
    LayoutInflater inflater = LayoutInflater.from( this );
    View header = inflater.inflate( R.layout.actionbar_header, null );

    //Here do whatever you need to do with the view (set text if it's a textview or whatever)
    TextView tv = (TextView) header.findViewById( R.id.program_title );
    tv.setText( textToSet );

    // Magic happens to center it.
    int actionBarWidth = DeviceHelper.getDeviceWidth( this ); //Google for this method. Kinda easy.

    tv.measure( 0, 0 );
    int tvSize = tv.getMeasuredWidth();

    try
    {
        int leftSpace = 0;

        View homeButton = findViewById( android.R.id.home );
        final ViewGroup holder = (ViewGroup) homeButton.getParent();

        View firstChild =  holder.getChildAt( 0 );
        View secondChild =  holder.getChildAt( 1 );

        leftSpace = firstChild.getWidth()+secondChild.getWidth();
    }
    catch ( Exception ignored )
    {}

    mActionbar.setCustomView( header );

    if ( null != header )
    {
        ActionBar.LayoutParams params = (ActionBar.LayoutParams) header.getLayoutParams();

        if ( null != params )
        {
            int leftMargin =  ( actionBarWidth / 2 - ( leftSpace ) ) - ( tvSize / 2 ) ;

            params.leftMargin = 0 >= leftMargin ? 0 : leftMargin;
        }
    }
}

Mise en page :

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal|center_vertical|center"
    android:orientation="horizontal" >

<TextView
    android:id="@+id/program_title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@android:color/white"
    android:contentDescription="@string/content_description_program_title"
    android:ellipsize="end"
    android:maxLines="1"
    android:textSize="22sp"/>

</RelativeLayout>

Profitez-en.

0 votes

Pouvez-vous ajouter le code de votre actionbar_header s'il vous plaît ? J'ai un Cast Exception sur la ligne ActionBar.LayoutParams. Merci !

0 votes

Bonjour, j'ai modifié le code, maintenant vous devez fournir une vue et elle devrait être ajoutée. J'ai également ajouté la mise en page.

0 votes

La mise en page xml, c'est votre actionbar_layout ou votre viewToAdd ?

7voto

jeason_tse Points 1

J'ai rencontré ce problème, voici ma solution :

ActionBar.LayoutParams layoutParams = new ActionBar.LayoutParams(
        ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.MATCH_PARENT);
layoutParams.gravity = Gravity.CENTER_HORIZONTAL|Gravity.CENTER_HORIZONTAL;
actionBar.setCustomView(yourCustomView,layoutParams);

0 votes

Cela fonctionne, merci

0 votes

Il serait peut-être préférable d'utiliser layoutParams.gravity = Gravity.CENTER

3voto

Const Points 276

L'ImageView dans votre code est centrée par rapport au LinearLayout, et non par rapport à la barre d'action. Vous pouvez ajouter une marge gauche (Android:layout_marginLeft) à la disposition pour ajuster la position de l'image.

Une autre façon de procéder consiste à ne pas ajouter une icône et des éléments d'action à la barre d'action, mais à utiliser une mise en page personnalisée contenant une icône et des boutons. Mais dans ce cas, vous devrez gérer vous-même les éléments d'action.

3voto

Blueberry Points 696

J'interviens tardivement, mais si cela peut aider quelqu'un d'autre, utilisez une liste de calques et définissez-la comme arrière-plan. Sinon, le logo sera centré en fonction de l'espace restant, et non de l'ensemble de la barre d'outils comme le mentionne Reinherd.

Vous pouvez utiliser une liste de calques avec une couleur d'arrière-plan statique, et une image dont la gravité est centrée, comme ci-dessous. J'espère que cela vous aidera !

toolbar.axml

<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="@drawable/toolbar_background"
    android:theme="@style/ThemeOverlay.AppCompat.Dark"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
    app:layout_scrollFlags="scroll|enterAlways"
    app:layout_collapseMode="pin">
</android.support.v7.widget.Toolbar>

toolbar_background.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  <item>
    <shape android:shape="rectangle">
      <solid android:color="@color/colorPrimary" />
    </shape>
  </item>
  <item>
    <bitmap android:src="@drawable/logo" android:gravity="center" />
  </item>
</layer-list>

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