【Android】时间选择器PopupWindow(自定义)

时间选择器PopupWindow

preview

在这里插入图片描述


Crazy Coding

implementation

basepopup              : 'com.github.razerdp:BasePopup:2.2.20',

PopupWindow

/**
 * @ClassName GlobalPopupWindow
 * @Description TODO
 * @Author Kolin Zhao / Mozhimen
 * @Date 2021/12/30 13:54
 * @Version 1.0
 */
class PopupWindowTime(context: Context, val onTimeSure: (String) -> Unit) : BasePopupWindow(context) {
    private lateinit var btnSure: Button
    private lateinit var btnCancel: Button
    private lateinit var pickerHour: NumberPicker
    private lateinit var pickerMinute: NumberPicker

    override fun onCreateContentView(): View {
        return createPopupById(R.layout.popup_time)
    }

    override fun onViewCreated(contentView: View) {
        super.onViewCreated(contentView)

        pickerHour = findViewById(R.id.popup_time_hour)
        pickerMinute = findViewById(R.id.popup_time_minute)
        btnSure = findViewById(R.id.popup_time_sure)
        btnCancel = findViewById(R.id.popup_time_cancel)

        initTimePicker()
        btnCancel.setOnClickListener {
            this.dismiss()
        }
        btnSure.setOnClickListener {
            val time = convertDiscreteTimeToString(pickerHour.value, pickerMinute.value * 5)
            onTimeSure(time)//00:00->hh:mm
            this.dismiss()
        }
    }

    private fun initTimePicker() {
        val step5Minutes = arrayOf("00", "05", "10", "15", "20", "25", "30", "35", "40", "45", "50", "55")
        val formatter = NumberPicker.Formatter { String.format("%02d", it) }
        pickerHour.setFormatter(formatter)
        pickerMinute.setFormatter(formatter)

        pickerHour.minValue = 0
        pickerHour.maxValue = 23
        pickerMinute.displayedValues = step5Minutes
        pickerMinute.minValue = 0
        pickerMinute.maxValue = step5Minutes.size - 1

        val currentTime = DateUtil.formatDateToString(Date(), DateUtil.format_hhmm)!!.split(":")
        Log.d("TAG", "initTimePicker: ${currentTime[0]} ${currentTime[1]}")
        val currentHour = currentTime[0].toInt()
        val currentMinute = currentTime[1].toInt()

        pickerHour.value = currentHour
        pickerMinute.value = (currentMinute / 5f).roundToInt()

        pickerHour.descendantFocusability = DatePicker.FOCUS_BLOCK_DESCENDANTS
        pickerMinute.descendantFocusability = DatePicker.FOCUS_BLOCK_DESCENDANTS

        pickerHour.wrapSelectorWheel = false
        pickerMinute.wrapSelectorWheel = true
    }

    private fun convertDiscreteTimeToString(hour: Int, minute: Int): String {
        val hourStr = String.format("%02d", hour)
        val minuteStr = String.format("%02d", minute)
        return "$hourStr:$minuteStr"
    }

    fun show() {
        setPopupAnimationStyle(R.style.PopWindowAnimStyle)
        showPopupWindow()
    }
}

layout

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/popup_view"
    android:layout_width="match_parent"
    android:layout_height="480dp"
    android:layout_gravity="bottom"
    android:background="@drawable/popup_bottom">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="时间选择器"
        android:textColor="@color/blue_theme"
        android:textSize="@dimen/global_title"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.07"
        tools:ignore="HardcodedText" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <NumberPicker
            android:id="@+id/popup_time_hour"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/margin_bottom_inner"
            android:theme="@style/TimePicker" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/margin_bottom_inner"
            android:text=":"
            android:textColor="@color/blue_theme"
            android:textSize="@dimen/global_title"
            android:textStyle="bold"
            tools:ignore="HardcodedText" />

        <NumberPicker
            android:id="@+id/popup_time_minute"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/margin_bottom_inner"
            android:theme="@style/TimePicker" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.95">

        <Button
            android:id="@+id/popup_time_cancel"
            style="@style/CancelButton"
            android:layout_width="@dimen/btn_width"
            android:layout_height="@dimen/btn_height"
            android:layout_marginEnd="@dimen/margin_end"
            android:text="@string/btn_cancel" />

        <Button
            android:id="@+id/popup_time_sure"
            style="@style/SubmitButton"
            android:layout_width="@dimen/btn_width"
            android:layout_height="@dimen/btn_height"
            android:text="@string/text_sure" />

    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

drawable

  • cancel
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <stroke
        android:width="2dp"
        android:color="@color/gray_theme" />

    <corners android:radius="@dimen/btn_corner" />
</shape>
  • submit
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="@dimen/btn_corner" />
    <solid android:color="@color/blue_theme" />
</shape>

anim

  • show
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <alpha
        android:duration="500"
        android:fillAfter="true"
        android:fromAlpha="0"
        android:toAlpha="1.0" />
</set>
  • exit
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <alpha
        android:duration="500"
        android:fillAfter="true"
        android:fromAlpha="1.0"
        android:toAlpha="0.0" />
</set>

dimen

    <dimen name="global_title">28sp</dimen>
	<dimen name="margin_bottom_inner">20dp</dimen>
    <dimen name="btn_width">200dp</dimen>
    <dimen name="btn_height">64dp</dimen>
    <dimen name="margin_end">16dp</dimen>
    <dimen name="btn_text">24sp</dimen>

string

    <string name="btn_cancel">取消</string>
    <string name="text_sure">确定</string>

color

    <color name="blue_theme">#4785EF</color>

style

	<!--时间选择器-->
    <style name="TimePicker" parent="@android:style/Widget.Material.TimePicker">
        <item name="android:textColorPrimary">@color/blue_theme</item>
        <item name="colorControlNormal">@color/blue_theme</item>
        <item name="android:textSize">22sp</item>
        <item name="android:textColor">@color/white</item>
        <item name="android:textStyle">bold</item>
        <item name="android:scaleX">1.2</item>
        <item name="android:scaleY">1.2</item>
    </style>
    
    <style name="SubmitButton">
        <item name="android:background">@drawable/btn_submit</item>
        <item name="android:elevation">2dp</item>
        <item name="android:textColor">@color/white</item>
        <item name="android:textSize">@dimen/btn_text</item>
    </style>

    <style name="CancelButton">
        <item name="android:background">@drawable/btn_cancel</item>
        <item name="android:elevation">2dp</item>
        <item name="android:textColor">@color/black</item>
        <item name="android:textSize">@dimen/btn_text</item>
    </style>
    
	<style name="PopWindowAnimStyle" parent="android:Animation">
        <item name="android:windowEnterAnimation">@anim/anim_popup_show</item>
        <item name="android:windowExitAnimation">@anim/anim_popup_exit</item>
    </style>

How to use

private var popupWindowTime: PopupWindowTime? = null
private fun operateChooseTime(view: View) {
	popupWindowTime?.dismiss()
    popupWindowTime = PopupWindowTime(requireActivity()) {
    	//your logic exam:(view as TextView).text = it
	}
    popupWindowTime!!.show()
}

猜你喜欢

转载自blog.csdn.net/weixin_42473228/article/details/122411958
今日推荐