B4A Class SLSPinner - Android 4 style spinner for all API's

This is a plugin replacement for the standard spinner styled as the spinner in Android 4. I redesigned an app using the Android 4 spinner and then hated it running on earlier versions with the old style spinner, so I created this.

I've added several additional functions to the normal Spinner. You can change more of the appearance, List Border color, List Border width, List width, List height (within certain constraints), Item Heights etc.

I've also added an option to allow a touch on the button when the list is displayed, to return the button value as if it were selected from the list - ButtonTouchSelect, something I needed used with manual ordering of a list.

The background icon is drawn in code, so you can change it add a different graphic or change the colors as you please, or you can just use the defaults.

The Pressed and Focused colors in the state list drawable are taken from the Hololight Theme if it's available, if not the defaults are used. If for some reason neither are available, the Class will create it's own.

This is a custom view class, which you can also add manually to your code. The example shows both and includes a standard spinner for comparison.

I've tested it on various devices and API levels, please let me know if you find any problems.

The code is included so you can poke about and change anything you don't like. If you make improvements, please repost.

This is new software, and is quite complex in places. Please test thoroughly in any apps you plan to use it in.

SLSpinner
Author:
Steve Laming
Version: 0.9

  • Methods:
    • Add(Item As String) As String
      Add an item to the spinner

      AddAll(List As List) As String
      Add all items from a List of Strings to the spinner

      Background As Object
      Get or Set the background for the visible Button. Can be one of: BitmapDrawable, ColorDrawable, GradientDrawable or StateListDrawable
      Returns a drawable of the type that was initially or subsequently set


      BringToFront As String
      Changes the Z order of this view and brings it to the front.

      ButtonTouchSelect As boolean
      Gets or sets whether a touch on the button passes the currently selected item as a selection
      Default is False


      Clear As String
      Clear all items from the Spinner

      Color(Color As int) As String - [Write Only]
      Sets the background of the Button to be a ColorDrawable with the given color.

      DropDownTextColor As int
      Get or set the DropDownTextColor

      Enabled As boolean
      Enable / Disable the spinner

      GetItem(Index As int) As String
      Get Item at index from the list

      Gravity As int
      Gets or sets the Gravity for the displayed Button and drop down List

      Height As int
      'Gets or sets the height of the displayed View

      IndexOf(Value As String) As int
      Returns the index of Value in the Spinner or -1 if not found

      Initialize(TargetModule As Object, EventName As String) As String
      Initializes the object.
      Required for both designer and code setup.
      Provides callback {EventName}_ItemClick(Position As Int,Value As Object)


      Invalidate As String
      Invalidates the view, forcing it to redraw itself.

      IsInitialized As boolean
      Returns True if the View has been initialized. For a manually added Spinner, setup must have also been called

      ItemHeight As int
      Gets or sets the ItemHeight. Default height is 48Dip

      Left As int
      Gets or sets the view's left position.

      ListBorderColor(Color As int) As String - [Write Only]
      Sets the List Border Color . Default = Colors.ARGB(120,35,35,35) and gives a shadow effect

      ListBorderSize(Size As int) As String - [Write Only]
      Set the List Border Size. Default = 5Dip Set to '0' to hide the border

      ListColor(Color As int) As String - [Write Only]
      Sets the background of the List to be a ColorDrawable with the given color.

      ListHeight As int
      Gets or sets the lists height excluding any border
      Seting this will be ignored if it would make the height of the list go off the screen, so that the list can scroll fully.


      ListWidth As int
      Gets or sets the lists width excluding any border

      RemoveAt(Index As int) As String
      Removes the item at the specified index.

      RemoveView As String
      Removes this view from its parent.

      RequestFocus As boolean
      Tries To set the focus To this View.
      Returns True If the focus was set.


      SelectedIndex As int
      Gets or sets the index of the selected item. Returns -1 if no item is selected.

      SelectedItem As String - [Read Only]
      Returns the value of the selected item. Returns an empty string if no item is selected.

      SendToBack As String
      Changes the Z order of this view and sends it to the back.

      SetBackgroundImage(Image As Bitmap) As String
      Set the Spinner Buttons background image

      SetLayout(Left As int, Top As int, Width As int, Height As int) As String
      Changes the view position and size.

      Setup(Act As Activity, Pnl As Panel, Left As int, Top As int, Width As int, Height As int) As String
      Use when setting up the CustomView manually. Pass an initialized panel to add the Spinner to or Null to add to the Activity

      Size As int - [Read Only]
      Returns the number of items in the list.

      Tag As Object
      Gets or sets the Tag value. This is a place holder which can used to store additional data.

      TextColor As int
      Gets or sets the Buttons text color.

      TextSize As float
      Get or sets the text size. Default for a customview is 14, default for a Spinner is 16

      ToggleList As String
      Show / Hide the drop down list

      Top As int
      Gets or sets the view's top position.

      TypeFace As Typeface
      Get or set the Typeface used by the spinner

      Visible As boolean
      Gets or sets the spinners Visibility

      Width As int
      Gets or sets the view's width. If you have set listwidth, setting this will only effect the Button width

      Depends on:
      javaobject, reflection

Version 0.9 attached with example. You can compile the module to a library if you prefer.

Added pre3.2 for those without the latest javaobject
 

Attachments

  • SLSPinner.zip
    16.8 KB · Views: 863
  • SLSPinnerPre3.2.zip
    15.4 KB · Views: 695
Last edited:

stevel05

Expert
Licensed User
Longtime User
No I hadn't thought about that, if the parent is a scroll view, it's position will have to be recalculated each time it's accessed.
 

tdocs2

Well-Known Member
Licensed User
Longtime User
Thank you, Steve, for this and all of your contributions to the forum.

