Select Android DatePickerDialog 中的多个日期

Select multiple dates in Android DatePickerDialog

我需要 select 来自 Android DatePickerDialog 的多个日期。下面是我的片段。有了这个,我只能 select 一次约会。我见过其他库,例如 https://github.com/square/android-times-square。但是,我对原生 Android 代码更感兴趣。

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val currentDate = Calendar.getInstance()
        val year = currentDate.get(Calendar.YEAR)
        val month = currentDate.get(Calendar.MONTH)
        val day = currentDate.get(Calendar.DAY_OF_MONTH)

        val maxDate = Calendar.getInstance()
        maxDate.add(Calendar.MONTH, 3)

        val datePickerDialog = DatePickerDialog(activity, onDateSet, year, month, day)
        datePickerDialog.datePicker.minDate = currentDate.timeInMillis
        datePickerDialog.datePicker.maxDate = maxDate.timeInMillis

        return datePickerDialog
}

Android 到目前为止不支持此功能。但是,您可以创建自己的日历。我有同样的要求并且已经做到了。请注意,我不允许用户 select 任何日期。但用户可以 select 自定义日期。我创建了一个仅更改月份的片段,因此它会在更改月份时更改适配器。

public class CalendarFragment extends DialogFragment {

private final String TAG = CalendarFragment.class.getSimpleName();

private static CalendarFragment instance;
private View view;
private ImageView ivDecrementMonth, ivIncrementMonth;
private TextView btnOk, btnCancel;
public TextView tvMonthYear;
private int counter = 0;
private int year = 2017;
private static CalendarActivity INSTANCE;

private Calendar calendarMinimumDate, calendarMaximumDate;

private GridView gridCalendarView;
private ArrayList<EventDateSelectionBean> listEventDates;
private String from;

public static final String KEY_EVENT_DATES = "key event dates";
public static final String KEY_FROM = "key from";

public static final String FROM_ANNOUNCEMENT_ACTIVITY = "from announcement activity";
public static final String FROM_BOOKING_DIALOG = "from booking dialog";
private List<String> listMonths;

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    Dialog dialog = super.onCreateDialog(savedInstanceState);
    WindowManager.LayoutParams wlmp = dialog.getWindow().getAttributes();
    wlmp.gravity = Gravity.CENTER | Gravity.FILL_HORIZONTAL;
    wlmp.dimAmount = 0.0F;
    dialog.getWindow().setAttributes(wlmp);
    dialog.getWindow().setWindowAnimations(R.style.DialogTheme);
    dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
    dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
    dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
    return dialog;
}
//End of onCreateDialog()

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    if (view == null) {
        instance = this;
        view = inflater.inflate(R.layout.activity_calendar, container);
        findViewsId();
        setData();
        setClickListeners();
    }

    LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams();


    return view;
}
//End of onCreateView()

private void findViewsId() {

    ivDecrementMonth = (ImageView) view.findViewById(R.id.ivDecrementMonth);
    ivIncrementMonth = (ImageView) view.findViewById(R.id.ivIncrementMonth);
    gridCalendarView = (GridView) view.findViewById(R.id.calendar);
    tvMonthYear = (TextView) view.findViewById(R.id.tvMonthYear);
    btnOk = (TextView) view.findViewById(R.id.btnOk);
    btnCancel = (TextView) view.findViewById(R.id.btnCancel);

}
//End of findViewsId()

