自定义时间选择器

自定义时间选择器

布局

<?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"

    android:id="@+id/cl_time_date_bg"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:background="@color/transparent">

    <ImageView

        android:id="@+id/iv_bg"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:src="@mipmap/bg_time_date_left"

        app:layout_constraintBottom_toBottomOf="parent"

        app:layout_constraintEnd_toEndOf="parent"

        app:layout_constraintStart_toStartOf="parent"

        app:layout_constraintTop_toTopOf="parent" />

    <ImageView

        android:layout_width="@dimen/common_190dp"

        android:layout_height="@dimen/common_30dp"

        android:layout_marginTop="@dimen/common_6dp"

        android:src="@drawable/shape_e5e5e8_r7"

        app:layout_constraintBottom_toBottomOf="parent"

        app:layout_constraintEnd_toEndOf="parent"

        app:layout_constraintStart_toStartOf="parent"

        app:layout_constraintTop_toTopOf="parent" />

    <LinearLayout

        android:id="@+id/item_linear_layout"

        android:layout_width="@dimen/common_210dp"

        android:layout_height="@dimen/common_152dp"

        android:layout_weight="1"

        android:background="@color/transparent"

        android:gravity="fill_horizontal"

        android:paddingTop="@dimen/common_6dp"

        app:layout_constraintBottom_toBottomOf="parent"

        app:layout_constraintEnd_toEndOf="parent"

        app:layout_constraintStart_toStartOf="parent"

        app:layout_constraintTop_toTopOf="parent">

        <NumberPicker

            android:id="@+id/number_picker_left"

            android:layout_width="0dp"

            android:layout_height="match_parent"

            android:layout_weight="0.15"

            android:descendantFocusability="blocksDescendants" />

        <NumberPicker

            android:id="@+id/number_picker_center"

            android:layout_width="0dp"

            android:layout_height="match_parent"

            android:layout_weight="0.15"

            android:descendantFocusability="blocksDescendants" />

        <NumberPicker

            android:id="@+id/number_picker_right"

            android:layout_width="0dp"

            android:layout_height="match_parent"

            android:layout_weight="0.15"

            android:descendantFocusability="blocksDescendants" />

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

代码调用

import android.content.Context;

import android.content.res.Resources;

import android.content.res.TypedArray;

import android.graphics.drawable.ColorDrawable;

import android.util.AttributeSet;

import android.view.View;

import android.widget.ImageView;

import android.widget.NumberPicker;

import androidx.annotation.NonNull;

import androidx.annotation.Nullable;

import androidx.constraintlayout.widget.ConstraintLayout;

import com.autel.cruiser.R;

import com.autel.lib.utils.ResourcesUtils;

import com.autel.util.log.AutelLog;

import org.jetbrains.annotations.NotNull;

import java.lang.reflect.Field;

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Calendar;

import java.util.Locale;

import java.util.Objects;

import butterknife.BindView;

import butterknife.ButterKnife;

/**

* <p> 功能描述:时间选择器

* <p>

* 详细描述:

*

* @Author: 龚寿生

* @CreateDate: 2021/8/30 14:46

* @UpdateUser: 最后一次更新者

* @UpdateDate: 2021/8/30 14:46

* @UpdateRemark: 最后一次更新说明

* @Version: 1.0 版本

*/

public class TimeDateView extends ConstraintLayout {

    private static final int MIN_ZERO = 0;

    private static final int MIN_ONE = 1;

    private static final int HOUR_OF_DAY = 24;

    private static final int MINUTE_OF_HOUR = 60;

    private static final int SECOND_OF_MINUTE = 60;

    private static final int YEAR_MAX = 5;

    private static final int MONTH_OF_YEAR = 12;

    private static final int DATE_MODE = 0;

    private static final int TIME_MODE = 1;

    @BindView(R.id.iv_bg)

    ImageView iv_bg;

    @BindView(R.id.number_picker_left)

    NumberPicker numberPickerLeft;

    @BindView(R.id.number_picker_center)

