当前位置: 首页 > news >正文

Android 中 spinner / AppCompatSpinner 文字颜色 和 显示样式 源码分析

Android 中 spinner / AppCompatSpinner 文字颜色 和 显示样式 源码分析

  • 1 源码分析
    • 1.1 AppCompatSpinner
    • 1.2 Spinner/AbsSpinner
    • 1.3 simple_spinner_item.xml
    • 1.4 simple_spinner_dropdown_item.xml
  • 1.4 自定义布局文件设置
  • 2 Sample 工程
    • 2.1 创建Sample工程
    • 2.2 增加MainActivity
    • 2.3 AndroidManifest.xml 配置缺省启动 MainActivity
    • 2.4 在主布局中添加 AppCompatSpinner
  • 3 自定义的 Spinner 项布局 (spinner_item.xml):
  • 4 创建适配器并使用自定义布局

1 源码分析

我们想要自定义 spinner / AppCompatSpinner 的文字颜色和显示样式,我们先来看下spinner / AppCompatSpinner是如何来设置文字颜色 和 显示样式的。

1.1 AppCompatSpinner

我们看AppCompatSpinner 的源码,其父类是 android.widget.Spinner。

import android.widget.Spinner;[...此处省略部分代码] 
public class AppCompatSpinner extends Spinner implements TintableBackgroundView {[...此处省略部分代码] 
}

因此,我们可以统一自定义 spinner 的文字颜色和显示样式来达到目的。

1.2 Spinner/AbsSpinner

我们通过查找 R.layout 资源来看Spinner是如何设置的。在spinner 的父类 AbsSpinner 的源码中,发现如下代码:

        final CharSequence[] entries = a.getTextArray(R.styleable.AbsSpinner_entries);if (entries != null) {final ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(context, R.layout.simple_spinner_item, entries);adapter.setDropDownViewResource(R.layout.simple_spinner_dropdown_item);setAdapter(adapter);}

适配器创建:

final ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(context, R.layout.simple_spinner_item, entries);
  • 使用 ArrayAdapter 作为数据适配器
  • 使用系统预定义的 simple_spinner_item 布局作为项视图
  • 将 entries 数组作为数据源

下拉视图设置:

adapter.setDropDownViewResource(R.layout.simple_spinner_dropdown_item);

适配器绑定:

setAdapter(adapter);

调用 setAdapter() 将适配器设置给 Spinner

代码中,使用了两个布局资源

  • R.layout.simple_spinner_item: 系统预定义的简单文本项布局
  • R.layout.simple_spinner_dropdown_item: 系统预定义的下拉项布局

1.3 simple_spinner_item.xml

我们来看 Android\Sdk\platforms\android-35\data\res\layout\simple_spinner_item.xml 源码,包含一个 TextView:

<?xml version="1.0" encoding="utf-8"?>
<!--
/* //device/apps/common/assets/res/any/layout/simple_spinner_item.xml
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License"); 
** you may not use this file except in compliance with the License. 
** You may obtain a copy of the License at 
**
**     http://www.apache.org/licenses/LICENSE-2.0 
**
** Unless required by applicable law or agreed to in writing, software 
** distributed under the License is distributed on an "AS IS" BASIS, 
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
** See the License for the specific language governing permissions and 
** limitations under the License.
*/
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1"style="?android:attr/spinnerItemStyle"android:singleLine="true"android:layout_width="match_parent"android:layout_height="wrap_content"android:ellipsize="marquee"android:textAlignment="inherit"/>

1.4 simple_spinner_dropdown_item.xml

Android\Sdk\platforms\android-35\data\res\layout\simple_spinner_dropdown_item.xml 源码,包含一个CheckedTextView

