起因
工作中的一个需求,实现点击显示下拉列表,并且默认显示列表中的某个item,在github上找了一圈,找到一个“NiceSpinner”,样式合适,但是拓展性不够,于是有了本篇博客。
需求确定
spinner默认状态显示已选中的item内容,点击展开列表中不显示当前内容,即:{“one”,"two","three"},其中默认为“one”的话,列表只显示“two”,“three” 。
效果图如下
在xml中配置
<com.yspinner.widget.YSpinner
android:id="@+id/spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/spinner_text_color" />
YSpinnerBaseAdapter
public abstract class YSpinnerBaseAdapter<T, D extends ViewDataBinding> extends BaseAdapter {
...
public void setData(List<T> data) {
this.data = data;
notifyDataSetChanged();
}
//由于不显示选中项,默认展示size-1 个
@Override
public int getCount() {
if (data != null) {
return data.size() - 1;
} else {
return 0;
}
}
/*
* 用于外部取item数据
*/
public T getItemData(int position) {
return data.get(position);
}
/*
* 用于渲染item,不作为外部取item数据
* 此处的控制逻辑实现当前index不显示在列表中
*/
@Override
public T getItem(int position) {
if (position >= mSelectedIndex) {
return data.get(position + 1);
} else {
return data.get(position);
}
}
public abstract String getItemContent(int position);
public abstract void setData(T info, D dataBinding);
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
dataBinding = DataBindingUtil.inflate(LayoutInflater.from(mContext), layoutId, parent, false);
} else {
dataBinding = DataBindingUtil.getBinding(convertView);
}
//由子类实现具体数据绑定
setData(getItem(position), dataBinding);
dataBinding.executePendingBindings();
return dataBinding.getRoot();
}
}
自定义adapter继承YSpinnerBaseAdapter
//第一个泛型可传入任意自定义Object,此处用String测试
public class DemoAdapter extends YSpinnerBaseAdapter<String, SpinnerItemDataBinding> {
public DemoAdapter(Context context, int layoutId) {
super(context, layoutId);
}
//供Spinner调用显示内容的数据
@Override
public String getItemContent(int position) {
return data.get(position);
}
@Override
public void setData(String info, SpinnerItemDataBinding dataBinding) {
if (dataBinding != null) {
if (dataBinding.getModel() == null) {
dataBinding.setModel(new SpinnerModel());
}
dataBinding.getModel().setItemText(info);
}
}
}
初始化数据进行测试
String[] arr = new String[] { "one", "two", "three", "four", "five" };
DemoDataBinding demoDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
DemoAdapter adapter = new DemoAdapter(this, R.layout.layout_spinner_item);
adapter.setData(Arrays.asList(arr));
demoDataBinding.spinner.setAdapter(adapter);