Select multiple dates in Android DatePickerDialog

I have a requirement to select multiple dates from an Android DatePickerDialog. Below is my snippet. However, I can only choose one date. I've seen other libraries like https://github.com/square/android-times-square . But I'm more interested in native Android code.

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
}

      

+3


source to share


1 answer


Android does not support this feature until date. However, you can create your own calendar. I have the same requirement and I did it. Note that I did not allow the user to select a date. But users can choose their own dates. I created a snippet that only changes the months and so it changes the adapter like when the month changes.

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()

      

}

// Here is the layout of the 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>

      

And the most important part is the Gridview adapter. Go through the code and try to figure out what's not bothering you. However, if you have problems. Please comment.



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()

      

}

Adapter diagram

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

      

The result will be like this.

enter image description here

+1


source







All Articles