使用NumberPicker和PopupWindow,自定义View日历选择器

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ShenQiXiaYang/article/details/83151034

对于PopupWindow不了解的,请自行移步到Android PopupWindow详解
对于NumberPicker不了解的,请自行移步到android NumberPicker 全面解析

本次Demo总共有四种样式。由于全部贴出本文篇幅较长,所以只贴关于月日时分样式选择器代码。

下面直接看我们的自定义View,上代码:
SelectTimePop .java

import android.app.Activity;
import android.graphics.drawable.ColorDrawable;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.PopupWindow;

import com.maigu.yang.datetimepickerdemo.R;

import java.util.Calendar;

public class SelectTimePop extends PopupWindow implements OnClickListener {

    private Button btnCancel, btnConfirm;

    private DateTimePicker mDateTimePicker;

    private Calendar mDate = Calendar.getInstance();

    private OnDateTimeSetListener mOnDateTimeSetListener;

    private Activity context;

    public SelectTimePop(final Activity context, View parent) {
        super(context);
        this.context = context;
        mDateTimePicker = new DateTimePicker(context);
        mDateTimePicker.setOnDateTimeChangedListener(new DateTimePicker.OnDateTimeChangedListener() {
            @Override
            public void onDateTimeChanged(DateTimePicker view, int year, int month, int day, int hour, int minute) {
                mDate.set(Calendar.YEAR, year);
                mDate.set(Calendar.MONTH, month);
                mDate.set(Calendar.DAY_OF_MONTH, day);
                mDate.set(Calendar.HOUR_OF_DAY, hour);
                mDate.set(Calendar.MINUTE, minute);
                mDate.set(Calendar.SECOND, 0);
            }
        });
        btnCancel = (Button) mDateTimePicker.findViewById(R.id.btn_cancel);
        btnConfirm = (Button) mDateTimePicker.findViewById(R.id.btn_ok);
        btnCancel.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                dismiss();
            }
        });
        btnConfirm.setOnClickListener(this);
        // 设置SelectTimePop的View
        this.setContentView(mDateTimePicker);
        // 设置SelectTimePop弹出窗体的宽
        this.setWidth(LayoutParams.MATCH_PARENT);
        // 设置SelectTimePop弹出窗体的高
        this.setHeight(LayoutParams.WRAP_CONTENT);
        // 设置SelectTimePop弹出窗体可点击
        this.setFocusable(true);
        // 设置SelectTimePop弹出窗体动画效果
        this.setAnimationStyle(R.style.animation);
        // 设置SelectTimePop弹出窗体的背景
        ColorDrawable dw = new ColorDrawable(0xffffffff);
        this.setBackgroundDrawable(dw);
        // 在指定位置的弹出窗口中显示内容视图。
        showAtLocation(parent, Gravity.BOTTOM, 0, 0);
        anseBg();
        this.setOnDismissListener(new OnDismissListener() {

            @Override
            public void onDismiss() {
                baiseBg();
            }
        });
    }

    private void anseBg() {
        WindowManager.LayoutParams params = context.getWindow()
                .getAttributes();
        params.alpha = 0.7f;

        context.getWindow().setAttributes(params);

    }

    private void baiseBg() {
        WindowManager.LayoutParams params = context.getWindow()
                .getAttributes();
        params.alpha = 1.0f;

        context.getWindow().setAttributes(params);
    }

    @Override
    public void onClick(View v) {
        this.dismiss();
        if (mOnDateTimeSetListener != null) {
            mOnDateTimeSetListener.OnDateTimeSet(mDate.getTimeInMillis());
        }
    }

    public interface OnDateTimeSetListener {
        void OnDateTimeSet(long date);
    }

    public void setOnDateTimeSetListener(OnDateTimeSetListener callBack) {
        mOnDateTimeSetListener = callBack;
    }

}

上文代码中使用到的dialog_datedialog.xml文件

<?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="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/ll_title2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <View
            android:layout_width="match_parent"
            android:layout_height="0.8dp" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#ffffff"
            android:orientation="horizontal">

            <Button
                android:id="@+id/btn_cancel"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#ffffff"
                android:text="取消"
                android:textColor="@android:color/black"
                android:textSize="14sp"
                tools:ignore="HardcodedText" />

            <TextView
                android:id="@+id/tv_type"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="3"
                android:gravity="center"
                android:text="确认时间"
                android:textSize="16sp"
                tools:ignore="HardcodedText" />

            <Button
                android:id="@+id/btn_ok"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#ffffff"
                android:text="确定"
                android:textColor="@android:color/black"
                android:textSize="14sp"
                tools:ignore="HardcodedText" />

        </LinearLayout>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:gravity="center_horizontal"
        android:orientation="horizontal">

        <NumberPicker
            android:id="@+id/np_date"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="5" />

        <NumberPicker
            android:id="@+id/np_hour"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dp"
            android:layout_weight="2"
            tools:ignore="RtlHardcoded" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text=":"
            android:textSize="20sp"
            tools:ignore="HardcodedText" />

        <NumberPicker
            android:id="@+id/np_minute"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="2" />

    </LinearLayout>

