How to style android spinner boxes? - android

Apologies if this has already been answered, but I've been looking through answers/trying things for a couple of hours and I can't find anything.
I find the android spinner boxes too big:
For my taste, there is far too much grey space around the '80' and the '90' above. I'd like to make them less high and less wide.
However, I don't just want to set a pixel height/width, because of the lack of assurance that they'll look right on all devices.
They are set to wrap_content now. Is there any way to get it to wrap the content, but more tightly? There seems to be a fair amount of padding in there...
Many thanks!
EDIT:
I've made a little progress, I've figured out how to attach a style to a view, so now I am trying:
<Spinner
style="#style/spinner_style"
etc
and
<style name="spinner_style">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:paddingLeft">0dp</item>
<item name="android:paddingRight">0dp</item>
<item name="android:paddingTop">0dp</item>
<item name="android:paddingBottom">0dp</item>
<item name="android:layout_marginLeft">0dp</item>
<item name="android:layout_marginRight">0dp</item>
<item name="android:layout_marginTop">0dp</item>
<item name="android:layout_marginBottom">0dp</item>
</style>
However, this seems to have hardly any effect:
vs
before. How can I get the boxes really close to the text?
EDIT:
Bit more progress. This image seems to be the entire grey box plus drop down:
android:background="#android:drawable/btn_dropdown"
If I can find some way to make that smaller? Again, I have the challenge that I want it to wrap the text properly, so that I can be sure it will display well on all devices.
EDIT:
I think I'm going to use my own layout for the spinner, but in a way that wraps the text reliably - probably using a linear layout and setting the background color on that. I'll post back when I have the full code.

