29

I'd really like my app to have a Spinner which stretches the entire length of my ActionBar, like the one in Gmail 4.0. Anyone know how to achieve this? Even if I set "match_parent" in the Spinner layout resource, it doesn't fill the entire bar. Preferably, I'd like to be able to have it fill the entire bar except for my action items, rather than using the split actionbar as well.

EDIT: see my answer below for an implementation using the built-in actionbar, or hankystyles' when using a custom view

enter image description here

Alex Curran
  • 8,818
  • 6
  • 49
  • 55
  • How about paddings - does the image resource for the button itself include a bit of padding? – Scalarr Feb 01 '12 at 22:19
  • Do you have multiple accounts set up? Mine also spans all the way to the right like yours do, but I think that's mainly because I have several accounts set up. The content of the 'drop down' (or what it's called) is then different - and wider. – hnilsen Feb 03 '12 at 23:20
  • 1
    yeah, I've got 2 accounts set up. It's kinda of strange to have it different depending on how many accounts you have! – Alex Curran Feb 04 '12 at 15:48

4 Answers4

28

Bit annoying that I've just done it, but here is a method of doing it using the built-in Spinner in the action bar. All you need to do is make your spinner item's main container a RelativeLayout and set its gravity to fillHorizontal, like so:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/RelativeLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="fill_horizontal"
android:orientation="vertical" >

<TextView
    android:id="@android:id/text1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:layout_marginBottom="-4dip"
    android:text="@string/gen_placeholder"
    android:textAppearance="?android:attr/textAppearanceMedium" />

<TextView
    android:id="@+id/TextView1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_below="@android:id/text1"
    android:text="@string/app_name"
    android:textAppearance="?android:attr/textAppearanceSmall" />

</RelativeLayout>

And initialising the Adapter as so:

ArrayAdapter<CharSequence> barAdapter = new ArrayAdapter<CharSequence>(this, R.layout.subtitled_spinner_item, 
    android.R.id.text1, getResources().getStringArray(R.array.actionList));
barAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

which then gives the required spinner spanning the entire actionbar (except for the action buttons):

Spanned actionbar

Alex Curran
  • 8,818
  • 6
  • 49
  • 55
  • 1
    Can you expand on what you mean by setting the spinner item's "main container"? Any chance you could give an example of how you added the above layout? – brk3 Feb 16 '12 at 21:19
  • I mean the enclosing layout of your spinner item. The xml code above generates the full-width spinner as shown. – Alex Curran Feb 16 '12 at 21:32
  • So do you need a custom adapter to go with this? – brk3 Feb 16 '12 at 21:46
  • Nope! I just used an `ArrayAdapter`, then passed the xml resource as shown above to the `setDropDownResource(..)` method. – Alex Curran Feb 16 '12 at 22:01
  • Ok :) I think Im close.. Here's the code Im using: ArrayAdapter list = ArrayAdapter.createFromResource(this, R.array.locations, R.layout.actionbar_main); R.layout.actionbar_main contains the xml above. The problem is I need to somehow pull out the id of the textview to pass to the adapter. Do you need to inflate it? Thanks for the help.. – brk3 Feb 16 '12 at 22:05
  • I've added the code used to initialise my adapter, I didn't use `createFromResource(..)` because I don't think it's as flexible. subtitled_spinner_item is the xml layout in the post. – Alex Curran Feb 16 '12 at 22:14
  • This works really nice. However, I'm trying to get the View for the selected item (I need to modify the static part of the text). I've tried barAdapter.getView() but this just got me a new View, not the one that is selected so modifying it didn't change anything. – Tim van Dalen May 25 '12 at 21:20
  • @ Espiandev - Any way to do this without losing the action bar title and subtitle? Once I set the textview width to match_parent the title of the activity gets cut off. I'm actually NOT using any action items, i'd just like to have the home icon, title, and spinner. – dell116 May 31 '12 at 18:55
  • 1
    I think on phones its designed so that you only see the spinner or the title, not both. Might be worth having the spinner show the title at all times, like how in the example above the second text view only shows "Formulae" - nothing else. – Alex Curran May 31 '12 at 19:17
  • ...that's exactly what my boss just suggested....thanks for your reply and this post! Helped me out a lot! – dell116 May 31 '12 at 19:24
  • @Espiandev how do you add those 3 dots at right side of the ActionBar ? – h4ck3d Jul 14 '12 at 18:40
  • @Espiandev > is there a way to have the **selected** item content (In this case the first item text : "Chemistry") **WRAPPED** in the spinner ? Like for Google Maps Actionbar spinner items for example. – kaffein Sep 26 '12 at 13:05
  • I think not using a RelativeLayout and setting everything's width to wrap_content should do the trick. – Alex Curran Sep 26 '12 at 21:03
  • Thanks for the answer, it's helped me in several ways. However, if I use match_parent on all items it pushes the other action icons off the screen. How did you keep your overflow and search button as shown? – Josh Oct 20 '12 at 15:08
  • Is it possible to customize the spinner, and also get the spinner view itself to make operations on it programmatically ? – android developer May 22 '14 at 09:31
  • How did you add the spinner to the action bar? @AlexCurran – Erich Mar 09 '15 at 05:50
20

The spinner on my gmail app also spans the entire width of my action bar. This solution worked for me:

View spinner = getLayoutInflater().inflate(R.layout.actionbar_spinner, null);
actionBar.setCustomView(spinner);
actionBar.setDisplayShowCustomEnabled(true);

Where the spinner layout is like so:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="fill_horizontal" >
    <Spinner 
        android:id="@+id/spinner"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:prompt="@string/spinner_text"
    />
</RelativeLayout>

I suspect there's a better solution to be had by overriding the default action bar navigation style like this but I couldn't immediately get that working.

hankystyles
  • 511
  • 2
  • 8
  • ah brilliant, thanks. I'd prefer an implementation which uses the standard navigation controls (i.e. not a custom view), but if no-one give me one by the end, I'll award the bounty. – Alex Curran Feb 03 '12 at 18:23
0

If you have a TextView inside your Spinner, you can set the minEms to a high value. This is the easiest workaround I explored:

<?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="fill_parent"
    android:gravity="center_vertical">

    <TextView
        android:id="@+id/spinner_active"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:text="blaa"
        android:minEms="100"
        android:textSize="20sp" />

</LinearLayout>
Fabian Knapp
  • 1,342
  • 13
  • 27
0

Try setting the background of the spinner to an image file. The default background has caused me layout issues, but when I set it to my own png of a blank 1x1 pixle it filled my layout as I wanted. If that works you may have to create a custom image that works for you. I hope that helps.

Skyler Lauren
  • 3,792
  • 3
  • 18
  • 30