Android: Global style for all Spinners in my app

2019-07-07 17:57发布

问题:

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?

回答1:

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);