    NumberPicker numberPickerCenter;

    @BindView(R.id.number_picker_right)

    NumberPicker numberPickerRight;

    //日期或者时间

    private int mode;

    private int leftDate;

    private int centerDate;

    private int rightDate;

    private Calendar calendar;

//    public TimeDateView(@NonNull @NotNull Context context) {

//        super(context);

//        initView(context);

//    }

    public TimeDateView(@NonNull @NotNull Context context, @Nullable @org.jetbrains.annotations.Nullable AttributeSet attrs) {

        this(context, attrs, 0);

    }

    public TimeDateView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

        super(context, attrs, defStyleAttr);

        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.TimeDateView);

        mode = array.getInteger(R.styleable.TimeDateView_mode, 0);

        array.recycle();

        initView(context);

    }

    private void initView(Context context) {

        View view = inflate(context, R.layout.layout_time_date_view, this);

        ButterKnife.bind(this, view);

        initData();

        initColor();

    }

    private void initData() {

        calendar = Calendar.getInstance();

        numberPickerLeft.setWrapSelectorWheel(false);

        numberPickerLeft.setOnValueChangedListener((picker, oldVal, newVal) -> {

            leftDate = newVal;

            if (mode == DATE_MODE) {

                changeDataValue();

            }

            if (onValueChangedLister != null) {

                onValueChangedLister.onValueChanged(leftDate, centerDate, rightDate);

            }

        });

        numberPickerCenter.setWrapSelectorWheel(false);

        numberPickerCenter.setOnValueChangedListener((picker, oldVal, newVal) -> {

            centerDate = newVal;

            if (onValueChangedLister != null) {

                onValueChangedLister.onValueChanged(leftDate, centerDate, rightDate);

            }

            if (mode == DATE_MODE) {

                changeDataValue();

            }

        });

        numberPickerRight.setWrapSelectorWheel(false);

        numberPickerRight.setOnValueChangedListener((picker, oldVal, newVal) -> {

            rightDate = newVal;

            if (onValueChangedLister != null) {

                onValueChangedLister.onValueChanged(leftDate, centerDate, rightDate);

            }

        });

        if (mode == DATE_MODE) {

            initDateView();

        } else {

            initTimeView();

        }

        updateDate();

    }

    private void initTimeView() {

        iv_bg.setImageResource(R.mipmap.bg_time_date_right);

        //24小时制,限制小时数为0~23

        String[] hour = new String[HOUR_OF_DAY];

        for (int i = 0; i < hour.length; i++) {

            hour[i] = i + ResourcesUtils.getString(R.string.unit_hour);

        }

        numberPickerLeft.setDisplayedValues(hour);

        numberPickerLeft.setMinValue(MIN_ZERO);

        numberPickerLeft.setMaxValue(hour.length - 1);

        //限制分钟数为0~59

        String[] minute = new String[MINUTE_OF_HOUR];

        for (int i = 0; i < minute.length; i++) {

            minute[i] = i + ResourcesUtils.getString(R.string.unit_minute);

        }

        numberPickerCenter.setDisplayedValues(minute);

        numberPickerCenter.setMinValue(MIN_ZERO);

        numberPickerCenter.setMaxValue(minute.length - 1);

        //限制秒数为0~59

        String[] sec = new String[SECOND_OF_MINUTE];

        for (int i = 0; i < sec.length; i++) {

            sec[i] = i + ResourcesUtils.getString(R.string.unit_second);

        }

        numberPickerRight.setDisplayedValues(sec);

        numberPickerRight.setMinValue(MIN_ZERO);

        numberPickerRight.setMaxValue(sec.length - 1);

        //初始化时间位置

        leftDate = calendar.get(Calendar.HOUR_OF_DAY);

        centerDate = calendar.get(Calendar.MINUTE);

        rightDate = calendar.get(Calendar.SECOND);

    }

    private void initDateView() {

        iv_bg.setImageResource(R.mipmap.bg_time_date_left);

        //限制年份范围为前后五年

        int yearNow = calendar.get(Calendar.YEAR);

        String[] year = new String[YEAR_MAX + 1];

        for (int i = 0; i < year.length; i++) {

            year[i] = (yearNow + i) + ResourcesUtils.getString(R.string.unit_year);

        }

        numberPickerLeft.setMinValue(yearNow);

        numberPickerLeft.setMaxValue(yearNow + YEAR_MAX);

        numberPickerLeft.setDisplayedValues(year);

        //设置月份范围为1~12

        String[] month = new String[MONTH_OF_YEAR];

        for (int i = 1; i <= month.length; i++) {

            month[i - 1] = i + ResourcesUtils.getString(R.string.unit_month);

        }

        numberPickerCenter.setMinValue(MIN_ONE);

        numberPickerCenter.setMaxValue(MONTH_OF_YEAR);

        numberPickerCenter.setDisplayedValues(month);

        //设置日期

        int dayMax = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

        String[] day = new String[dayMax];

        for (int i = 1; i <= day.length; i++) {

            day[i - 1] = i + ResourcesUtils.getString(R.string.unit_day);

        }

        numberPickerRight.setMinValue(MIN_ONE);

        numberPickerRight.setMaxValue(dayMax);

        numberPickerRight.setDisplayedValues(day);

        //初始化日期位置

        leftDate = calendar.get(Calendar.YEAR);

        centerDate = calendar.get(Calendar.MONTH);

        rightDate = calendar.get(Calendar.DATE);

    }

    public void changeDataValue() {

        String dateStr = String.format(Locale.CHINA, "%d-%d", leftDate, centerDate);

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM", Locale.CHINA);

        try {

            calendar.setTime(Objects.requireNonNull(simpleDateFormat.parse(dateStr)));

        } catch (ParseException e) {

            e.printStackTrace();

        }

        //设置日期

        int dayMax = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

        AutelLog.e("gss", calendar.getTime() + "dayMax=" + dayMax);

        String[] day = new String[dayMax];

        for (int i = 1; i <= day.length; i++) {

            day[i - 1] = i + ResourcesUtils.getString(R.string.unit_day);

        }

        numberPickerRight.setMaxValue(dayMax);

        numberPickerRight.setDisplayedValues(day);

        numberPickerRight.setValue(MIN_ONE);

    }

    public void updateTimeView() {

        if (onValueChangedLister != null) {

            onValueChangedLister.onValueChanged(leftDate, centerDate, rightDate);

        }

    }

    public void updateTimeView(int leftDate, int centerDate, int rightDate) {

        this.leftDate = leftDate;

        this.centerDate = centerDate;

        this.rightDate = rightDate;

        updateDate();

    }

    private void updateDate() {

        numberPickerLeft.setValue(rightDate);

        numberPickerCenter.setValue(centerDate);

        numberPickerRight.setValue(rightDate);

    }

    private void initColor() {

        setNumberPickerDividerColor(numberPickerLeft);

        setNumberPickerDividerColor(numberPickerCenter);

        setNumberPickerDividerColor(numberPickerRight);

    }

    private void setNumberPickerDividerColor(NumberPicker numberPicker) {

        Field[] pickerFields = NumberPicker.class.getDeclaredFields();

        for (Field pf : pickerFields) {

            if (pf.getName().equals("mSelectionDivider")) {

                pf.setAccessible(true);

                try {

                    //设置分割线的颜色值

                    pf.set(numberPicker, new ColorDrawable(ResourcesUtils.getColor(R.color.transparent)));

                } catch (IllegalArgumentException | Resources.NotFoundException | IllegalAccessException e) {

                    e.printStackTrace();

                }

                break;

            }

        }

    }

    private OnValueChangedLister onValueChangedLister;

    public void setOnValueChangedLister(OnValueChangedLister onValueChangedLister) {

        this.onValueChangedLister = onValueChangedLister;

    }

    public interface OnValueChangedLister {

        void onValueChanged(int leftDate, int centerDate, int rightDate);

    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时代我西

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值