2

在 Android 2.2 上,我的 ActionBar 中的 Spinner 看起来非常难看,下拉文本颜色与背景颜色相同。这使文本不可读。

在此处输入图像描述

这是相关的代码。

spinner = new Spinner(getSupportActionBar().getThemedContext());
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>
(
    getSupportActionBar().getThemedContext(), 
    R.layout.sherlock_spinner_dropdown_item, 
    new String[]{"All", "Solved", "Unsolved"}
);
spinner.setAdapter(spinnerArrayAdapter);

Edit: I have added the below 3 lines for completeness.

menu.add("Display")
    .setActionView(spinner)
    .setShowAsAction(MenuItem.Show_AS_ACTION_ALWAYS);

这是它在 Android 4.2 上的样子。这也是我期望它在 Android 2.2 上的样子。

在此处输入图像描述

4

4 回答 4

4

当你创建时SpinnerArrayAdapter,你应该使用R.layout.sherlock_spinner_item; 那么你应该调用setDropDownViewResource(R.layout.sherlock_spinner_dropdown_item)适配器。请注意两个资源名称之间的区别。

从示例代码:

Context context = getSupportActionBar().getThemedContext();
ArrayAdapter<CharSequence> list = ArrayAdapter.createFromResource(context, R.array.locations, R.layout.sherlock_spinner_item);
list.setDropDownViewResource(R.layout.sherlock_spinner_dropdown_item);

对于您的代码,这将是:

spinner = new Spinner(getSupportActionBar().getThemedContext());
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>
(
    getSupportActionBar().getThemedContext(), 
    R.layout.sherlock_spinner_item, 
    new String[]{"All", "Solved", "Unsolved"}
);
spinnerArrayAdapter.setDropDownViewResource(R.layout.sherlock_spinner_dropdown_item);
spinner.setAdapter(spinnerArrayAdapter);
于 2012-11-30T00:51:59.837 回答
3

我创建了一个在 MenuItem 中使用 ICS 样式 Spinner 的解决方案。Android 支持库有 SpinnerICS 小部件,它用于列表导航模式,但他们决定将其设为内部,因此我们不能直接使用它。我的解决方案是通过反射访问 SpinnerICS 小部件。

首先创建 SpinnerICS.java:

package com.example.widget;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;

public class SpinnerICS 
{
    private Spinner spinner = null;
    private View spinnerICS = null;
    private Method setAdapterICS = null;
    private Method setSelectionICS = null;
    private Method getAdapterICS = null;
    private Method getSelectedItemPositionICS = null;
    private Method getSelectedItemICS = null;
    private Class<?> OnItemSelectedListenerICS = null;
    private Method setOnItemSelectedListenerICS = null;