private void setData() {
    listMonths = Arrays.asList(getResources().getStringArray(R.array.months));

    Bundle bundle = getArguments();

    calendarMinimumDate = Calendar.getInstance();
    calendarMinimumDate.setTimeInMillis(System.currentTimeMillis());
    calendarMaximumDate = Calendar.getInstance();
    calendarMaximumDate.setTimeInMillis(System.currentTimeMillis());

    btnOk.setText(getString(R.string.ok));
    btnCancel.setText(getString(R.string.cancel));

    listEventDates = bundle.getParcelableArrayList(KEY_EVENT_DATES);
    from = bundle.getString(KEY_FROM);

    //setMinMaxDateCalendar();

    counter = calendarMinimumDate.get(Calendar.MONTH);
    year = calendarMinimumDate.get(Calendar.YEAR);
    tvMonthYear.setText(listMonths.get(counter) + " " + year);

    MyCalendarAdapter adapter = new MyCalendarAdapter(GoToTourActivity.getInstance(),
            listEventDates, counter, year);
    gridCalendarView.setAdapter(adapter);
}
//End of setData()

private void setClickListeners() {
    btnOk.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (from.equals(FROM_ANNOUNCEMENT_ACTIVITY)) {
                GoToTourActivity.getInstance().setDate(listEventDates);
            } else if (from.equals(FROM_BOOKING_DIALOG)) {
                BookDialogs.getInstance().setDate(listEventDates);
            }
            dismiss();
        }
    });

    btnCancel.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            dismiss();
        }
    });

    ivDecrementMonth.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (counter == 0) {
                counter = listMonths.size() - 1;
                year = year - 1;
            } else {
                counter--;
            }
            tvMonthYear.setText(listMonths.get(counter) + " " + year);
            updateCalendar();
        }
    });

    ivIncrementMonth.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (counter == (listMonths.size() - 1)) {
                counter = 0;
                year = year + 1;
            } else {
                counter++;
            }
            tvMonthYear.setText(listMonths.get(counter) + " " + year);
            updateCalendar();
        }
    });
}
//End of setClickListeners()

private void updateCalendar() {
    MyCalendarAdapter adapter = new MyCalendarAdapter(GoToTourActivity.getInstance(),
            listEventDates, counter, year);
    gridCalendarView.setAdapter(adapter);
}
//End of updateCalendar()

}

//这里是Fragment Calendar的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mainlayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:weightSum="1">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="0.1"
    android:background="#FFF"
    android:gravity="center"
    android:orientation="horizontal"
    android:weightSum="1">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="0.2"
        android:background="#FFF"
        android:gravity="center"
        android:orientation="horizontal">

        <LinearLayout
            android:id="@+id/llPrev"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="@dimen/margin">

            <ImageButton
                android:id="@+id/back"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginRight="2dp"
                android:padding="1dp"
                android:src="@drawable/slide_right" />

        </LinearLayout>

    </LinearLayout>

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="0.6"
        android:gravity="center">

        <TextView
            android:id="@+id/tvMonthYear"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="DECEMBER 2017"
            android:textAllCaps="false"
            android:textColor="#000"
            android:textSize="22dp" />
    </LinearLayout>


    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="0.2"
        android:background="#FFF"
        android:gravity="center"
        android:orientation="horizontal">

        <LinearLayout
            android:id="@+id/llNext"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="@dimen/margin">

            <ImageButton
                android:id="@+id/forw"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="2dp"
                android:padding="1dp"
                android:rotation="180"
                android:src="@drawable/slide_right" />

        </LinearLayout>

    </LinearLayout>

</LinearLayout>

<LinearLayout
    android:id="@+id/llcalender"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="0.9"
    android:background="#FFF">

    <GridView
        android:id="@+id/calgrid"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:numColumns="7">

    </GridView>
</LinearLayout>

而最重要的部分是 Gridview Adapter。通读代码并尝试理解,没有任何问题会困扰您。但是,如果您有任何问题。请评论。

