如何为自定义Spinner Adapter设置自定义下拉样式?
自定义BaseAdapter实现Spinner下拉视图的方法
我创建了继承自BaseAdapter的CustomSpinnerAdapter类(源码如下),实现了Spinner的自定义项样式(custom_spinner_item),这部分显示正常。但在设置Spinner的下拉视图样式时遇到问题:由于该自定义Adapter不是ArrayAdapter
CustomSpinnerAdapter.java
public class CustomSpinnerAdapter extends BaseAdapter { private Context context; private String[] cities; public CustomSpinnerAdapter(Context context, String[] cities) { this.context = context; this.cities = cities; } @Override public int getCount() { return cities != null ? cities.length : 0; } @Override public Object getItem(int i) { return i; } @Override public long getItemId(int i) { return i; } @Override public View getView(int i, View view, ViewGroup viewGroup) { View rootView = LayoutInflater.from(context).inflate(R.layout.custom_spinner_item, viewGroup, false); TextView txtName = rootView.findViewById(R.id.customSpinnerItemTextView); txtName.setText(cities[i]); return rootView; } }
custom_spinner_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:id="@+id/customSpinnerItemTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="City" android:layout_centerVertical="true" android:layout_marginStart="5dp" android:layout_marginEnd="22dp" android:textAppearance="@style/toolbar_text_white"/> </LinearLayout>
解决方法
BaseAdapter本身提供了getDropDownView()方法专门处理下拉列表项的布局,你只需要在CustomSpinnerAdapter中重写这个方法即可,具体步骤如下:
- 先准备下拉视图的布局文件,比如命名为
custom_spinner_dropdown_item.xml,可以根据需求设计独立样式(示例如下) - 在CustomSpinnerAdapter中重写
getDropDownView()方法,逻辑和getView类似,但加载下拉布局,同时优化视图复用提升性能
修改后的CustomSpinnerAdapter.java
public class CustomSpinnerAdapter extends BaseAdapter { private Context context; private String[] cities; // 抽离LayoutInflater复用,提升性能 private LayoutInflater inflater; public CustomSpinnerAdapter(Context context, String[] cities) { this.context = context; this.cities = cities; this.inflater = LayoutInflater.from(context); } @Override public int getCount() { return cities != null ? cities.length : 0; } @Override public Object getItem(int position) { // 建议返回实际数据,而非position,方便后续获取选中项内容 return cities[position]; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { // 复用convertView,避免重复inflate视图 if (convertView == null) { convertView = inflater.inflate(R.layout.custom_spinner_item, parent, false); } TextView txtName = convertView.findViewById(R.id.customSpinnerItemTextView); txtName.setText(cities[position]); return convertView; } // 重写该方法自定义下拉视图 @Override public View getDropDownView(int position, View convertView, ViewGroup parent) { // 同样复用视图提升性能 if (convertView == null) { convertView = inflater.inflate(R.layout.custom_spinner_dropdown_item, parent, false); } TextView txtDropDownName = convertView.findViewById(R.id.customSpinnerDropdownTextView); txtDropDownName.setText(cities[position]); return convertView; } }
示例下拉布局:custom_spinner_dropdown_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="12dp"> <TextView android:id="@+id/customSpinnerDropdownTextView" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="City" android:textSize="16sp" android:textColor="@android:color/black"/> </LinearLayout>
注意事项
- 务必复用
convertView,避免每次滚动都重新加载布局,提升下拉列表的流畅度 - 下拉视图的样式可以和Spinner选中项完全不同,按需设计即可
- 原代码中
getItem返回position的写法不太合理,建议返回对应的数据对象或字符串,方便后续通过spinner.getSelectedItem()获取选中内容
内容的提问来源于stack exchange,提问作者Darian Pudic
相关产品推荐
相关产品推荐