The SLSPinner contains some of the attributes which should be part of the V4 Standard Spinner. It is simply just a better spinner.

For those who do not have a device with an pre 4 Android version, you can simulate the "standard spinner" behavior by adding this line to the manifest:

B4X:
SetActivityAttribute(main, android:theme, "@android:style/Theme.Translucent")

I came to this discovery, not by brilliant wisdom, but merely by chance since I ran into the issue of a spinner reverting back to "pre Android 4" when I added this line to the Manifest Editor.

I created a new thread related to a question on the behavior of other views when Theme.Traslucent is used:

http://www.b4x.com/android/forum/threads/translucent-theme-affects-behavior-of-some-views.44932/

Best regards.

Sandy
 
Last edited:

bluedude

Well-Known Member
Licensed User
Longtime User
Pretty cool but gravity right is not working properly, items are almost not visible.
 

stevel05

Expert
Licensed User
Longtime User
Hi BlueDude,

The border was covering part of the listview item, try the attached.
 

Attachments

  • slspinner2.zip
    15.7 KB · Views: 169

bluedude

Well-Known Member
Licensed User
Longtime User
Good start but not completely, see attached screen for two issues. When gravity is right the selected value is too much to the right (on top of the selection triangle). Second, when the dropdown is generated gravity is center.

Where exactly can I fix this in the code? Maybe some padding on top of gravity would be flexible.

One other thing I was wondering is how to set the border the same as the background of the list.
 

Attachments

  • Screenshot_2014-10-24-09-36-55.png
    Screenshot_2014-10-24-09-36-55.png
    41.8 KB · Views: 253

stevel05

Expert
Licensed User
Longtime User
With this version I've added a ButtonPadding(Left,Top,Right,Bottom) Method, so you can set the padding as you want it. You will need to do a Bit.Or on the Gravity, Bit.Or(Gravity.Right,Gravity.Center_Vertical) or it will set gravity to Right Top by default.

You can change the border color using the ListBorderColor method.
 

Attachments

  • slspinner3.zip
    15.8 KB · Views: 156

bluedude

Well-Known Member
Licensed User
Longtime User
The padding is cool and a solution but my problem is the gravity in the dropdown, see attached picture. It also needs to put values at the right. Not sure why it displays some pixels from the left when the width becomes bigger.
 

Attachments

  • Screenshot_2014-10-24-15-51-17.png
    Screenshot_2014-10-24-15-51-17.png
    43.3 KB · Views: 234

stevel05

Expert
Licensed User
Longtime User
Hi bluedude, it's a while since I've looked at this I have to go out this evening, so I'll take a better look tomorrow.
 

stevel05

Expert
Licensed User
Longtime User
OK, try this one. The reason was that the label width in the list was not being adjusted, it should work now. I've also put 20Dip right padding in as default which you can still change if needed.
 

Attachments

  • slspinner4.zip
    15.8 KB · Views: 152

bluedude

Well-Known Member
Licensed User
Longtime User
Hi, that works great! One other question. I want to adapt the backcolor, border automatically to the Android OS it runs on. Just like the default spinner.

Any suggestions?
 

bluedude

Well-Known Member
Licensed User
Longtime User
Hi, also setting the listborder smaller will kill gravity settings in dropdown.

Backcolor adaption works BTW.
 

bluedude

Well-Known Member
Licensed User
Longtime User
One very tiny styling thing. Can the dropdown text be right gravity with some kind of offset? When there is a scollbar the scrollbar is over the text, would like do have the text slightly more to the left (padding or offset).

Would like to know how to change it myself.
 

stevel05

Expert
Licensed User
Longtime User
Hi Bluedude,

The attached fixes the first issue, changing the border width reset the width of the label, (see Sub setListBorderSize) I have changed this to use the current size.

The default padding is set in Sub SetUpButton, you can change the value (currently 20) as you like.

When you're happy with this, I'll upload it to the first post.

Thanks

Steve
 

Attachments

  • slspinner5.zip
    15.8 KB · Views: 191

bluedude

Well-Known Member
Licensed User
Longtime User
Hi, the issue I'm talking about is the problem in the dropdown where all the values show. Gravity right works but the values are really tight to the right edge, it does not look too good especially when there is a scroll feature.

The padding is not working in the list.
 

stevel05

Expert
Licensed User
Longtime User
OK, I'm with you. I thought it would be as simple as adding padding to the SPList.SingleLineLayout.Label, but that's causing a ClassCastException. I'm out for the rest of the day, I'll try and take a look tomorrow.
 

johndb

Active Member
Licensed User
Longtime User
OK, I'm with you. I thought it would be as simple as adding padding to the SPList.SingleLineLayout.Label, but that's causing a ClassCastException. I'm out for the rest of the day, I'll try and take a look tomorrow.

Is Spinner5.zip the latest or has the first post been updated with the latest revisions?
Has the issue related to placing the spinner on a scrollview been resolved?
 
Last edited:

stevel05

Expert
Licensed User
Longtime User
Hi John,

Spinner5 is the latest version, this issue was not completed. If it causes you any problems I'll add it to my current list and revisit it when I get a chance.

Steve
 

ArminKH

Well-Known Member
Hi stevel
Thank u 4 sharing this usefull class
What is the difference between normal version and pre version?
The difference is in android version or basic version?
I use normal version now,thats okay in all android version?
Tnx again
 

stevel05

Expert
Licensed User
Longtime User
There is no functional difference, just the code syntax is slightly different for the Pre 3.2 version.
 

ArminKH

Well-Known Member
Ok tnx
But which version we can use?the first post link is updated?because i have same issue with right edge padding with persian and arabic language(right to left)
Now we must download your lib from first post or download slspinner5 ?
 
Top