Comment afficher une vue personnalisée dans ActionBar?

92

Je souhaite afficher la recherche personnalisée dans la barre d'action (j'utilise ActionBarSherlock pour cela).

J'ai compris:

entrez la description de l'image ici

Mais je veux faire une mise en page personnalisée (champ edittext) pour occuper toute la largeur disponible.

J'ai implémenté une mise en page personnalisée comme suggéré ici .

Voici ma mise en page personnalisée search.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    style="?attr/actionButtonStyle"
    android:layout_width="fill_parent"
    android:layout_height="match_parent"
    android:layout_gravity="fill_horizontal"
    android:focusable="true" >

    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical|fill_horizontal" >

        <EditText
            android:id="@+id/search_query"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="left|center"
            android:background="@drawable/bg_search_edit_text"
            android:imeOptions="actionSearch"
            android:inputType="text" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right|center_vertical"
            android:src="@drawable/ic_search_arrow" />

    </FrameLayout>

</LinearLayout>

Et dans MyActivity:

ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setIcon(R.drawable.ic_action_search);

LayoutInflater inflator = (LayoutInflater) this .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflator.inflate(R.layout.search, null);

actionBar.setCustomView(v);

Comment puis-je créer une mise en page personnalisée pour occuper toute la largeur disponible de actionBar?

Aidez-moi, s'il vous plaît.

Sabre
la source
Pouvez-vous définir le titre avec un jeu de vues personnalisé?
Roy Lee

Réponses:

95

Il y a une astuce pour cela. Tout ce que vous avez à faire est d'utiliser RelativeLayoutplutôt LinearLayoutque comme conteneur principal. Il est important de s'y android:layout_gravity="fill_horizontal"préparer. Ça devrait le faire.

Tomik
la source
3
@Tomik Pourriez-vous jeter un œil à mon scénario? stackoverflow.com/questions/16516306/... J'ai un titre manquant une fois la vue personnalisée définie.
Roy Lee
36

J'ai lutté avec cela moi-même et j'ai essayé la réponse de Tomik. Cependant, cela n'a pas rendu la mise en page pleine largeur disponible au démarrage, uniquement lorsque vous ajoutez quelque chose à la vue.

Vous devrez définir le LayoutParams.FILL_PARENTlors de l'ajout de la vue:

//I'm using actionbarsherlock, but it's the same.
LayoutParams layout = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
getSupportActionBar().setCustomView(overlay, layout); 

De cette façon, il remplit complètement l'espace disponible. (Vous devrez peut-être également utiliser la solution de Tomik).

Peterdk
la source
2
+1, en fait, cela n'a fonctionné pour moi qu'après avoir ajouté les LayoutParams, thnx
Mahmoud Badri
1
quelle est la valeur de la superposition?
androidevil
2
@androider est votre vue personnalisée. Soit gonflé à partir de xml, soit créé dans le code.
Bilthon
8

C'est ainsi que cela a fonctionné pour moi (à partir des réponses ci-dessus, il montrait à la fois le titre par défaut et ma vue personnalisée également).

ActionBar.LayoutParams layout = new ActionBar.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
// actionBar.setCustomView(view); //last view item must set to android:layout_alignParentRight="true" if few views are there 
actionBar.setCustomView(view, layout); // layout param width=fill/match parent
actionBar.setDisplayShowCustomEnabled(true);//must other wise its not showing custom view.

Ce que j'ai remarqué, c'est que les deux setCustomView(view)et setCustomView(view,params)la largeur de la vue = match / fill parent. setDisplayShowCustomEnabled (booléen showCustom)

Bharatesh
la source
6

Les réponses de Tomik et Peterdk fonctionnent lorsque vous souhaitez que votre vue personnalisée occupe toute la barre d'actions, en masquant même le titre natif.

Mais si vous voulez que votre vue personnalisée coïncide avec le titre (et remplisse tout l'espace restant après l'affichage du titre), puis-je vous référer à l'excellente réponse de l'utilisateur Android-Developer ici:

https://stackoverflow.com/a/16517395/614880

Son code au fond a parfaitement fonctionné pour moi.

Mike Repass
la source
3

Par exemple, vous pouvez définir un fichier de mise en page contenant un élément EditText.

<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/searchfield"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:inputType="textFilter" >

</EditText> 

tu peux faire

public class MainActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ActionBar actionBar = getActionBar();
    // add the custom view to the action bar
    actionBar.setCustomView(R.layout.actionbar_view);
    EditText search = (EditText) actionBar.getCustomView().findViewById(R.id.searchfield);
    search.setOnEditorActionListener(new OnEditorActionListener() {

      @Override
      public boolean onEditorAction(TextView v, int actionId,
          KeyEvent event) {
        Toast.makeText(MainActivity.this, "Search triggered",
            Toast.LENGTH_LONG).show();
        return false;
      }
    });
    actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM
        | ActionBar.DISPLAY_SHOW_HOME);


    }
BoldHD
la source
sauvé mes n heures .. Merci
CrazyMind
1

Il y a un exemple dans l'application de lancement d'Android (dont j'en ai fait une bibliothèque, ici), à l'intérieur de la classe qui gère la sélection de fonds d'écran ("WallpaperPickerActivity").

L'exemple montre que vous devez définir un thème personnalisé pour que cela fonctionne. Malheureusement, cela a fonctionné pour moi uniquement en utilisant le framework normal, et non celui de la bibliothèque de support.

Voici les thèmes:

styles.xml

 <style name="Theme.WallpaperPicker" parent="Theme.WallpaperCropper">
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:colorBackgroundCacheHint">@null</item>
    <item name="android:windowShowWallpaper">true</item>
  </style>

  <style name="Theme.WallpaperCropper" parent="@android:style/Theme.DeviceDefault">
    <item name="android:actionBarStyle">@style/WallpaperCropperActionBar</item>
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowActionBarOverlay">true</item>
  </style>

  <style name="WallpaperCropperActionBar" parent="@android:style/Widget.DeviceDefault.ActionBar">
    <item name="android:displayOptions">showCustom</item>
    <item name="android:background">#88000000</item>
  </style>

valeur-v19 / styles.xml

 <style name="Theme.WallpaperCropper" parent="@android:style/Theme.DeviceDefault">
    <item name="android:actionBarStyle">@style/WallpaperCropperActionBar</item>
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowActionBarOverlay">true</item>
    <item name="android:windowTranslucentNavigation">true</item>
  </style>

  <style name="Theme" parent="@android:style/Theme.DeviceDefault.Wallpaper.NoTitleBar">
    <item name="android:windowTranslucentStatus">true</item>
    <item name="android:windowTranslucentNavigation">true</item>
  </style>

EDIT: il existe une meilleure façon de le faire, qui fonctionne également sur la bibliothèque de support. Ajoutez simplement cette ligne de code au lieu de ce que j'ai écrit ci-dessus:

getSupportActionBar().setDisplayShowCustomEnabled(true);
développeur android
la source