How can I fix the Spinner style for Android 4.x placed on top of the Toolbar

后端 未结 15 715
别那么骄傲
别那么骄傲 2020-12-04 06:10

According to Android documentation, Material Design style is supported for Spinner widget.

So I decided to use it in my app placing it on top of the Toolbar.

<

相关标签:
15条回答
  • 2020-12-04 06:24

    I know this is late but I came accross this question when I encountered this problem myself and I found a solution in the BrowseSessionsActivity of the Google I/O 2014 app and adapted it.

    Layouts

    toolbar_spinner.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <Spinner
            android:id="@+id/toolbar_spinner"
            style="@style/Widget.MyApp.HeaderBar.Spinner"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"/>
    
    </LinearLayout>
    

    toolbar_spinner_item_actionbar.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:orientation="vertical">
    
        <TextView
            android:id="@android:id/text1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawablePadding="8dp"
            android:drawableRight="@drawable/spinner_triangle"
            android:fontFamily="sans-serif"
            android:paddingLeft="16dp"
            android:paddingRight="4dp"
            android:textColor="#ffffffff"
            android:textSize="18dp"
            android:textStyle="bold"/>
    
    </LinearLayout>
    

    The spinner_triangle drawable can be found here.

    toolbar_spinner_item_dropdown.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:orientation="vertical">
    
        <TextView
            android:id="@android:id/text1"
            android:layout_width="match_parent"
            android:layout_height="48dp"
            android:drawablePadding="8dp"
            android:gravity="center_vertical|start"
            android:paddingLeft="16dp"
            android:paddingRight="16dp"
            android:textColor="#ff333333"
            android:textSize="16sp"/>
            
    </LinearLayout>
    

    Styles

    toolbar_spinner.xml uses the following style.

    <style name="Widget.MyApp.HeaderBar.Spinner" parent="Widget.AppCompat.Light.Spinner.DropDown.ActionBar">
            <item name="android:background">?android:selectableItemBackground</item>
            <item name="android:dropDownSelector">?android:selectableItemBackground</item>
            <item name="android:divider">@null</item>
            <item name="android:overlapAnchor">true</item>
    </style>
    

    Adapter

    This adapter will need to be changed to match your own needs. getTitle() returns the text for each item shown in the spinner.

    private class YourObjectSpinnerAdapter extends BaseAdapter {
        private List<YourObject> mItems = new ArrayList<>();
    
        public void clear() {
            mItems.clear();
        }
    
        public void addItem(YourObject yourObject) {
            mItems.add(yourObject);
        }
    
        public void addItems(List<YourObject> yourObjectList) {
            mItems.addAll(yourObjectList);
        }
    
        @Override
        public int getCount() {
            return mItems.size();
        }
    
        @Override
        public Object getItem(int position) {
            return mItems.get(position);
        }
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    
        @Override
        public View getDropDownView(int position, View view, ViewGroup parent) {
            if (view == null || !view.getTag().toString().equals("DROPDOWN")) {
                view = getLayoutInflater().inflate(R.layout.toolbar_spinner_item_dropdown, parent, false);
                view.setTag("DROPDOWN");
            }
    
            TextView textView = (TextView) view.findViewById(android.R.id.text1);
            textView.setText(getTitle(position));
    
            return view;
        }
    
        @Override
        public View getView(int position, View view, ViewGroup parent) {
            if (view == null || !view.getTag().toString().equals("NON_DROPDOWN")) {
                view = getLayoutInflater().inflate(R.layout.
                        toolbar_spinner_item_actionbar, parent, false);
                view.setTag("NON_DROPDOWN");
            }
            TextView textView = (TextView) view.findViewById(android.R.id.text1);
            textView.setText(getTitle(position));
            return view;
        }
    
        private String getTitle(int position) {
            return position >= 0 && position < mItems.size() ? mItems.get(position).title : "";
        }
    }
    

    Adding the Spinner to Your Toolbar

    Toolbar toolbar = getActionBarToolbar();
    
    View spinnerContainer = LayoutInflater.from(this).inflate(R.layout.toolbar_spinner,
            toolbar, false);
    ActionBar.LayoutParams lp = new ActionBar.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
    toolbar.addView(spinnerContainer, lp);
    
    YourObjectSpinnerAdapter spinnerAdapter = new YourObjectSpinnerAdapter();
    spinnerAdapter.addItems(getMyObjectSpinnerData());
    
    Spinner spinner = (Spinner) spinnerContainer.findViewById(R.id.toolbar_spinner);
    spinner.setAdapter(spinnerAdapter);
    

    Result

    Material Spinner

    KitKat Spinner

    0 讨论(0)
  • 2020-12-04 06:26

    I am struggling with the exact same problem.

    Try to change the dropdown view resource. At least, this fixed the text color issue for me - however the arrow icon color is still dark. So this is just a partial workaround.

    setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    
    0 讨论(0)
  • 2020-12-04 06:32

    For correct Spinner icon tinting you can also just inflate the spinner from code:

    spinner_toolbar.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <Spinner xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/spinner_toolbar"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"/>
    

    Then you have to attach the Spinner to the Toolbar in your Activity:

    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getSupportActionBar().getThemedContext(),
                R.array.planets_array, R.layout.support_simple_spinner_dropdown_item);
    adapter.setDropDownViewResource(R.layout.support_simple_spinner_dropdown_item);
    spinner.setAdapter(adapter);
    
    // we inflate the spinner with the themed Toolbar context -> correct icon tinting
    LayoutInflater.from(getSupportActionBar().getThemedContext()).inflate(R.layout.spinner_toolbar, tb, true);
    
    Spinner spinner = (Spinner) toolbar.findViewById(R.id.spinner_toolbar);
    spinner.setAdapter(adapter);
    

    However, this uses the app:theme instead of the app:popupTheme for the whole Spinner, including the dropdown menu. Hence, the Spinner icon and text will be colored correctly, but the dropdown menu also has the style of the toolbar and not of the popupTheme.

    So if you want to have a dark Toolbar and a light dropdown menu, you would need to fix the dropdown style somehow, for example by creating a custom style for the spinner that specifies a white background and a custom dropdown view with a dark text color.

    Maybe somebody else has a better solution on how the app:popupTheme can be propagated to the Spinner dropdown menu.

    0 讨论(0)
  • 2020-12-04 06:35

    A simple way that isn't perfect, but uniform enough for both 4.x and 5.0

    img

    I removed the <Spinner> from the layout files and added it programmatically - that allowed for the white triangle to show up properly.

    I also created a dropdown item layout using the appcompat required color.

    layout/spinner_dropdown_item.xml, note the android:background="@color/primaryColor"

    <?xml version="1.0" encoding="utf-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@android:id/text1"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:textAppearance="?android:attr/textAppearanceListItemSmall"
          android:gravity="center_vertical"
          android:paddingLeft="12dp"
          android:paddingRight="12dp"
          android:background="@color/primaryColor"
          android:minHeight="?android:attr/listPreferredItemHeightSmall" />
    

    And in the activity:

        SpinnerAdapter spinnerAdapter = ArrayAdapter.createFromResource(getApplicationContext(), R.array.your_array, R.layout.spinner_dropdown_item);
        Spinner navigationSpinner = new Spinner(getSupportActionBar().getThemedContext());
        navigationSpinner.setAdapter(spinnerAdapter);
        toolbar.addView(navigationSpinner, 0);
    

    It's not perfect and the items don't highlight when you click on them, but it's good enough while we wait for the future appcompat libraries to fix these problems (here's hoping anyway).

    0 讨论(0)
  • 2020-12-04 06:35

    Had the exact same issue with the spinner's

    What i did was to add a custom theme to spinner

     <Spinner
                    android:id="@+id/spinner1"
                    android:layout_width="match_parent"
                    android:layout_height="30sp"
                    android:entries="@array/guest_type"
                    android:prompt="@string/guesttype"
                    android:theme="@style/AppTheme1"   />
    

    styles.xml

      <style name="AppTheme1" parent="Theme.AppCompat.Light">
        <item name="android:spinnerDropDownItemStyle">@style/mySpinnerItemStyle</item>
    </style>
    
    <style name="mySpinnerItemStyle" parent="@android:style/Widget.Holo.DropDownItem.Spinner">
        <item name="android:textColor">#000000</item>
    </style>
    
    0 讨论(0)
  • 2020-12-04 06:35

    When i used spinner it crashed (Android 2.3.3 - 2.3.7).

    So i try to use TintSpinner now it's not crashing, Try your self as a Optional solution

     <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:orientation="vertical">
    
            <android.support.v7.internal.widget.TintSpinner
                android:id="@+id/toolbar_spinner"
                style="@style/HeaderBar.Spinner"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"/>
        </LinearLayout>
    

    And use below code to cast your toolbar

     View spinnerContainer = LayoutInflater.from(this).inflate(R.layout.toolbar_spinner, toolbarTop, false);
            ActionBar.LayoutParams lp = new ActionBar.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
            toolbarTop.addView(spinnerContainer, lp);
    
            ToolBarSpinnerAdapter spinnerAdapter = new ToolBarSpinnerAdapter(getLayoutInflater());
            String[] items = getResources().getStringArray(R.array.action_dropdown);
            spinnerAdapter.addItems(items);
    
            TintSpinner mNavigationSpinner = (TintSpinner) spinnerContainer.findViewById(R.id.toolbar_spinner);
            mNavigationSpinner.setAdapter(spinnerAdapter);
    
    0 讨论(0)
提交回复
热议问题