Android: Global style for all Spinners in my app - android

I'm using Xamarin Android in Visual Studio 2017.
I have a few existing Spinners which are created in xml layout which all work perfectly and are styled exactly how I want them to look. The code for these is typically:
<Spinner
android:spinnerMode="dialog"
android:id="#+id/SpnProject"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_marginBottom="8dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:background="#drawable/myspinner"
android:prompt="#string/project_prompt" />
That works great and my little background image is all rendered correctly..
Now I am trying to create some other spinners dynamically, 100% through code (not layout XML). I'm putting them inside a LinearLayout dynamically with my code.
To create one of these, the code is typically:
Spinner CustomPicker = new Spinner(TheActivity);
List<CustomAttributeOption> AttOptions = db.GetCustomAttributeOptions(ThisAtt.AttributeId);
ArrayAdapter<CustomAttributeOption> AttOptionsAdapter = new ArrayAdapter<CustomAttributeOption>(Activity, Android.Resource.Layout.SimpleSpinnerDropDownItem, AttOptions);
CustomPicker.Adapter = AttOptionsAdapter;
customAttributeHolder.AddView(CustomPicker, StackerPosition);
This code all completely works and a new dynamic Spinner appears on my form.
But it has default styling and I want to apply the same styles as my other spinners, specifically, I want these dynamic spinners to have a specified height = 40dp. I can't seem to be able to specify layoutHeight=40dp anywhere using code? Does it have to be done using styles/xml?
I played around a lot trying to setup a Theme and specifying a style for all Spinners in my Activity, but the app wouldn't build or run.
Ideally, I'd really like to remove the layout_height and layout_width values out of layout XML and just have it defined somewhere ONCE like in a global style for ALL SPINNERS IN MY ENIRE PROJECT kind of thing.
Can this be done, or are you forced to specify width and height for every single widget on a case by case basis?

You can use the layout inflater in order to "auto-magically" apply the styles you can defined.
Lets assume you have a "global" style for your Spinner:
<style name="MySpinnerStyle" parent="android:Widget.Spinner">
<item name="android:spinnerMode">dialog</item>
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">40dp</item>
<item name="android:layout_marginBottom">8dp</item>
<item name="android:paddingTop">8dp</item>
<item name="android:paddingBottom">8dp</item>
<item name="android:paddingStart">8dp</item>
<item name="android:paddingEnd">8dp</item>
<item name="android:background">#drawable/myspinner</item>
<item name="android:prompt">#string/project_prompt</item>
</style>
Create an independent Layout for the dynamic Spinner(s) that you create that uses your global Spinner style
<?xml version="1.0" encoding="UTF-8" ?>
<Spinner xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/masterSpinner"
style="#style/MySpinnerStyle" />
Now instead of instancing a new Spinner, inflate the layout and all the associated properties will be assigned:
var spinner = LayoutInflater.Inflate(Resource.Layout.Spinner, rootLayout, false) as Spinner;
spinner.Adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleSpinnerItem, new string[] { "Stack", "Over", "Flow" });
customAttributeHolder.AddView(spinner, StackerPosition);

Related

Issues changing the color of views

So I am trying to change my app color to blue and some of most the views I have are not willing to cooperate with me.
Here is the image:
Here I want to change the color of the green parts on the spinner, edittext and checkbox views (which are green) to black or blue.
I've looked all over Stack Overflow and I can't find the solution!
Thank you very much, If possible I would like to have a XML solution but I wouldn't mind a programmatic solution!
Add these to your base theme in styles.xml
<item name="colorControlNormal">#color/YOUR_COLOR</item>
<item name="colorControlActivated">#color/YOUR_COLOR</item>
<item name="colorControlHighlight">#color/YOUR_COLOR</item>
Note: The above change will affect the EditTexts and other views probably throughout the application.
If not, and if you are using the AppCompat v22 support library, you can specify the theme in the EditText like: android:theme="#style/Theme.App.Base.
This will ensure the style won't also affect other views in your layouts that you don't want to change
Also if you want to change the above solution, just add another Theme specific to EditTexts and Spinners and apply it to all Spinners if you want
<style name="MyWidgetTheme">
<item name="colorControlNormal">#color/YOUR_COLOR</item>
<item name="colorControlActivated">#color/YOUR_COLOR</item>
<item name="colorControlHighlight">#color/YOUR_COLOR</item>
</style>
and in your EditText, Spinner or any other View, just assign this theme:
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Demo"
android:lines="1"
android:theme="#style/MyWidgetTheme"
/>
<Spinner
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="#style/MyWidgetTheme"></Spinner>
Take a look to this resource generator.
Choose your color, the widgets you want to generate and voila! You copy them to your project and reference them in your xmls.

