Android 开发之自定义 Spinner
Android 开发之自定义 Spinner
官方自带的 Spinner 不算好用,所以要想要特定的效果只能自己动手了
- Spinner 概述
- 完全自定义
Spinner 概述
Spinner 就是一个下拉选择器,是 Android 开发中很常用的一种控件,但是确实挺难用,比较死板,变化不灵活。
当我们需要特定样式的 Spinner 的时候,就很纠结,用还是不用它呢?今天就来自定义 Spinner ,满足所有需求。
Spinner 有几个特点:
- 右下角图标难看;
- 下拉列表包括已选分类;
- 下拉列表样式单一;
我需要的 Spinner 也有几个特点:
- 可以自定义右下角图标;
- 下拉列表样式可自定义;
- 下拉列表显示项不包括已选分类;
- 想怎么样就怎么样!
完全自定义 Spinner
准备工作
新建一个数组 res/values/arrays.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="category">
<item>国内</item>
<item>国际</item>
<item>体育</item>
<item>社会</item>
<item>科技</item>
<item>娱乐</item>
</string-array>
<string-array name="category_id">
<item>topNewsCN</item>
<item>topNewsWorld</item>
<item>sports</item>
<item>eco</item>
<item>technology</item>
<item>entertainment</item>
</string-array>
</resources>
自定义已选分类的 layout(打开+关闭)
spinner_item.xml
<?xml version="1.0" encoding="utf-8"?><!--Custom spinner item layout-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/spinner_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableEnd="@drawable/btn1_1"
android:drawableRight="@drawable/btn1_1"
android:gravity="center_vertical"
android:singleLine="true"
android:textAlignment="inherit"
android:textColor="@color/white"
tools:ignore="UnusedAttribute" />
spinner_item_open.xml
<?xml version="1.0" encoding="utf-8"?><!--Custom spinner item layout-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/spinner_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableEnd="@drawable/ic_arrow_drop_up_white_24dp"
android:drawableRight="@drawable/ic_arrow_drop_up_white_24dp"
android:gravity="center_vertical"
android:singleLine="true"
android:textAlignment="inherit"
android:textColor="@color/white"
tools:ignore="UnusedAttribute" />
弹窗选项(PopupWindow)
弹窗使用 PopupWindow + ListView
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/list_bg"
/>
</LinearLayout>
ListView 这里简单使用 TextView 作为 item ,具体用什么布局,就要看你自己的需求了
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="@color/white" />
</LinearLayout>
前期准备已经搞定,接下来就是 Activity 中的代码了
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//ButterKnife好东西
ButterKnife.bind(this);
mContext = this;
styleSpinner();
public void styleSpinner() {
//标记各个分类
hashMap = new HashMap<String, Integer>();
hashMap.put(Constants.CN, 0);
hashMap.put(Constants.WORLD, 1);
hashMap.put(Constants.SPORTS, 2);
hashMap.put(Constants.ECO, 3);
hashMap.put(Constants.TECHNOLOGY, 4);
hashMap.put(Constants.ENTERTAINMENT, 5);
catname.setText(Utils.getCurrentCatogery());
//分类
cat = getResources().getStringArray(R.array.category);
list = Arrays.asList(cat);
arrayList = new ArrayList<String>(list);
//下拉列表选项中去除已选分类
arrayList.remove(Utils.getCurrentCatogeryPos());
//设置弹窗布局
layout = (LinearLayout) LayoutInflater.from(this).inflate(R.layout.spinner_dropdown, null);
//CustomSpinnerAdapter 就是一个自定义的 Adapter
adapter = new CustomSpinnerAdapter(mContext, arrayList);
listView.setAdapter(adapter);
}
public void showWindow(View view, final TextView txt) {
adapter.notifyDataSetChanged();
//设置弹窗 PopopWindow 属性,去除已选分类
popupWindow = new PopupWindow(view);
popupWindow.setWidth(position.getWidth());
popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
popupWindow.setBackgroundDrawable(new BitmapDrawable(getResources(), (Bitmap) null));
popupWindow.setOutsideTouchable(true);
popupWindow.setFocusable(true);
popupWindow.setContentView(layout);
//设置弹窗的位置
popupWindow.showAsDropDown(position, 0, 0);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
String selected = arrayList.get(arg2);
txt.setText(selected);//设置已选分类
arrayList.clear();
arrayList.addAll(list);
int pos = hashMap.get(selected);
String[] categories = getResources().getStringArray(R.array.category_id);
arrayList.remove(pos);//更新弹窗列表(去除已选分类)
category_id = categories[pos];
popupWindow.dismiss();//关闭弹窗
popupWindow = null;
doSomething();//进行选中分类的相应处理工作
}
});
}
到这里就基本完成自定义 Spinner了
对了,你可以直接把 spinner_item.xml 放在你想要放的位置,还可以设置其打开的状态(箭头变化等),使用 spinner_item_open.xml。只需要监听弹窗的出现和消息就可以了。
现在就可以实现完全自定义的 Spinner了