复制代码
class CustomSpinnerAdapter:
java
复制代码
public class CustomSpinnerAdapter extends BaseAdapter {
private Context context;
private List<ListDataEntity> dataList;
private LayoutInflater inflater;
// 颜色配置(深色主题)
private int textColor = Color.WHITE;
private int hintTextColor = Color.parseColor("#999999");
private boolean showHint = true;
private String hintText = "请选择";
/**
* 构造函数
*/
public CustomSpinnerAdapter(Context context, List<ListDataEntity> dataList) {
this.context = context;
this.dataList = dataList;
this.inflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
if (dataList == null) {
return showHint ? 1 : 0;
}
return showHint ? dataList.size() + 1 : dataList.size();
}
@Override
public Object getItem(int position) {
if (dataList == null || dataList.isEmpty()) {
return null;
}
if (showHint) {
if (position == 0) {
return createHintEntity();
}
return dataList.get(position - 1);
}
return dataList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
// 使用内置的布局资源
convertView = inflater.inflate(R.layout.layout_spinner_item, parent, false);
holder = new ViewHolder();
holder.textView = convertView.findViewById(R.id.tv_item_name);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
ListDataEntity item = (ListDataEntity) getItem(position);
if (item != null) {
holder.textView.setText(item.getName());
// 设置文字颜色
if (showHint && position == 0) {
holder.textView.setTextColor(hintTextColor);
} else {
holder.textView.setTextColor(textColor);
}
}
return convertView;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
DropDownViewHolder holder;
if (convertView == null) {
// 使用内置的下拉布局资源
convertView = inflater.inflate(R.layout.layout_spinner_dropdown_item, parent, false);
holder = new DropDownViewHolder();
holder.textView = convertView.findViewById(R.id.tv_dropdown_name);
convertView.setTag(holder);
} else {
holder = (DropDownViewHolder) convertView.getTag();
}
ListDataEntity item = (ListDataEntity) getItem(position);
if (item != null) {
holder.textView.setText(item.getName());
// 下拉列表始终保持浅色字
if (showHint && position == 0) {
holder.textView.setTextColor(hintTextColor); // 提示项灰色
convertView.setEnabled(false);
} else {
holder.textView.setTextColor(Color.WHITE); // 普通项白色
convertView.setEnabled(true);
}
}
return convertView;
}
@Override
public boolean isEnabled(int position) {
// 如果显示提示项,且位置为0,则该项不可点击
if (showHint && position == 0) {
return false;
}
return true;
}
/**
* 创建提示项实体
*/
private ListDataEntity createHintEntity() {
return new ListDataEntity("-1", hintText);
}
/**
* 设置是否显示提示项
*/
public void setShowHint(boolean showHint) {
this.showHint = showHint;
notifyDataSetChanged();
}
/**
* 设置提示文字
*/
public void setHintText(String hintText) {
this.hintText = hintText;
notifyDataSetChanged();
}
/**
* 设置文字颜色
*/
public void setTextColor(int textColor) {
this.textColor = textColor;
notifyDataSetChanged();
}
/**
* 设置提示文字颜色
*/
public void setHintTextColor(int hintTextColor) {
this.hintTextColor = hintTextColor;
notifyDataSetChanged();
}
/**
* 设置数据源
*/
public void setDataList(List<ListDataEntity> dataList) {
this.dataList = dataList;
notifyDataSetChanged();
}
/**
* 获取原始数据(不包含提示项)
*/
public List<ListDataEntity> getOriginalDataList() {
return dataList;
}
/**
* 根据ID获取位置
*/
public int getPositionById(String id) {
if (dataList == null || dataList.isEmpty()) {
return -1;
}
for (int i = 0; i < dataList.size(); i++) {
if (dataList.get(i).getId().equals(id)) {
return showHint ? i + 1 : i;
}
}
return -1;
}
/**
* 根据名称获取位置
*/
public int getPositionByName(String name) {
if (dataList == null || dataList.isEmpty()) {
return -1;
}
for (int i = 0; i < dataList.size(); i++) {
if (dataList.get(i).getName().equals(name)) {
return showHint ? i + 1 : i;
}
}
return -1;
}
/**
* 获取实际数据项(排除提示项)
*/
public ListDataEntity getRealItem(int position) {
if (dataList == null || dataList.isEmpty()) {
return null;
}
if (showHint) {
if (position > 0 && position <= dataList.size()) {
return dataList.get(position - 1);
}
} else {
if (position >= 0 && position < dataList.size()) {
return dataList.get(position);
}
}
return null;
}
/**
* 获取指定位置的ID
*/
public String getIdAtPosition(int position) {
ListDataEntity item = getRealItem(position);
return item != null ? item.getId() : null;
}
/**
* 获取指定位置的名称
*/
public String getNameAtPosition(int position) {
ListDataEntity item = getRealItem(position);
return item != null ? item.getName() : null;
}
/**
* 获取当前选中的实体(如果选中的是提示项,返回null)
*/
public ListDataEntity getSelectedEntity(int position) {
return getRealItem(position);
}
// ViewHolder 类
private static class ViewHolder {
TextView textView;
}
// DropDownViewHolder 类
private static class DropDownViewHolder {
TextView textView;
}
}
复制代码
class MainActivity:
java
复制代码
@BindView(R.id.mSpStartPlace)
Spinner mSpStartPlace;
private CustomSpinnerAdapter startPlaceAdapter;
private void initSpinners() {
// 初始化起点数据
List<ListDataEntity> startPlaceList = new ArrayList<>();
startPlaceList.add(new ListDataEntity("1", "北京南站"));
startPlaceList.add(new ListDataEntity("2", "上海虹桥站"));
startPlaceList.add(new ListDataEntity("3", "广州南站"));
startPlaceList.add(new ListDataEntity("4", "深圳北站"));
startPlaceList.add(new ListDataEntity("5", "杭州东站"));
startPlaceList.add(new ListDataEntity("6", "成都东站"));
startPlaceList.add(new ListDataEntity("7", "武汉站"));
startPlaceList.add(new ListDataEntity("8", "南京南站"));
// 创建适配器
startPlaceAdapter = new CustomSpinnerAdapter(this, startPlaceList);
// 配置适配器
configureSpinnerAdapters();
// 设置适配器
mSpStartPlace.setAdapter(startPlaceAdapter);
// 设置 Spinner 样式
setupSpinnerStyle();
// 设置选择监听器
setupSpinnerListeners();
// 设置默认选择
setDefaultSelections();
}
/**
* 配置 Spinner 适配器
*/
private void configureSpinnerAdapters() {
if (startPlaceAdapter != null) {
startPlaceAdapter.setHintText("请选择起点");
startPlaceAdapter.setShowHint(true);
}
}
/**
* 设置 Spinner 样式
*/
private void setupSpinnerStyle() {
// 设置下拉菜单背景
mSpStartPlace.setPopupBackgroundResource(R.drawable.spinner_popup_background);
// 设置下拉菜单垂直偏移
mSpStartPlace.setDropDownVerticalOffset(2);
// 设置下拉菜单宽度
mSpStartPlace.setDropDownWidth(ViewGroup.LayoutParams.MATCH_PARENT);
}
private ListDataEntity selectedStartPlace;
/**
* 设置 Spinner 选择监听器
*/
private void setupSpinnerListeners() {
// 起点选择监听
mSpStartPlace.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
mSpStartPlace.setBackgroundResource(position > 0 ? R.drawable.spinner_background_white : R.drawable.spinner_background_dark);
ListDataEntity selectedItem = startPlaceAdapter.getRealItem(position);
if (selectedItem != null) {
selectedStartPlace = selectedItem;
onStartPlaceSelected(selectedItem);
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
selectedStartPlace = null;
}
});
}
/**
* 设置默认选择
*/
private void setDefaultSelections() {
// 起点提示项
mSpStartPlace.setSelection(0, false); // 0 = 提示项
mSpStartPlace.setBackgroundResource(R.drawable.spinner_background_dark);
}
private void onStartPlaceSelected(ListDataEntity place) {
if (place != null) {
// 可以在这里处理起点选择逻辑
// 例如:更新地图显示、计算路线等
// 可以显示提示或执行其他操作
showMessage("选择了起点: " + place.getName());
}
}
复制代码
class ListDataEntity:
java
复制代码
public class ListDataEntity {
private String id;
private String name;
public ListDataEntity() {
}
public ListDataEntity(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
复制代码
layout/activity_main.xml:
XML
复制代码
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/mLlStartPlace"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_25"
android:paddingStart="@dimen/dp_25">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:drawableStart="@drawable/circle_start_point"
android:drawablePadding="@dimen/dp_5"
android:text="起点:"
android:textColor="@color/color_FFFFFF"
android:textSize="@dimen/sp_12" />
<Spinner
android:id="@+id/mSpStartPlace"
android:layout_width="@dimen/dp_150"
android:layout_height="@dimen/dp_26"
android:layout_marginStart="@dimen/dp_5"
android:background="@drawable/spinner_background_dark" />
</LinearLayout>
</RelativeLayout>
复制代码
drawable/circle_start_point.xml:
XML
复制代码
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#99CCFF"/>
<size
android:width="12dp"
android:height="12dp"/>
</shape>
复制代码
layout/layout_spinner_item.xml:
XML
复制代码
<?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="@dimen/dp_32"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="@dimen/dp_8"
android:paddingEnd="@dimen/dp_8">
<TextView
android:id="@+id/tv_item_name"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:ellipsize="end"
android:gravity="center_vertical"
android:singleLine="true"
android:layout_marginEnd="@dimen/dp_15"
android:textColor="@color/color_FFFFFF"
android:textSize="@dimen/sp_12" />
</LinearLayout>
复制代码
layout/layout_spinner_dropdown_item.xml:
XML
复制代码
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tv_dropdown_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:minHeight="@dimen/dp_32"
android:gravity="center_vertical"
android:paddingStart="@dimen/dp_12"
android:paddingEnd="@dimen/dp_12"
android:singleLine="true"
android:textColor="@color/color_FFFFFF"
android:textSize="@dimen/sp_13" />
复制代码
drawable/spinner_background_dark.xml:
XML
复制代码
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 圆角底色 -->
<item>
<shape>
<solid android:color="@color/color_232B35"/>
<corners android:radius="@dimen/dp_4"/>
</shape>
</item>
<!-- 右侧向下单箭头 → 符号 -->
<item
android:width="26dp"
android:height="26dp"
android:gravity="end|center_vertical"
android:right="@dimen/dp_8">
<vector
android:width="26dp"
android:height="26dp"
android:viewportWidth="24"
android:viewportHeight="24">
<!-- 仅两条斜线组成 ↓ -->
<path
android:strokeColor="@color/color_999999"
android:strokeWidth="2"
android:strokeLineCap="round"
android:pathData="M8,10l4,4 4,-4"/>
</vector>
</item>
</layer-list>
复制代码
drawable/spinner_background_white.xml:
XML
复制代码
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 圆角底色 -->
<item>
<shape>
<solid android:color="@color/color_232B35"/>
<corners android:radius="@dimen/dp_4"/>
</shape>
</item>
<!-- 右侧向下单箭头 → 符号 -->
<item
android:width="26dp"
android:height="26dp"
android:gravity="end|center_vertical"
android:right="@dimen/dp_8">
<vector
android:width="26dp"
android:height="26dp"
android:viewportWidth="24"
android:viewportHeight="24">
<!-- 仅两条斜线组成 ↓ -->
<path
android:strokeColor="@color/color_FFFFFF"
android:strokeWidth="2"
android:strokeLineCap="round"
android:pathData="M8,10l4,4 4,-4"/>
</vector>
</item>
</layer-list>