自定义Spinner适配器

37

我想将自定义字体应用于我的Spinner。 我发现的唯一方法是创建一个自定义适配器。 这是我的代码:

    private class CustomAdapter extends ArrayAdapter {

    private Context context;
    private List<CharSequence> itemList;
    public CustomAdapter(Context context, int textViewResourceId,List<CharSequence> itemList) {

        super(context, textViewResourceId);
        this.context=context;
        this.itemList=itemList;
    }

    public TextView getView(int position, View convertView, ViewGroup parent) {

        TextView v = (TextView) super
                .getView(position, convertView, parent);
        Typeface myTypeFace = Typeface.createFromAsset(context.getAssets(),
                "fonts/gilsanslight.otf");
        v.setTypeface(myTypeFace);
        v.setText(itemList.get(position));
        return v;
    }

    public TextView getDropDownView(int position, View convertView,
            ViewGroup parent) {

        TextView v = (TextView) super
                .getView(position, convertView, parent);
        Typeface myTypeFace = Typeface.createFromAsset(context.getAssets(),
                "fonts/gilsanslight.otf");
        v.setTypeface(myTypeFace);
        v.setText(itemList.get(position));
        return v;
    }

}
然后我使用

List<CharSequence> itemList = new ArrayList<CharSequence>(
            Arrays.asList(items));

    mySpinnerArrayAdapter = new   CustomAdapter(context,android.R.layout.simple_spinner_item,itemList); 
    spinner.setAdapter(mySpinnerArrayAdapter);

我这么做之后,我的适配器为空。请问有人可以帮助我吗?items包含了一个国家列表。

谢谢!

5个回答

56

尝试

public View getView(int position, View convertView, ViewGroup parent) {

    LayoutInflater inflater = getLayoutInflater();
            View row = inflater.inflate(yourRowlayout, parent,
                    false);
       TextView make = (TextView) row.findViewById(R.id.Make);
        Typeface myTypeFace = Typeface.createFromAsset(context.getAssets(),
                "fonts/gilsanslight.otf");
        v.setTypeface(myTypeFace);
        v.setText(itemList.get(position));
        return row;
    }


public View getDropDownView(int position, View convertView, ViewGroup parent) {

        LayoutInflater inflater = getLayoutInflater();
                View row = inflater.inflate(yourRowlayout, parent,
                        false);
           TextView make = (TextView) row.findViewById(R.id.Make);
            Typeface myTypeFace = Typeface.createFromAsset(context.getAssets(),
                    "fonts/gilsanslight.otf");
            v.setTypeface(myTypeFace);
            v.setText(itemList.get(position));
            return row;
        }

2
你可以在构造函数中获取填充器一次,然后在此之后重复使用。 - Andrew Mackenzie
有没有办法不使用自定义适配器,而是使用setDropDownResource来实现这个功能? - barq
1
我还建议在convertview上进行检查,只有在convertview == null时才进行充气,因为这是ArrayAdapters为了效率而内部执行的操作。 - Jawnnypoo
你可以在这个适配器中使用viewHolder模式来实现平滑滚动。 - Rahul
2
两者的参数和函数体都相同,为什么不从getView调用getDropDownView呢?反之亦然。DRY。 - Val Martinez
1
感谢getDropDownView()方法。奇怪的是,许多教程都跳过了这个方法。在我的情况下,当下拉列表展开时,它显示了item.toString()而不是项内的字符串(字段)。我同意@ValMartinez的观点,您可以重构代码并提取创建TextView的方法,甚至可以从getDropDownView()中调用getView() - CoolMind

4

在超类构造函数中将itemList作为参数传递

public CustomAdapter(Context context, int textViewResourceId,List<CharSequence> itemList) {

    super(context, textViewResourceId, itemList);
    this.context=context;
    this.itemList=itemList;
}

2

试一下这个

在您的布局文件内:

<Spinner
     android:id="@+id/spinnerview"
     android:layout_width="180dp"
     android:layout_height="42dp"
     android:layout_marginLeft="105dp"
     android:layout_marginTop="45dp"
     android:background="@drawable/spinner_back"
     android:paddingLeft="5dp"
     android:spinnerMode="dropdown"
     android:visibility="visible" />

在你的string.xml文件中:
 <string-array name="spinner_array_environtment">
        <item>Test</item>
        <item>Production</item>
 </string-array>

在Java文件中的onCreate()方法内部:

spinner_environment = (Spinner) findViewById(R.id.spinnerview);
            adapter = ArrayAdapter.createFromResource(this,
                    R.array.spinner_array_environtment, R.layout.spinner);
            adapter.setDropDownViewResource(R.layout.spinner);
            spinner_environment.setAdapter(adapter);

创建一个新的spinner.xml文件到你的布局文件夹中:

spinner.xml文件中:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/spinnerTarget"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textSize="25dp"
    android:textColor="#4C4646" />

这就是它了!!!

2
我认为最简单的方法是:)
List<String> listOfItems = getListOfItems(); // returns ArrayList<String>

ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, listOfItems);

targetSpinner.setAdapter(spinnerAdapter);

简单来说,将字符串列表放入下拉框中不应该强制我们实现一个适配器。这会使代码变得混乱而且有点过于复杂。

关键是使用 simple_spinner_item id - 真可恶,我喜欢 R.id 机制,但从文档上看并不直观。


0

这对我有用(使用 android.R.layout.simple_spinner_dropdown_item):

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    CheckedTextView checkedTextView = (CheckedTextView) super.getView(position, convertView, parent);
    checkedTextView.setText(itemList.get(position));
    return checkedTextView;
}

我认为这是更好的解决方案,因为您不需要多次膨胀。


实际上,simple_spinner_dropdown_item 无论如何都会被膨胀多次,那为什么不膨胀您自定义的视图呢? - ichalos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接