Changing the font for the List Preference

i have a list preference in my application.
Have extended with a custom list preference.
Now i would like to keep the font of the preference entries according to my styling . (Don't want to have it changed according to the Device's fond settings).
I don't want to change any UI but only the styling like font size , font type etc.
Is it possible to do so. ?
cheers,
Saurav
You can create a custom style in XML, in a <resources> tag (not the listView layout), and then in the single item XML layout you can add Style = "#Style/mystyle" etc.
For example, there is a style.xml file already in values, and you could add:
<style name="ListViewStyle" >
<item name="android:textColor">#000000</item>
<item name="android:textSize">20dp</item>
</style>
and then in the listView xml:
<TextView
style="#style/ListViewStyle"
android:id="#+id/mainListView"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />

How to set style for spinner programmatically?

I have spinner with a style selection (I set the spinner style in strings.xml) and it's works well if I set the style in main.xml. But I want to know how to set the style programmatically in which the style already defined in strings.xml.
Refer my code below
main.xml:
<Spinner
android:id="#+id/PassengersSpinner1"
android:layout_width="100dp"
android:layout_height="40dp"
android:layout_span="3"
android:layout_marginTop="6dp"
style="#style/SpinnerStyle" />
strings.xml:
<style
name="SpinnerStyle"
parent="#android:style/Widget.Spinner">
<item name="android:background">#android:drawable/btn_default</item>
</style>
Now, I want to know that how can I set this strings.xml programmatically without main.xml?
From all my reading, you cannot do it, because the style has to be set before the view is created.
You can do it if you create the view in code (since then you can set the style before creating the view).
If you want to do that, a good example is here. Both the question and the answer give you methods to achieve your goal.

Android: How to set text color for list items in AlertDialog properly

I have an AlertDialog in my application. It contains a list of custom views with TextView widgets inside. Everything works fine on Android 2.x. The AlertDialog is created with white list and black text in it. But when I run my app on Android 3.x devices all TextViews are black and list's background is black too. So I can't see the text until I tap and hold one of the items.
Here's a TextView's definition from the layout file:
<TextView
android:id="#+id/label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceSmallInverse" />
I thought that using textAppearanceSmallInverse for the textAppearance attribute is a proper way to set text parameters and it must work on all devices but seems I was wrong. So what should I do to make AlertDialog display list items properly on all platforms? Thanks in advance.
The solution is to leverage Android's built-in resource selection system. You should specify two different styles and place them in the proper folders based on the API version. Note that the following examples are not mine, I took them from this tutorial.
res/values-v4/styles.xml:
<resources>
<!-- Text for listboxes, inverted for Andorid prior to 3.0 -->
<style name="MyListTextAppearanceSmall">
<item name="android:textAppearance">?android:attr/textAppearanceSmallInverse</item>
</style>
<style name="MyListTextAppearanceDefault">
<item name="android:textAppearance">?android:attr/textAppearanceInverse</item>
</style>
<style name="MyListTextAppearanceMedium">
<item name="android:textAppearance">?android:attr/textAppearanceMediumInverse</item>
</style>
</resources>
res/values-v11/styles.xml:
<resources>
<!-- Text for listboxes, non-inverted starting with Android 3.0 -->
<style name="MyListTextAppearanceSmall">
<item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
</style>
<style name="MyListTextAppearanceDefault">
<item name="android:textAppearance">?android:attr/textAppearance</item>
</style>
<style name="MyListTextAppearanceMedium">
<item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
</style>
</resources>
Then, in your TextView, specify the style like so:
<TextView
android:style="#style/MyListTextAppearanceSmall"
android:id="#+id/label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="marquee" />
See the tutorial linked above for a lengthier explanation.
Your code for the popup dialog should look similar to this:
// Sets dialog for popup dialog list
AlertDialog dialog;
String[] items = {"exampleItem"};
ListAdapter itemlist = new ArrayAdapter(this, android.R.layout.simple_list_item_1, items);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Title");
builder.setAdapter(itemlist, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
}
});
dialog = builder.create();
dialog.getListView().setBackgroundColor(Color.WHITE);
Here, you are getting the listview and setting the background color to white. If you want to change the color of the text for each of the textviews then you need to define their color in the layout of the textview, in this case black:
android:textColor="#000000"
The accepted answer seems like a bit of overkill. I simply forced the inverse background by calling:
dialogBuilder.setInverseBackgroundForced(true);
solves the problem just fine.
This probably happens because you aren't specifying a theme, then it falls back to the default theme. In 2.x this should be Theme.Black and in 3.x Theme.Holo (or Theme.Light, not sure on this). Then textAppearanceSmallInverse resolves to different style in each theme.

