Android自定义Spinner控件及其使用
Posted 胖胖中式小笼包
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android自定义Spinner控件及其使用相关的知识,希望对你有一定的参考价值。
一、简单使用
1. 写选项值
在 res/values/ 文件夹下新建一个 arrays.xml 文件:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="spinner_string">
<item>C语言</item>
<item>C++</item>
<item>python</item>
<item>Java</item>
</string-array>
</resources>
2. 在界面文件中添加Spinner控件
activity_main.xml 文件:
2.1 dropdown模式
<Spinner
android:id="@+id/spinner"
android:spinnerMode="dropdown"
android:layout_width="150dp"
android:entries="@array/spinner_string"/>
效果:
2.2 dialog模式
<Spinner
...
android:spinnerMode="dialog"/>
效果:
二、自定义dropdown样式
1. 修改点击样式和下拉框样式
在res/drawable/ 文件夹下新建两个文件:
(1)shape_for_custom_spinner.xml 文件(用来定义下拉框的样式):
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 填充颜色 -->
<solid android:color="@color/white"/>
<stroke android:width="1dp" android:color="#661886F7"/>
<!-- 矩形的圆角半径 -->
<corners android:radius="6dp" />
</shape>
(2)selector_for_custom_spinner文件(用来定义Spinner控件本身的样式,带选择器,有点击效果):
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<!-- 填充颜色 -->
<solid android:color="#661886F7"/>
<!-- 矩形的圆角半径 -->
<corners android:radius="6dp" />
</shape>
</item>
<item android:state_pressed="false">
<shape android:shape="rectangle">
<!-- 填充颜色 -->
<solid android:color="@android:color/transparent"/>
<stroke android:width="1dp" android:color="#661886F7"/>
<!-- 矩形的圆角半径 -->
<corners android:radius="6dp" />
</shape>
</item>
</selector>
在界面文件中的Spinner控件中引用它们:
<Spinner
...
android:popupBackground="@drawable/shape_for_custom_spinner"
android:background="@drawable/selector_for_custom_spinner"/>
效果:
2. 增加下划线
在res/values/ 文件夹下新建一个style.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="customTheme">
<item name="dropDownListViewStyle">@style/customSpinnerStyle</item>
</style>
<style name="customSpinnerStyle" parent="android:Widget.ListView.DropDown">
<item name="android:textAlignment">center</item>
<item name="divider">@color/black</item>
<item name="android:dividerHeight">1dp</item>
</style>
</resources>
说明:
(1)customTheme——自定义主题样式,引用它自定义下划线才能正常显示。
(2)customSpinnerStyle——自定义的Spinner样式,和上面的主题样式一样在界面文件中引用。
(3)android:divider——分割线颜色。
(4)android:dividerHeight——分割线宽度。
在界面文件中的Spinner控件中引用它:
<Spinner
...
android:paddingTop="15dp"
android:paddingBottom="15dp"
style="@style/customSpinnerStyle"/>
效果:
三、动态配置Spinner选项
1. 删除界面文件中引入的字符串组
即,删除这一行:
<Spinner
...
android:entries="@array/spinner_string"
.../>
2. 增加一个自定义的layout文件来配置列表样式
在res/layout/ 文件夹下新建一个item_for_custom_spinner.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="center"
android:text="下拉列表项样式"
android:textColor="@color/purple_700"
android:textSize="18dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="15dp"
android:paddingBottom="15dp"
android:singleLine="true"
android:ellipsize="marquee"/>
3. 在Java文件中对Spinner控件进行配置
MainActivity.java文件:
public class MainActivity extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 预定义变量
Spinner spinner;
List<String> listForSpinner = new ArrayList<>();
ArrayAdapter<String> adapterForSpinner;
// 变量初始化
spinner = findViewById(R.id.spinner);// 引用Spinner控件
// 给字符串数组赋初值
listForSpinner.add("C语言");
listForSpinner.add("Python");
listForSpinner.add("Java");
listForSpinner.add("C++");
// 设置适配器
adapterForSpinner = new ArrayAdapter<>(MainActivity.this, R.layout.item_for_custom_spinner, listForSpinner);
spinner.setAdapter(adapterForSpinner);
说明:
不想自己自定义列表样式可以选择直接使用Android自带的support_simple_spinner_dropdown_item
效果:
四、Spinner选择事件
1. 增加一个简单的选择监听器
Toast toast = Toast.makeText(getApplicationContext(), "default toast", Toast.LENGTH_SHORT);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l)
toast.setText(listForSpinner.get(i));
toast.show();
@Override
public void onNothingSelected(AdapterView<?> adapterView)
);
可以发现有两个问题:
(1)初始化监听器的时候事件被调用了。
(2)重复点击同一选项事情不会被重复调用。
2. 不希望监听器动作初始化时就被调用
办法很简单,就是定义一个flag用来确认监听器是否是第一次被调用,是则忽略它:
final int[] flag = 0;
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l)
if (flag[0] == 0)
flag[0] = flag[0] + 1;
return;
...
@Override
public void onNothingSelected(AdapterView<?> adapterView)
);
这样一来,界面初始化时就不会出现监听器动作被执行了一次的情况了。
3. 不希望重复点击同一选项时没有动作
需要重写Spinner控件的部分代码。
(1)在java/com.example.myapplication/ 文件夹下新建一个ReSpinner.java文件:
package com.example.myapplication;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.Spinner;
@SuppressLint("AppCompatCustomView")
public class ReSpinner extends Spinner
public boolean isDropDownMenuShown = false;
/**
* @param context 用来解决原生spinner点击同一选项无反应的问题
*/
public ReSpinner(Context context)
super(context);
public ReSpinner(Context context, AttributeSet attrs)
super(context, attrs);
public ReSpinner(Context context, AttributeSet attrs, int defStyleAttr)
super(context, attrs, defStyleAttr);
@Override
public void setSelection(int position, boolean animate)
boolean sameSelected = (position == getSelectedItemPosition());
super.setSelection(position, animate);
if (sameSelected)
getOnItemSelectedListener().onItemSelected(this, getSelectedView(), position, getSelectedItemId());
@Override
public boolean performClick()
this.isDropDownMenuShown = true;
return super.performClick();
@Override
public void setSelection(int position)
boolean sameSelected = (position == getSelectedItemPosition());
super.setSelection(position);
if (sameSelected)
getOnItemSelectedListener().onItemSelected(this, getSelectedView(), position, getSelectedItemId());
(2)替换掉界面文件中的控件根名称,其他什么都不用动:
将
<Spinner
.../>
改为
<com.example.myapplication.ReSpinner
.../>
这样一来,重复点击同一事件,也能正常多次触发监听器动作了。
五、自定义dialog样式
经过上面的修改,基本已经完成了对dropdown模式下的样式自定义和监听器动作自定义了,将spinnerMode改回dialog,增加一个prompt标签,增加dialog的标题:
(1)先在res/values/strings.xml文件中定义一个标题(必须步骤):
<resources>
<string name="app_name">My Application</string>
<string name="spinner_title">Spinner Title</string>
</resources>
(2)再在边界文件中引用它:
<com.example.myapplication.ReSpinner
...
android:spinnerMode="dialog"
android:prompt="@string/spinner_title"
.../>
以上是关于Android自定义Spinner控件及其使用的主要内容,如果未能解决你的问题,请参考以下文章
Android Spinner实现下拉框几种方式及配合BaseAdapter实现自定义布局
Android使用popueWindow自定义Spinner