<?xml version="1.0" encoding="utf-8"?>
<!--
/* //device/apps/common/assets/res/any/layout/simple_spinner_item.xml
**
** Copyright 2008, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License")
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"android:id="@android:id/text1"style="?android:attr/spinnerDropDownItemStyle"android:singleLine="true"android:layout_width="match_parent"android:layout_height="?android:attr/dropdownListPreferredItemHeight"android:ellipsize="marquee"/>

1.4 自定义布局文件设置

通过上面的分析,下面我们参考源码的方式通过自定义布局文件设置来实现目标。

2 Sample 工程

2.1 创建Sample工程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2 增加MainActivity

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

2.3 AndroidManifest.xml 配置缺省启动 MainActivity

        <activityandroid:name=".MainActivity"android:exported="true" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity>

2.4 在主布局中添加 AppCompatSpinner

<?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:gravity="center_vertical"android:orientation="horizontal"android:paddingVertical="8dp"android:id="@+id/main"android:spacing="16dp"><!-- 外层容器设置背景色 --><LinearLayoutandroid:layout_width="0dp"android:layout_height="32dp"android:layout_weight="2"android:gravity="center_vertical"><androidx.appcompat.widget.AppCompatSpinnerandroid:id="@+id/spinner"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_vertical"android:paddingStart="0dp"android:paddingEnd="0dp"android:spinnerMode="dropdown"android:textColor="?attr/colorOnSurface"android:textSize="14sp" /></LinearLayout></LinearLayout>

3 自定义的 Spinner 项布局 (spinner_item.xml):

在 res\layout 下创建布局:spinner_item.xml,为了演示,我使用了显眼的红色

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"android:id="@android:id/text1"android:gravity="center"android:paddingTop="5dp"android:textStyle="bold"android:textColor="#FF0000"android:textSize="14dp"android:singleLine="true"android:layout_width="match_parent"android:layout_height="wrap_content"android:ellipsize="marquee"/>

4 创建适配器并使用自定义布局

在 MainActivity.java 的 onCreate 中源码如下:

package com.lzc.myapplication;import android.os.Bundle;
import android.widget.ArrayAdapter;import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatSpinner;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_main);ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);return insets;});// 创建模拟数据String[] planets = {"水星", "金星", "地球", "火星", "木星", "土星", "天王星", "海王星"};AppCompatSpinner spinner = findViewById(R.id.spinner);// 创建适配器并使用自定义布局ArrayAdapter<String> adapter = new ArrayAdapter<>(this,R.layout.custom_spinner,planets);// 设置下拉样式adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);spinner.setAdapter(adapter);}
}

如果想处理下拉样式,和上面同理,就不多说了。

http://www.dtcms.com/a/353138.html

相关文章:

  • 如何轻松地将数据从安卓设备传输到安卓设备
  • 构建AI智能体:十五、超越关键词搜索:向量数据库如何解锁语义理解新纪元
  • 使用 html2canvas + jspdf 实现页面元素下载为pdf文件
  • Transformer 模型在自动语音识别(ASR)中的应用
  • 华为L420国产笔记本(统信UOS桌面专业版1070)安装openEuler2403虚拟机
  • 基于Spring Boot的民宿服务管理系统-项目分享
  • Python 并行计算进阶:ProcessPoolExecutor 处理 CPU 密集型任务
  • Java设计模式之《外观模式》
  • 广东省省考备考(第八十八天8.27)——判断推理(第八节课)
  • 31. 什么是字符串常量池
  • 2025.8.27链表_链表逆置
  • 【Python-1】字符串连接方式“+“和“,”的区别
  • AI + 旅游 = 应用案例分析(一)
  • TDengine IDMP 5 个实测场景让监控变简单
  • 【和春笋一起学C++】(三十七)类的析构函数
  • rust语言(1.88.0)sqlite数据库rusqlite库(0.37.0)学习笔记
  • Linux 服务器故障全解析:常见问题及处理方法大全
  • 极简风格PDF格式转换解决方案
  • java将doc文件转pdf
  • PDF补丁丁:开源多年,完全免费的多功能 PDF 工具箱
  • Magicodes.IE.Pdf 生成导出PDF文件 bytes Stream FileStreamResult 下载
  • 像WPS Office 一样处理pdf页面尺寸
  • OpenGL 视差贴图
  • UVa11607 Cutting Cakes
  • Java垃圾回收器:从SerialGC到G1的演进/速通
  • 流程控制语句(1)
  • 如何检查 Linux 系统的内存使用情况
  • vue2实现背景颜色渐变
  • 【目标检测】论文阅读4
  • 分布式2PC理论