How do I change the text style of a spinner?

I'm creating a spinner in my layout xml files and setting an string array to this spinner.
If I change the textstyle of the spinner the text is not affected by the changes.
I read in the googlegroups that a spinner has no text and therefore the textstyle can not be changed and I have to change the style of the textview that is shown in the spinner. But how can I do that. Preferably in my xml file.
As my predecessor specified, you can't do it on the main XML layout file where the Spinner component is.
And the answer above is nice, but if we want to use Google's best practices, like you know... to use styles for everything... you could do it in 3 'easy' steps as follows:
Step 1: You need an extra file under your layout folder with the look for the Spinner's items:
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:id="#+id/textViewSpinnerItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/SpinnerTextViewItem"
xmlns:android="http://schemas.android.com/apk/res/android" />
Name this file: spinner_item_text.xml
Step 2: Then, on your Activity Class when you are filling the Spinner with an array of items:
adapter = new ArrayAdapter<CharSequence>(this, R.layout.spinner_item_text, items);
spinner.setAdapter(adapter);
Note that the R.layout.spinner_item_text resource is in your own R's file.
Step 3: Under your values folder, create or use (you might have one already) the file styles.xml. The style entry needed should look like this one:
<style name="SpinnerTextViewItem" parent="#android:style/Widget.TextView" >
<item name="android:textSize" >8dp</item>
<item name="android:textStyle" >bold</item>
</style>
And that's it!
So far it has been really, really handy to put all about text sizes, styles, colors, etc... on a styles.xml file so it's easy to maintain.
Via XML Only
As a follow-up to #Cyril REAL's excellent answer, here is a thorough implementation of how to style your Spinners just through XML if you're populating your Spinner via android:entries.
The above answers work if you're creating your Spinner via code but if you're setting your Spinner entries via XML, i.e. using android:entries, then you can adjust the text size and other attributes with the following two theme settings:
In your res/values/styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppBaseTheme" parent="android:Theme.Holo">
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<!-- For the resting Spinner style -->
<item name="android:spinnerItemStyle">
#style/spinnerItemStyle
</item>
<!-- For each individual Spinner list item once clicked on -->
<item name="android:spinnerDropDownItemStyle">
#style/spinnerDropDownItemStyle
</item>
</style>
<style name="spinnerItemStyle">
<item name="android:padding">10dp</item>
<item name="android:textSize">20sp</item>
<item name="android:textColor">#FFFFFF</item>
</style>
<style name="spinnerDropDownItemStyle">
<item name="android:padding">20dp</item>
<item name="android:textSize">30sp</item>
<item name="android:textColor">#FFFFFF</item>
</style>
</resources>
When you create the Adapter that backs the Spinner you can set a layout for the spinner item.
spinner.setAdapter(new ArrayAdapter(this, R.id.some_text_view));
You can style some_text_view the way you want.
<TextView android:id="#+id/some_text_view" android:textStyle="bold" />
Actually you can customize spinner's text by xml.
In your own style, define a :
<item name="android:spinnerItemStyle">#style/yourStyleForSpinnerItem</item>
and define this style also :
<style name="yourStyleForSpinnerItem">
// Stuff you want for the item style.
</style>
When you instantiate the spinner's adapter in the java code, you can use the default android.R.layout.simple_spinner_item
If you don't want such workarounds, there's a simple way. Get the textview from the spinner and change its parameters:
TextView tv = (TextView) spin.getSelectedView();
tv.setTypeface(Typeface.DEFAULT_BOLD); //to make text bold
tv.setTypeface(Typeface.DEFAULT); //to make text normal
if you want just change background of popup View in spinner, call this method:
spinner.setPopupBackgroundResource(R.color.pa_md_white);

Categories

Resources