public MyCalendarAdapter(Context context, ArrayList<EventDateSelectionBean> listEvents, int month, int year) {
    super();
    this._context = context;
    dateDefaultTextColor = context.getResources().getColor(R.color.calendar_date_default_text_color);
    dateInEventTextColor = context.getResources().getColor(R.color.calendar_date_in_event_text_color);
    dateInEventSelectedTextColor = context.getResources().getColor(R.color.calendar_date_in_event_selected_text_color);

    this.list = new ArrayList<>();
    Calendar calendar = Calendar.getInstance();
    setCurrentDayOfMonth(calendar.get(Calendar.DAY_OF_MONTH));
    setCurrentWeekDay(calendar.get(Calendar.DAY_OF_WEEK));
    this.listEvents = listEvents;

    currentMonth = month;
    currentYear = year;

    // Print Month
    printMonth(month, year);

    eventCalendar = Calendar.getInstance();
    eventCalendar.setTimeInMillis(System.currentTimeMillis());
    currentDayCalendar = Calendar.getInstance();
    currentDayCalendar.setTimeInMillis(System.currentTimeMillis());

    currentDayCalendar.set(Calendar.MONTH, currentMonth);
    currentDayCalendar.set(Calendar.YEAR, currentYear);
}

private String getMonthAsString(int i) {
    return months[i];
}

private int getNumberOfDaysOfMonth(int i) {
    if (currentYear % 4 == 0 && i == 1) {
        return daysOfMonth[i] + 1;
    } else {
        return daysOfMonth[i];
    }
}

public String getItem(int position) {
    return list.get(position);
}

@Override
public int getCount() {
    return list.size();
}

private void printMonth(int mm, int yyyy) {
    int trailingSpaces = 0;
    int daysInPrevMonth = 0;
    int prevMonth = 0;
    int prevYear = 0;
    int nextMonth = 0;
    int nextYear = 0;

    int currentMonth = mm/* - 1*/;
    daysInMonth = getNumberOfDaysOfMonth(currentMonth);

    // Gregorian Calendar : MINUS 1, set to FIRST OF MONTH
    GregorianCalendar cal = new GregorianCalendar(yyyy, currentMonth, 1);

    if (currentMonth == 11) {
        prevMonth = currentMonth - 1;
        daysInPrevMonth = getNumberOfDaysOfMonth(prevMonth);
        nextMonth = 0;
        prevYear = yyyy;
        nextYear = yyyy + 1;
    } else if (currentMonth == 0) {
        prevMonth = 11;
        prevYear = yyyy - 1;
        nextYear = yyyy;
        daysInPrevMonth = getNumberOfDaysOfMonth(prevMonth);
        nextMonth = 1;
    } else {
        prevMonth = currentMonth - 1;
        nextMonth = currentMonth + 1;
        nextYear = yyyy;
        prevYear = yyyy;
        daysInPrevMonth = getNumberOfDaysOfMonth(prevMonth);
    }

    int currentWeekDay = cal.get(Calendar.DAY_OF_WEEK) - 1;
    trailingSpaces = currentWeekDay;

    // Trailing Month days
    for (int i = 0; i < trailingSpaces; i++) {
        list.add(String.valueOf((daysInPrevMonth - trailingSpaces + DAY_OFFSET) + i) + "-GREY" + "-" + getMonthAsString(prevMonth) + "-" + prevYear);
    }

    // Current Month Days
    for (int i = 1; i <= daysInMonth; i++) {
        if (i == getCurrentDayOfMonth())
            list.add(String.valueOf(i) + "-BLUE" + "-" + getMonthAsString(currentMonth) + "-" + yyyy);
        else
            list.add(String.valueOf(i) + "-WHITE" + "-" + getMonthAsString(currentMonth) + "-" + yyyy);
    }

    // Leading Month days
    for (int i = 0; i < list.size() % 7; i++) {
        list.add(String.valueOf(i + 1) + "-GREY" + "-" + getMonthAsString(nextMonth) + "-" + nextYear);
    }
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    //Blue - Current Day
    //White - Current Month
    //Grey - Next Month
    final ViewHolder holder;
    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) _context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.calendar_day_gridcell, parent, false);
        holder = new ViewHolder(convertView);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    // ACCOUNT FOR SPACING
    String[] day_color = list.get(position).split("-");
    String theday = day_color[0];

    // Set the Day GridCell
    holder.btnDate.setText(theday);

    if (day_color[1].equals("WHITE") || day_color[1].equals("BLUE")) {      //For Current Month
        holder.btnDate.setTextColor(dateDefaultTextColor);
        holder.btnDate.setBackgroundResource(R.drawable.date_default_bg);

        currentDayCalendar.set(Calendar.DAY_OF_MONTH, Integer.valueOf(theday));

        for (int i = 0; i < listEvents.size(); i++) {

            EventDateSelectionBean eventDate = listEvents.get(i);
            setDataInEventCalendar(eventDate.getDate());

            if(Commons.checkDateEquality(currentDayCalendar, eventCalendar)) {

                final EventDateSelectionBean finalEventDate = eventDate;
                if(finalEventDate.isSelected()) {
                    holder.btnDate.setBackgroundResource(R.drawable.date_selected_bg);
                    holder.btnDate.setTextColor(dateInEventSelectedTextColor);

                } else {
                    holder.btnDate.setBackgroundResource(R.drawable.date_unselected);
                    holder.btnDate.setTextColor(dateInEventTextColor);
                }

                holder.btnDate.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        if(finalEventDate.isSelected()) {
                            finalEventDate.setSelected(false);
                            holder.btnDate.setBackgroundResource(R.drawable.date_unselected);
                            holder.btnDate.setTextColor(dateInEventTextColor);

                        } else {
                            finalEventDate.setSelected(true);
                            holder.btnDate.setBackgroundResource(R.drawable.date_selected_bg);
                            holder.btnDate.setTextColor(dateInEventSelectedTextColor);
                        }
                    }
                });
                break;
            }
        }
    } else {       //For Previous and next month dates
        holder.btnDate.setAlpha(0.4f);
        holder.btnDate.setBackgroundResource(R.drawable.date_default_bg);
        //holder.btnDate.setVisibility(View.INVISIBLE);
        holder.llBtnParent.setVisibility(View.INVISIBLE);
    }

    if (position == list.size() - 1) {
        //Set Default data
    }
    return convertView;
}
//End of getView()

