Spinner

584 阅读2分钟

效果图

Spinner 设置背景图片

 android:background="@drawable/bg_spinner_whitev3"

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_window_focused="true">
        <layer-list>
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="@color/white" />
                    <corners android:radius="5dp" />
                    <stroke android:width="1dp" android:color="@color/color_979797" />
                    <item android:name="android:shadowColor">#33000000</item>
                    <item android:name="android:shadowDx">0</item>
                    <item android:name="android:shadowDy">3</item>
                </shape>
            </item>
            <!--            <item>-->
            <!--                <shape>-->
            <!--                    <padding android:right="20dp" />-->
            <!--                </shape>-->
            <!--            </item>-->
            <item android:right="20dp">
                <bitmap android:gravity="center_vertical|right" android:src="@drawable/arrow_down_v1" />
            </item>
        </layer-list>
    </item>

    <item>
        <layer-list>
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="@color/white" />
                    <corners android:radius="5dp" />
                    <stroke android:width="1dp" android:color="@color/color_979797" />
                    <item android:name="android:shadowColor">#33000000</item>
                    <item android:name="android:shadowDx">0</item>
                    <item android:name="android:shadowDy">3</item>
                </shape>
            </item>
            <!--            <item>-->
            <!--                <shape>-->
            <!--                    <padding android:right="20dp" />-->
            <!--                </shape>-->
            <!--            </item>-->
            <item android:right="@dimen/dimen_20dp">
                <bitmap android:gravity="center_vertical|right" android:src="@drawable/arrow_up_v1" />
            </item>
        </layer-list>
    </item>
</selector>

Spinner 设置向下的偏移量

android:dropDownVerticalOffset="@dimen/dimen_41dp"

Spinner 设置弹出的Popup的背景

android:popupBackground="@drawable/bg_spinner_white"

Spinner 设置模式

android:spinnerMode="dropdown" 

代码如下

其中关键的点如下:

1、设置Spinner的背景。

2、设置Spinner的下拉框的背景。

3、设置Spinner的分割线。

4、设置Spinner 下拉框的最大高度,这个无法实现,必须通过 Spinner 可以用TextView + PopupWindow 来显示。

1、定义布局.

布局中就是使用background来设置Spinner的背景。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    tools:context=".MainActivity2">

    <Spinner
        android:id="@+id/spinner"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:dropDownVerticalOffset="40dp"
        android:background="@drawable/bg_spinner_whitev3"
        android:spinnerMode="dropdown"
        />

</LinearLayout>

其中bg_spinner_whitev3 为

其中,是一个图层的问题,重叠了3个图层。

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_window_focused="true">
        <layer-list>
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="@android:color/holo_green_light" />
                    <corners android:radius="20dp" />
                    <stroke android:width="1dp" android:color="@android:color/holo_red_light" />
                    <item android:name="android:shadowColor">#33000000</item>
                    <item android:name="android:shadowDx">0</item>
                    <item android:name="android:shadowDy">3</item>
                </shape>
            </item>
            <item>
                <shape>
                    <padding android:right="10dp" />
                </shape>
            </item>
            <item>
                <bitmap android:gravity="center_vertical|right" android:src="@android:drawable/arrow_up_float" />
            </item>
        </layer-list>
    </item>

    <item>
        <layer-list>
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="@android:color/holo_green_light" />
                    <corners android:radius="20dp" />
                    <stroke android:width="1dp" android:color="@android:color/holo_red_light" />
                    <item android:name="android:shadowColor">#33000000</item>
                    <item android:name="android:shadowDx">0</item>
                    <item android:name="android:shadowDy">3</item>
                </shape>
            </item>
            <item>
                <shape>
                    <padding android:right="10dp" />
                </shape>
            </item>
            <item>
                <bitmap android:gravity="center_vertical|right" android:src="@android:drawable/arrow_down_float" />
            </item>
        </layer-list>
    </item>
</selector>

2、定义Activity中的逻辑

package com.example.myapplication

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.LayoutInflater

import android.view.View
import android.view.ViewGroup

import android.R.string.no
import android.widget.*
import java.lang.ClassCastException
import java.lang.Exception
import java.lang.reflect.Field


class MainActivity2 : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main2)
        var context = this
        val spinner = findViewById<View>(R.id.spinner) as Spinner
        
        // 定义数据
        val arr = arrayOf(
            "孙悟空",
            "猪八戒",
            "唐僧",
            "孙悟空",
            "猪八戒"
        )
        // 定义Adapter
        val adapter = object : BaseAdapter() {
            override fun getCount(): Int {
                return arr.size
            }

            override fun getItem(p0: Int): Any {
                return 0
            }

            override fun getItemId(p0: Int): Long {
                return 0
            }

            override fun getView(p0: Int, p1: View?, p2: ViewGroup?): View {
                val view = LayoutInflater.from(context).inflate(R.layout.simple_list_item_1, null)
                val tv = view.findViewById<TextView>(R.id.tv)
                val line = view.findViewById<View>(R.id.view);
                tv.text = arr[p0]
                line.visibility = if (p0 == arr.size - 1) View.GONE else View.VISIBLE
                return view
            }

        }
//        try {
//            val popup: Field = Spinner::class.java.getDeclaredField("mPopup")
//            popup.isAccessible = true
//            val popupWindow = popup[spinner] as ListPopupWindow
//            popupWindow.height = 50
//            popupWindow.anchorView
//            popupWindow.setOnDismissListener {
//                val x = 1
//            }
//            popupWindow.setPromptView(ImageView(context))
//        } catch (e: Exception) {
//        }
        spinner.setPopupBackgroundResource(R.drawable.bg_spinner_whitev2)
        spinner.setAdapter(adapter)
    }
}

其中 bg_spinner_whitev2 为:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@android:color/holo_green_light" />
    <corners android:radius="20dp" />
    <stroke
        android:width="1dp"
        android:color="@android:color/holo_red_light" />
    <item android:name="android:shadowColor">#33000000</item>
    <item android:name="android:shadowDx">0</item>
    <item android:name="android:shadowDy">3</item>
</shape>

问题

Spinner 的弹出框的高度没有办法设置,可以使用TextView + PopUpWindow 来实现。

Spinner 如何设置弹出框的宽度和Spinner一样

spinner.viewTreeObserver.addOnGlobalLayoutListener(
            object : OnGlobalLayoutListener {
                override fun onGlobalLayout() {
                    spinner.viewTreeObserver.removeGlobalOnLayoutListener(this)
                    spinner.dropDownWidth = spinner.width
                }
            })

Spinner 设置每一个Item 分割线的显示逻辑(否则会有重影)

现象

Spinner 默认显示的布局为Adapter的getView的第一个布局,如果有横线,那么横线和Spinner的边界就会重复,就会有重影。

解决办法

1、首先布局文件中先设置线,然后设置TextView。

2、线第一个不显示,其他的显示 viewLine.setVisibility(position == 0 ? View.GONE : View.VISIBLE);

Spinner 设置布局

            <Spinner
                android:id="@+id/activity_upgrade_your_renewal_card_spinner"
                android:layout_width="match_parent"
                android:layout_height="@dimen/dimen_38dp"
                android:layout_below="@id/activity_upgrade_your_renewal_card_title"
                android:layout_marginTop="@dimen/dimen_6dp"
                android:background="@drawable/bg_spinner_whitev3"
                android:dropDownVerticalOffset="@dimen/dimen_41dp"
                android:popupBackground="@drawable/bg_spinner_white"
                android:spinnerMode="dropdown" />