</LinearLayout>

DateTimePicker.java

import java.util.Calendar;

import android.content.Context;
import android.text.format.DateFormat;
import android.widget.FrameLayout;
import android.widget.NumberPicker;
import android.widget.NumberPicker.OnValueChangeListener;

import com.maigu.yang.datetimepickerdemo.R;

public class DateTimePicker extends FrameLayout {

    private final NumberPicker mDateSpinner;
    private final NumberPicker mHourSpinner;
    private final NumberPicker mMinuteSpinner;

    private Calendar mDate;

    private int mHour, mMinute;

    private String[] mDateDisplayValues = new String[7];

    private OnDateTimeChangedListener mOnDateTimeChangedListener;

    public DateTimePicker(Context context) {
        super(context);
        mDate = Calendar.getInstance();

        mHour = mDate.get(Calendar.HOUR_OF_DAY);
        mMinute = mDate.get(Calendar.MINUTE);

        inflate(context, R.layout.dialog_datedialog, this);

        mDateSpinner = (NumberPicker) this.findViewById(R.id.np_date);
        (mDateSpinner.getChildAt(0)).setFocusable(false);
        // Sets the min value of the picker.——设置最小值
        mDateSpinner.setMinValue(0);
        // Sets the max value of the picker.——设置最大值
        mDateSpinner.setMaxValue(6);
        updateDateControl();
        // Sets the listener to be notified on change of the current value.——设置要在更改当前值时通知监听器。
        mDateSpinner.setOnValueChangedListener(mOnDateChangedListener);

        mHourSpinner = (NumberPicker) this.findViewById(R.id.np_hour);
        (mHourSpinner.getChildAt(0)).setFocusable(false);
        mHourSpinner.setMaxValue(23);
        mHourSpinner.setMinValue(0);
        // Set the current value for the number picker.——设置数字选择器的当前值。
        mHourSpinner.setValue(mHour);
        mHourSpinner.setOnValueChangedListener(mOnHourChangedListener);

        mMinuteSpinner = (NumberPicker) this.findViewById(R.id.np_minute);
        (mMinuteSpinner.getChildAt(0)).setFocusable(false);
        mMinuteSpinner.setMaxValue(59);
        mMinuteSpinner.setMinValue(0);
        mMinuteSpinner.setValue(mMinute);
        mMinuteSpinner.setOnValueChangedListener(mOnMinuteChangedListener);
    }

    private OnValueChangeListener mOnDateChangedListener = new OnValueChangeListener() {
        @Override
        public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
            mDate.add(Calendar.DAY_OF_MONTH, newVal - oldVal);
            updateDateControl();
            onDateTimeChanged();
        }
    };

    private OnValueChangeListener mOnHourChangedListener = new OnValueChangeListener() {
        @Override
        public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
            mHour = mHourSpinner.getValue();
            onDateTimeChanged();
        }
    };

    private OnValueChangeListener mOnMinuteChangedListener = new OnValueChangeListener() {
        @Override
        public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
            mMinute = mMinuteSpinner.getValue();
            onDateTimeChanged();
        }
    };

    private void updateDateControl() {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(mDate.getTimeInMillis());
        cal.add(Calendar.DAY_OF_YEAR, -7 / 2 - 1);
        mDateSpinner.setDisplayedValues(null);
        for (int i = 0; i < 7; ++i) {
            cal.add(Calendar.DAY_OF_YEAR, 1);
            mDateDisplayValues[i] = (String) DateFormat.format("MM月dd日", cal);
        }
        mDateSpinner.setDisplayedValues(mDateDisplayValues);
        // Sets the values to be displayed.——设置要显示的值。
        mDateSpinner.setValue(7 / 2);
        mDateSpinner.invalidate();
    }

    public interface OnDateTimeChangedListener {
        void onDateTimeChanged(DateTimePicker view, int year, int month, int day, int hour, int minute);
    }

    public void setOnDateTimeChangedListener(OnDateTimeChangedListener callback) {
        mOnDateTimeChangedListener = callback;
    }

    private void onDateTimeChanged() {
        if (mOnDateTimeChangedListener != null) {
            mOnDateTimeChangedListener.onDateTimeChanged(this, mDate.get(Calendar.YEAR),
                    mDate.get(Calendar.MONTH), mDate.get(Calendar.DAY_OF_MONTH), mHour, mMinute);
        }
    }

}