public class ViewHolder {
    Button btnDate;
    LinearLayout llBtnParent;

    public ViewHolder(View view) {
        btnDate = (Button) view.findViewById(R.id.calendar_day_gridcell);
        llBtnParent = (LinearLayout) view.findViewById(R.id.llBtnParent);
    }
}

public int getCurrentDayOfMonth() {
    return currentDayOfMonth;
}

private void setCurrentDayOfMonth(int currentDayOfMonth) {
    this.currentDayOfMonth = currentDayOfMonth;
}

public void setCurrentWeekDay(int currentWeekDay) {
    this.currentWeekDay = currentWeekDay;
}

private void setDataInEventCalendar(String date) {
    String splittedDate[] = date.split("-");
    eventCalendar.set(Calendar.YEAR, Integer.valueOf(splittedDate[0]));
    eventCalendar.set(Calendar.MONTH, (Integer.valueOf(splittedDate[1]) - 1));
    eventCalendar.set(Calendar.DAY_OF_MONTH, Integer.valueOf(splittedDate[2]));

}
//End of setDataInEventCalendar()

}

适配器布局为

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_margin="1dp"
android:background="@android:color/transparent"
android:id="@+id/llBtnParent">

<LinearLayout
    android:layout_width="44dp"
    android:layout_height="44dp"
    android:layout_margin="1dp"
    android:background="@drawable/day_calendar"
    android:padding="1dp"
    android:gravity="center">

    <com.yaashvi.placeandpeople.customviews.AttendanceButton
        android:id="@+id/calendar_day_gridcell"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:text="1"
        android:gravity="left"
        android:paddingLeft="2dp"
        android:textSize="12sp"/>
</LinearLayout>

输出就是这样。

此外,您可以尝试我目前在自己的项目中完成的这个存储库

https://github.com/Diwakarsingh9/MultiDatePickerCalendar