You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Spinner模式的TimePicker自定义布局并修改选中文字颜色

Hey there! Let's tackle your two requirements for the Spinner-mode TimePicker: customizing its layout and changing the selected text color to orange or green. I'll break this down into easy-to-follow steps.

1. Change Selected Text Color for Spinner-TimePicker

There are two practical approaches here—one using styles (no code needed) and another using code for dynamic control:

Approach 1: Using Custom Styles (Clean & Static)

This is the best option if you want to apply the same style across multiple TimePickers or your entire app.

First, add these styles to your res/values/styles.xml file:

<!-- Base style for the Spinner-mode TimePicker -->
<style name="CustomSpinnerTimePicker" parent="Widget.MaterialComponents.TimePicker.Spinner">
    <item name="android:spinnerStyle">@style/CustomTimeSpinner</item>
</style>

<!-- Style for the inner Spinners inside the TimePicker -->
<style name="CustomTimeSpinner" parent="Widget.MaterialComponents.Spinner">
    <item name="spinnerItemStyle">@style/CustomSpinnerItemText</item>
</style>

<!-- Style to define default and selected text colors -->
<style name="CustomSpinnerItemText" parent="TextAppearance.MaterialComponents.Spinner.Item">
    <item name="android:textColor">@color/default_text</item>
    <!-- Set your desired selected color (orange/green) -->
    <item name="android:textColorSelected">@color/orange</item>
</style>

Don't forget to define the colors in res/values/colors.xml:

<color name="orange">#FFA500</color>
<color name="green">#00C851</color>
<color name="default_text">#333333</color>

Then apply the custom style to your TimePicker in the layout:

<TimePicker
    android:id="@+id/timePicker"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:timePickerMode="spinner"
    style="@style/CustomSpinnerTimePicker" <!-- Add this line -->
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/constraintLayout2"
    tools:ignore="UnusedAttribute" />

Approach 2: Using Code (Dynamic Color Changes)

If you need to switch colors on the fly (e.g., based on user settings), use reflection to access the TimePicker's inner Spinners and customize their adapters:

Add this code to your Activity/Fragment:

val timePicker = findViewById<TimePicker>(R.id.timePicker)

// Access the hour and minute Spinners using their internal tags
val hourSpinner = timePicker.findViewWithTag<Spinner>("hour")
val minuteSpinner = timePicker.findViewWithTag<Spinner>("minute")

// Create a custom adapter to handle selected text color
fun createColoredAdapter(spinner: Spinner): ArrayAdapter<*> {
    val originalAdapter = spinner.adapter as ArrayAdapter<*>
    return object : ArrayAdapter<Any?>(this, android.R.layout.simple_spinner_item, originalAdapter.items) {
        override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
            val view = super.getView(position, convertView, parent)
            // Set color based on selection state
            view.setTextColor(
                if (spinner.selectedItemPosition == position) 
                    ContextCompat.getColor(this@YourActivity, R.color.green)
                else 
                    ContextCompat.getColor(this@YourActivity, R.color.default_text)
            )
            return view
        }

        override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View {
            val view = super.getDropDownView(position, convertView, parent)
            view.setTextColor(
                if (spinner.selectedItemPosition == position) 
                    ContextCompat.getColor(this@YourActivity, R.color.green)
                else 
                    ContextCompat.getColor(this@YourActivity, R.color.default_text)
            )
            return view
        }
    }
}

// Apply the custom adapters
hourSpinner.adapter = createColoredAdapter(hourSpinner)
minuteSpinner.adapter = createColoredAdapter(minuteSpinner)

// Update color when selection changes
hourSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
    override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
        (parent?.adapter as ArrayAdapter<*>).notifyDataSetChanged()
    }
    override fun onNothingSelected(parent: AdapterView<*>?) {}
}

minuteSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
    override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
        (parent?.adapter as ArrayAdapter<*>).notifyDataSetChanged()
    }
    override fun onNothingSelected(parent: AdapterView<*>?) {}
}

Replace YourActivity with your actual Activity class name.

2. Custom Layout for Spinner-Mode TimePicker

If you want full control over the layout (e.g., rearrange spinners, add labels, or remove separators), build a custom layout instead of using the default TimePicker:

Step 1: Create the Custom Layout (res/layout/custom_time_picker.xml)

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:gravity="center_vertical"
    android:padding="16dp">

    <!-- Hour Spinner -->
    <Spinner
        android:id="@+id/hourSpinner"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=":"
        android:textSize="24sp"
        android:paddingHorizontal="12dp" />

    <!-- Minute Spinner -->
    <Spinner
        android:id="@+id/minuteSpinner"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <!-- Add AM/PM spinner here if using 12-hour format -->
</LinearLayout>

Step 2: Create Hour/Minute Arrays (res/values/arrays.xml)

<resources>
    <!-- 24-hour format hours -->
    <string-array name="hours_24h">
        <item>00</item><item>01</item><item>02</item><item>03</item><item>04</item><item>05</item>
        <item>06</item><item>07</item><item>08</item><item>09</item><item>10</item><item>11</item>
        <item>12</item><item>13</item><item>14</item><item>15</item><item>16</item><item>17</item>
        <item>18</item><item>19</item><item>20</item><item>21</item><item>22</item><item>23</item>
    </string-array>

    <!-- 5-minute interval minutes -->
    <string-array name="minutes_interval">
        <item>00</item><item>05</item><item>10</item><item>15</item><item>20</item><item>25</item>
        <item>30</item><item>35</item><item>40</item><item>45</item><item>50</item><item>55</item>
    </string-array>
</resources>

Step 3: Implement the Custom TimePicker in Your Activity/Fragment

// Inflate the custom layout
val customTimePicker = layoutInflater.inflate(R.layout.custom_time_picker, null)
val hourSpinner = customTimePicker.findViewById<Spinner>(R.id.hourSpinner)
val minuteSpinner = customTimePicker.findViewById<Spinner>(R.id.minuteSpinner)

// Reuse the colored adapter logic from Approach 2
fun createColoredAdapter(entries: Array<String>): ArrayAdapter<String> {
    return object : ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, entries) {
        override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
            val view = super.getView(position, convertView, parent)
            view.setTextColor(
                if ((parent as Spinner).selectedItemPosition == position)
                    ContextCompat.getColor(this@YourActivity, R.color.orange)
                else
                    ContextCompat.getColor(this@YourActivity, R.color.default_text)
            )
            return view
        }

        override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View {
            val view = super.getDropDownView(position, convertView, parent)
            view.setTextColor(
                if ((parent as Spinner).selectedItemPosition == position)
                    ContextCompat.getColor(this@YourActivity, R.color.orange)
                else
                    ContextCompat.getColor(this@YourActivity, R.color.default_text)
            )
            return view
        }
    }
}

// Set adapters with our arrays
hourSpinner.adapter = createColoredAdapter(resources.getStringArray(R.array.hours_24h))
minuteSpinner.adapter = createColoredAdapter(resources.getStringArray(R.array.minutes_interval))

// Add selection listeners to capture the selected time
hourSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
    override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
        val selectedHour = parent?.selectedItem.toString()
        // Handle selected hour
    }
    override fun onNothingSelected(parent: AdapterView<*>?) {}
}

minuteSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
    override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
        val selectedMinute = parent?.selectedItem.toString()
        // Handle selected minute
    }
    override fun onNothingSelected(parent: AdapterView<*>?) {}
}

// Add the custom time picker to your main layout
val container = findViewById<ConstraintLayout>(R.id.your_main_container)
container.addView(customTimePicker)

内容的提问来源于stack exchange,提问作者MasterInAndroid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:22:06