在MainActivity.java文件中的使用

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

import com.maigu.yang.datetimepickerdemo.timepicker.SelectDateTimePop;
import com.maigu.yang.datetimepickerdemo.timepicker.SelectTimePop;
import com.maigu.yang.datetimepickerdemo.timepicker.SelectYearTimePop;
import com.maigu.yang.datetimepickerdemo.util.DateUtils;

import java.text.ParseException;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button btn_date_type_one;
    private Button btn_date_type_two;
    private Button btn_date_type_three;
    private Button btn_date_type_four;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        btn_date_type_one = (Button) findViewById(R.id.btn_date_type_one);
        btn_date_type_one.setOnClickListener(this);
        btn_date_type_two = (Button) findViewById(R.id.btn_date_type_two);
        btn_date_type_two.setOnClickListener(this);
        btn_date_type_three = (Button) findViewById(R.id.btn_date_type_three);
        btn_date_type_three.setOnClickListener(this);
        btn_date_type_four = (Button) findViewById(R.id.btn_date_type_four);
        btn_date_type_four.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_date_type_one:
                SelectTimePop selectTimePop = new SelectTimePop(MainActivity.this, btn_date_type_one);
                selectTimePop.setOnDateTimeSetListener(new SelectTimePop.OnDateTimeSetListener() {
                    @Override
                    public void OnDateTimeSet(long date) {
                        String time = null;
                        try {
                            time = DateUtils.longToString(date, "MM月dd日 HH时:mm分");
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                        btn_date_type_one.setText(time);
                    }
                });
                break;
            case R.id.btn_date_type_two:
                SelectYearTimePop selectYearTimePop = new SelectYearTimePop(MainActivity.this, btn_date_type_two, true);
                selectYearTimePop.setOnDateTimeSetListener(new SelectYearTimePop.OnDateTimeSetListener() {
                    @Override
                    public void OnDateTimeSet(long date, int i, View v) throws ParseException {
                        String time = null;
                        try {
                            time = DateUtils.longToString(date, "yyyy年");
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                        btn_date_type_two.setText(time);
                    }
                });
                break;
            case R.id.btn_date_type_three:
                SelectDateTimePop selectDateTimePop = new SelectDateTimePop(MainActivity.this, btn_date_type_three, true, false);
                selectDateTimePop.setOnDateTimeSetListener(new SelectDateTimePop.OnDateTimeSetListener() {
                    @Override
                    public void OnDateTimeSet(long date, int i, View v) throws ParseException {
                        String time = null;
                        try {
                            time = DateUtils.longToString(date, "yyyy年MM月dd日");
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                        btn_date_type_three.setText(time);
                    }
                });
                break;
            case R.id.btn_date_type_four:
                SelectDateTimePop selectDateTimePopLast = new SelectDateTimePop(MainActivity.this, btn_date_type_three, true, true);
                selectDateTimePopLast.setOnDateTimeSetListener(new SelectDateTimePop.OnDateTimeSetListener() {
                    @Override
                    public void OnDateTimeSet(long date, int i, View v) throws ParseException {
                        String time = null;
                        try {
                            time = DateUtils.longToString(date, "yyyy年MM月dd日");
                            if (i == 0) {
                                btn_date_type_four.setText(time + " 上午");
                            } else {
                                btn_date_type_four.setText(time + " 下午");
                            }
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                    }
                });
                break;
            default:
                break;
        }
    }

}

MainActivity.java中使用的activity_main.xml文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn_date_type_one"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="点击弹出月日时分选择器"
        tools:ignore="HardcodedText" />

    <Button
        android:id="@+id/btn_date_type_two"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/btn_date_type_one"
        android:layout_centerInParent="true"
        android:text="点击弹出年选择器"
        tools:ignore="HardcodedText" />

    <Button
        android:id="@+id/btn_date_type_three"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/btn_date_type_two"
        android:layout_centerInParent="true"
        android:text="点击弹出年月日选择器"
        tools:ignore="HardcodedText" />

    <Button
        android:id="@+id/btn_date_type_four"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/btn_date_type_three"
        android:layout_centerInParent="true"
        android:text="点击弹出年月日上下午选择器"
        tools:ignore="HardcodedText" />

</RelativeLayout>

运行效果图:
样式一:月日时分选择器(上面代码运行后就是此效果图)
在这里插入图片描述
样式二:年选择器
在这里插入图片描述
样式三:年月日选择器
在这里插入图片描述
样式四:年月日上下午选择器
在这里插入图片描述

项目中的代码可以自定义改动,定制自己想要的日历选择器。

Demo源码下载

Github源码下载

猜你喜欢

转载自blog.csdn.net/ShenQiXiaYang/article/details/83151034
今日推荐