As you didn't share the a bit of your spinner, I will suggest some options that may help you:
if you are using android.R.layout.simple_spinner_dropdown_item as your spinner item layout (when it's closed)
ArrayAdapter<Integer> adapter = new ArrayAdapter<>(this,
android.R.layout.simple_spinner_dropdown_item, myList);
Then change it to android.R.layout.simple_spinner_item, the later one has little padding than the first.
If that still adds some padding, you can add android:theme="#android:style/Theme.Holo.Light.NoActionBar" attribute to your spinner xml, although this will change the spinner arrow
Another option is to create a custom spinner item, similarly replace the system layout with your item when creating the adapter.
here's the item layout (just a new a layout with a TextView with wrap_content width/height)
<?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">
</TextView>

OK this is what I have arrived at and it gives me this effect:
compared to what I get with the default Spinner which is:
I much prefer my version, but of course these things are subjective.
What I've done is to set my own layout and textview within the adapter (seems you can set both), so that my adapter-setting code looks like this:
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
R.layout.my_spinner_layout, R.id.dropdowntext, list);
adapter.setDropDownViewResource(R.layout.my_spinner_dropdown_layout);
spinner.setAdapter(adapter);
I was also obliged to create my own custom layout for the dropdown - R.layout.my_spinner_dropdown_layout above - because the spinner reuses the textview used for the unopened box when it draws the dropdown list, so the same textview needs to be available in both layouts.
I created two new xml layout files called my_spinner_layout.xml and my_spinner_dropdown_layout.xml
They look like this respectively:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLayoutDisplayName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:background="#DDDDDD"
android:gravity="center"
android:orientation="horizontal">
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/dropdowntext"
style="#style/spinner_style"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true" />
<ImageView
android:id="#+id/dropdownicon"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentTop="true"
android:contentDescription="TODO"
android:src="#drawable/dropdown" />
</LinearLayout>
and
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/dropdowntext"
style="#style/spinner_style"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true" />
Basically, I have replaced the default, which is TextView and a huge grey background image including a dropdown arrow, with a horizontal linear layout containing a TextView and a dropdown IMAGE, with a grey background.
Now the grey wraps to the content very nicely (I've added padding of 5dp).
Hope this helps someone, or if there's something wrong with it, perhaps someone will correct me.

I have really worked hard to find you the best solution for your problem but it seems to be no way to do so. The only way is to create a custom spinner as described in https://stackoverflow.com/a/37859442/11896005
Also, sorry if I was annoying just wanted to help you!

Related

Android how to center text of chip with fixed size?

I have a chip with 100dp of width but the text is not centered how I can center the text.
I use androidx with material library, I've tried put android:textAlignment="center" and android:gravity="center" but not work
<com.google.android.material.chip.Chip
android:id="#+id/chip"
style="#style/Widget.MaterialComponents.Chip.Choice"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="7:00" />
I have this
I want this
just now I faced with the same problem, and I solved it by set a chip property: android: textAlignment = "center". I tested your example and it works fine too, here the code that I tested:
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.google.android.material.chip.Chip
android:id="#+id/chip"
style="#style/Widget.MaterialComponents.Chip.Choice"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="7:00"
android:textAlignment="center"/>
</FrameLayout>
Also make sure that you don't set or change a chip's text alignment somewhere in your code.
The short answer:
Chips aren't meant to be used the way you are trying to use them. They are supposed to wrap your content. Therefore there isn't a clean way to align the text in the center.
There is a workaround tho, you can use Chip_textEndPadding and Chip_textStartPadding attributes, which will be kinda awkward I guess.
I don't really know what you are trying to achieve, I mean, what is your why? Is it a button? Is it suppose just to show some text?
Please describe the feature, or at least, part of it.
Anyway:
According to the material design guidelines
Chips allow users to enter information, make selections, filter content, or trigger actions. Chips should appear dynamically as a group of multiple interactive elements. Unlike buttons, which should be a consistent and familiar call to action, one that a user expects to appear as the same action in the same general area.
Does your feature as anything to do with this?
In case you want a clickable, circular component you can simply use material button.
There is a similar question that was asked at github.
as others said you can use textAlignment ...but i wanted to tell you that if your using a custom font it wont be perfectly vertically aligned. you can check here for explanation.
so i would make a custom style that inherits from chip styles and set the font padding for usage like this:
<style name="customStyle" parent="#style/Widget.MaterialComponents.Chip.Choice">
<item name="chipBackgroundColor">#color/white</item>
******* <item name="android:includeFontPadding">true</item> *************
</style>
then for the text appearance you can make another style:
<style name="CustomChipTextAppearance" parent="TextAppearance.MaterialComponents.Chip">
<item name="android:fontFamily">?attr/myFont</item>
<item name="android:textAlignment">center</item>
</style>
dont forget to force a bridge theme in xml:
<com.google.android.material.chip.Chip xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
style="#style/customStyle"
**** android:theme="#style/Theme.MaterialComponents.Bridge" ****
***** android:textAppearance="#style/CustomChipTextAppearance" *******
app:chipMinHeight="38dp"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
app:chipStrokeWidth="2dp"
app:rippleColor="#android:color/transparent"
tools:chipText="my chip" />
Use isTextAlignmentResolved,
For example, chipname.isTextAlignmentResolved() to do this programmatically.

How can I debug an Android style inheritance issue?

When doing web development, you can inspect an element and see which classes provide which css rules. Is there an equivalent for Android development?
TLDR; Here's an example of a style inheritance problem that I had and solved:
I had a dialog has the Holo theme, but the text color was dark, even when I tried to set the text color to white.
This is the dialog layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ListView android:id="#android:id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/Theme.Dialog"/>
</RelativeLayout>
In the style.xml resource:
<style name="Theme.Dialog" parent="android:style/Theme.Holo.Dialog">
<item name="android:windowTitleStyle">#android:style/TextAppearance.Large</item>
<item name="android:textColor">#color/solid_white</item>
<item name="android:windowNoTitle">true</item>
</style>
It turned out that I was using a Fragment whose Activity was a ListActivity, and it defined getView, which created the view from an xml style that set the text color to be dark. It would have liked to see what was setting the text color.
I agree with the comments on your question, but for future, if you want to get an idea of the view hierarchy (not styles) for your app - you can do so in Eclipse.
Run the app.
Window > Open Perspective > DDMS.
In the DDMS pane, click the icon to the left that looks like a stack of phones (next to the camera icon)
You can mouse around the screen and get a visual representation of the view hierarchy.
Might help in some way.

How to change the text background color of a opened Spinner on Android

I set this XML Style in my app, but when I open a Spinner I cant see the text.
This is where searching of information takes place.I don't really know what I am doing wrong.
This is the XML Style:
<style name="Theme.Color" parent="android:Theme">
<item name="android:textColor">#FFFFFF</item>
<item name="android:windowBackground">#drawable/fondo2</item>
</style>
This the XML of the Spinner:
<Spinner
android:id="#+id/spAnswers"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/tvSecurity"
android:entries="#array/box" />
And when I open a Spinner this happens, I cant see the text (text color is white).
I need to set the text color to another of the spinner only when it is open or the background of the text changes.
While Creating Adapter for your Spinner give custom layout instead of predefined one
Create xml named spinner_row.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/cust_view"
android:layout_width="match_parent"
android:textColor="#color/black"
android:textSize="12dp"
android:layout_height="36dp"
android:gravity="left|center_vertical"/>
Here you can change the color Text size and width and height of the Elements in the spinner by modifying this textview
Use it like this while creating Adapter
ArrayAdapter<String> adapter=new ArrayAdapter<String>(context, R.layout.spinner_row,yourlist);
The Last task is routine
spinner.setAdapter(adapter);
I hope this will help you.

How to make a View clickable that's underneath another already clickable View?

It was hard to give a descriptive title for this question!
I have an app widget in which I have some clickable buttons (using RemoteViews and PendingIntents as needed for app widgets) that are difficult to tap at their current size. To work around this without having to resize the actual button, I have placed larger, invisible, clickable FrameLayouts over these buttons to increase the clickable area. This works well, except the buttons also have selectors connected to them so that the background color for the images change when tapped. This selector no longer works when the FrameLayout covers the buttons since it's now actually the FrameLayout that's being tapped, not the buttons.
My question is if there's a way to somehow make it "click through" the FrameLayout so that the selector for the button is still triggered, or any other clever workaround that achieves the same effect? Applying the selector on the FrameLayout itself will make the background change much too large.
Below is a simplified example of what I'm doing. The actual layout I'm using is more complex, so any solutions that requires changing the layout may be more difficult to do than it may seem here. Also, the reason the FrameLayout is placed in a RelativeLayout is so that I have more freedom with the placement.
EDIT
The FrameLayout is placed on top of two other layouts, which is why I can't simply place it under the button. It needs to cover a larger area. I'm hoping I won't have to redo the entire layout to fix this problem.
LAYOUT
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageButton
android:layout_width="#dimen/size_myButton_w"
android:layout_height="#dimen/size_myButton_h"
android:layout_alignParentRight="true"
android:background="#drawable/selector" //NOT TRIGGERED! Covered by FrameLayout below.
android:src="#drawable/myButton" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
<!-- More stuff here! -->
</RelativeLayout>
<!-- Even more stuff here! -->
</LinearLayout>
<FrameLayout
android:layout_width="120dp"
android:layout_height="35dp"
android:layout_alignParentRight="true">
</FrameLayout>
</RelativeLayout>
SELECTOR
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#color/navy" />
<item android:state_focused="true" android:drawable="#color/white" />
<item android:drawable="#color/white" />
</selector>
Perhaps you could place your FrameLayout below the button, rather than on top. That way if they hit the actual button, you get your selector triggered and if they miss the button and still hit the FrameLayout...well, your selector won't get triggered, but your FrameLayout click listener will still get called.

Android: keep blue background after ListView selection

I have a ListView, and it works great on a phone. Now I am making a tablet UI, with the ListView on the left and details on the right.
When I touch an item, it flashes blue as long as it is pressed. I want to keep that blue color until another item is selected, just like the Gmail app on the Nexus 7.
What is the cleanest way to achieve that? I'd rather avoid setting backgrounds manually, I assume there is a way to mark an element as the "active" one and theme it accordingly.
What is the cleanest way to achieve that?
What you are looking for is known as the "activated" state. To make this work:
Step #1: In res/values-v11/, have a style resource that implements activated. For example, for a new project that has the AppTheme declaration defined there, go with something like:
<resources>
<style name="AppTheme" parent="android:Theme.Holo.Light"></style>
<style name="activated" parent="AppTheme">
<item name="android:background">?android:attr/activatedBackgroundIndicator</item>
</style>
</resources>
Step #2: Define the same style in res/values/ for any older devices, just as a stub style resource, so references to it continue to work:
<resources>
<style name="AppTheme" parent="android:Theme.Light"/>
<style name="activated" parent="AppTheme"/>
</resources>
Step #3: In your layout XML resource for the row in the ListView, add style="#style/activated" to the list of attributes of the root element
Step #4: Set the ListView to be a single-choice list, such as the following line in a ListFragment:
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
You can see this in action in this sample project, this sample project, and this sample project. For more background on those first two samples, see this SO question: Complete Working Sample of the Gmail Three-Fragment Animation Scenario?
Using
android.R.layout.simple_list_item_activated_1
instead of
R.layout.simple_list_item_checkable_1.
Just for somebody checking someday.
after days of search and pulling my hair i just found out that activatedBackgroundIndicator is also available in ActionBarSherlock styling system. Most of the devs which develop backwards compatible apps, use ActionBarSherlock,so using ActionBarSherlock is a good option for most cases. So instead of using android:background="?android:attr/activatedBackgroundIndicator" which will give errors in android versions prior to 11, just use: android:background="?activatedBackgroundIndicator"
here is the example row layout xml code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
//note the activatedBackgroundIndicator
android:background="?activatedBackgroundIndicator"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingBottom="2dip"
android:paddingTop="2dip" >
<TextView
android:id="#+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingLeft="6dip"
android:paddingRight="6dip"
android:textSize="15sp" />
<TextView
android:id="#+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingRight="5dip"
android:textSize="20dip" />
</LinearLayout>

Categories

Resources