    public SpinnerICS(Context context)
    {
        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            try {
                Class<?> c = Class.forName("android.support.v7.internal.widget.SpinnerICS");            
                Constructor<?> ctor = c.getDeclaredConstructor(Context.class, AttributeSet.class, int.class);
                ctor.setAccessible(true);
                setAdapterICS = c.getMethod("setAdapter", SpinnerAdapter.class);
                setSelectionICS = c.getMethod("setSelection", int.class);
                getAdapterICS = c.getMethod("getAdapter");
                getSelectedItemPositionICS = c.getMethod("getSelectedItemPosition");
                getSelectedItemICS = c.getMethod("getSelectedItem");
                OnItemSelectedListenerICS = Class.forName("android.support.v7.internal.widget.AdapterViewICS$OnItemSelectedListener");
                setOnItemSelectedListenerICS = c.getMethod("setOnItemSelectedListener", OnItemSelectedListenerICS);             
                spinnerICS = (View)ctor.newInstance(context, null, android.support.v7.appcompat.R.attr.actionDropDownStyle);                
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (spinnerICS == null) {
            spinner = new Spinner(context);
        }
    }

    public View getView()
    {
        return (spinnerICS != null ? spinnerICS : spinner);
    }

    public void setAdapter(SpinnerAdapter adapter)
    {
        if (spinnerICS != null) {
            try {
                setAdapterICS.invoke(spinnerICS, adapter);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (spinner != null) {
            spinner.setAdapter(adapter);
        }
    }

    public void setSelection(int position)
    {
        if (spinnerICS != null) {
            try {
                setSelectionICS.invoke(spinnerICS, position);
            } catch (Exception e) {
                e.printStackTrace();
            }           
        } else if (spinner != null) {
            spinner.setSelection(position);
        }
    }

    public SpinnerAdapter getAdapter()
    {
        if (spinnerICS != null) {
            try {
                return (SpinnerAdapter)getAdapterICS.invoke(spinnerICS);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (spinner != null) {
            return spinner.getAdapter();
        }
        return null;
    }

    public int getSelectedItemPosition()
    {
        if (spinnerICS != null) {
            try {
                return (Integer)getSelectedItemPositionICS.invoke(spinnerICS);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (spinner != null) {
            return spinner.getSelectedItemPosition();
        }
        return -1;
    }

    public Object getSelectedItem()
    {
        if (spinnerICS != null) {
            try {
                return getSelectedItemICS.invoke(spinnerICS);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (spinner != null) {
            return spinner.getSelectedItem();
        }
        return null;        
    }

    public class OnItemSelectedListenerProxyListener implements java.lang.reflect.InvocationHandler
    {
        private OnItemSelectedListener listener;

        public OnItemSelectedListenerProxyListener(OnItemSelectedListener listener)
        {
            this.listener = listener; 
        }    

        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
        {
            if (method.getName().equals("onItemSelected")) {
                listener.onItemSelected(null, (View)args[1], (Integer)args[2], (Long)args[3]);
            } else if (method.getName().equals("onNothingSelected")) {
                listener.onNothingSelected(null);
            }
            return null;
        }
    }


    public void setOnItemSelectedListener(OnItemSelectedListener listener)
    {
        if (spinnerICS != null) {
            try {               
                Object obj = Proxy.newProxyInstance(OnItemSelectedListenerICS.getClassLoader(), new Class<?>[] { OnItemSelectedListenerICS } , new OnItemSelectedListenerProxyListener(listener));
                setOnItemSelectedListenerICS.invoke(spinnerICS, obj);
            } catch (Exception e) {
                e.printStackTrace();
            }           
        } else if (spinner != null) {
            spinner.setOnItemSelectedListener(listener);
        }
    }   
}

然后像这样使用这个 SpinnerICS:

    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);

        String[] items = new String[] { "one", "two", "three" };
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.support.v7.appcompat.R.layout.support_simple_spinner_dropdown_item, items);
        adapter.setDropDownViewResource(android.support.v7.appcompat.R.layout.support_simple_spinner_dropdown_item);

        SpinnerICS spinner = new SpinnerICS(this);
        MenuItem item = menu.add("Sample:");
        MenuItemCompat.setActionView(item, spinner.getView());
        MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
        spinner.setAdapter(adapter);

        return true;
    }
于 2014-01-17T14:03:42.503 回答
0

SpinnerICS 解决方案如图所示运行良好,但使用它与普通 Spinner 略有不同。

例如,您不能这样做:

在 xml 中:

<TableRow>
<TextView android:text="@string/textview_abc" 
    android:layout_width="80sp"
    android:gravity="center"
    android:inputType="textMultiLine"
/>
<SpinnerICS android:id="@+id/spinner_abc"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="14sp"
    android:prompt="@string/spinner_abc"
/>
</TableRow>

在java中:

SpinnerICS spinner = (SpinnerICS) view.findViewById(R.id.spinner_abc);

它的错误如下:

[javac] /home/androidin/build/Project/src/com/example/FragmentTab.java:77: error: inconvertible types
[javac]         SpinnerICS spinner = (SpinnerICS) view.findViewById(R.id.spinner_abc);
[javac]                                                                                                                              ^
[javac]   required: SpinnerICS
[javac]   found:    View
于 2014-07-17T23:03:57.310 回答
0

只是添加到上面的答案。它工作得很好,但是您需要将上下文设置为主题上下文,如下所示:

Context ctx = getSupportActionBar().getThemedContext();

否则主题将不匹配。

于 2014-05-19T12:10:55.180 回答