Customizing spinners' spacing

后端 未结 1 573
陌清茗
陌清茗 2021-02-15 18:56

Spinners provide two states. The first and default state (state A) shows the currently selected value. The second (state B) shows a dropdown menu when the spin

1条回答
  •  梦谈多话
    2021-02-15 19:35

    State A takes on the following style:

    // Theme (Base) // Theme.AppCompat
    @android:style/Widget.TextView.SpinnerItem
    
    // Holo & Holo Light
    @android:style/Widget.Holo.TextView.SpinnerItem
    

    The attribute at play here is spinnerItemStyle.

    Moreover, the padding provided is not paddingLeft, but paddingStart - to support LTR & RTL languages. Similarly, paddingEnd is set instead of paddingRight. This info applies to API >=17.

    If you are using AppCompat, you will still override the spinnerItemStyle attribute, but provide paddingLeft and paddingRight.

    Example:

    
    
    
    

    The 40dp value is for testing if setting this style even works. This should only pad State A(with 40dp), leaving State B with default padding of 8dp. Once confirmed, you can make it 0dp, or as per your requirement.

    This is the result I get:

    enter image description here

    Update:

    In reference to the sample project - MainActivity:

    spinner.setAdapter(ArrayAdapter.createFromResource(this,
                R.array.planets_array, android.R.layout.simple_spinner_item));
    

    By giving the adapter android.R.layout.simple_spinner_item, you are telling it to use the layout for both State A and State B. This is a problem because of the way this layout is defined:

    
    

    Notice the style applied to this TextView. Earlier, I had suggested that you override this attribute. And it worked. But since this layout is used for both the states, the outcome is not as desired.

    In fact, the statement right above (though not doing anything at the moment) is more promising:

    ArrayAdapter.createFromResource(this,
                R.array.planets_array, android.R.layout.simple_spinner_item)
                .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    

    By using setDropDownViewResource(int), you will allow the possibility of introducing different style attributes. In this case, State A will be represented by android.R.layout.simple_spinner_item and State B will use android.R.layout.simple_spinner_dropdown_item.

    Let's take a look at android.R.layout.simple_spinner_dropdown_item:

    
    

    Now we can override another attribute - spinnerDropDownItemStyle - and give State B a whole different look. But, we won't. On Lollipop, spinnerDropDownItemStyle points to style Widget.Material.DropDownItem.Spinner which sets the paddingX to 8dp. And you said that you're okay with the default padding in State B.

    So, here's what you need:

    // Create an ArrayAdapter
    ArrayAdapter mAdapter = ArrayAdapter.createFromResource(this,
                R.array.planets_array, android.R.layout.simple_spinner_item);
    
    // State B
    mAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    

    AND, if you don't have this already, add it to values/styles.xml:

    
    
    
    

    You should also create values-v21/styles.xml and add:

    
    

    0 讨论(0)
提交回复
热议问题