Android Spinner自定义背景

复制代码
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>
相关推荐
星期五不见面2 小时前
嵌入式学习!(一)C++学习-STL(21)-26/1/27
开发语言·c++·学习
小北方城市网2 小时前
Elasticsearch 分布式检索生产级优化:从索引设计到查询性能
java·大数据·运维·redis·分布式·elasticsearch·搜索引擎
En^_^Joy2 小时前
Kubernetes流量负载:Service与Ingress全解析(K8s)
java·容器·kubernetes
w_t_y_y2 小时前
工具Cursor(五)Rules&Skill
java·开发语言
冬奇Lab2 小时前
【Kotlin系列16】性能优化:内联、内存与字节码分析
开发语言·性能优化·kotlin
2301_765703142 小时前
C++代码风格检查工具
开发语言·c++·算法
h7ml2 小时前
企业微信“群机器人”消息合并转发:用Disruptor做环形队列的Java实例
java·机器人·企业微信
xyq20242 小时前
XSLT 编辑 XML:深入解析与实际应用
开发语言
hrrrrb2 小时前
【算法设计与分析】算法概述
开发语言·python·算法