Выберите несколько дат в Android DatePickerDialog


person Sravan Patti    schedule 18.07.2017    source источник
comment
Без предложений, я предполагаю, что это невозможно?   -  person Sravan Patti    schedule 01.08.2017
comment
привет Шраван, что ты для этого сделал? Я должен сделать то же самое. Предложения пожалуйста..   -  person Rakesh Yadav    schedule 04.08.2017
comment
Я ничего не сделал. Похоже, я застрял, иначе я должен пойти с библиотекой тайм-сквер.   -  person Sravan Patti    schedule 04.08.2017
comment
хорошо, я собираюсь создать свой собственный с помощью gridview. Поделюсь своим кодом, если вы спросите сегодня вечером.   -  person Rakesh Yadav    schedule 05.08.2017
comment
@RakeshYadav Не могли бы вы поделиться кодом?   -  person Sravan Patti    schedule 07.08.2017


Ответы (2)


Android пока не поддерживает эту функцию. Однако вы можете создать свой собственный календарь. У меня такое же требование, и я сделал это. Обратите внимание, что я не разрешаю пользователю выбирать дату. Но пользователи могут выбирать собственные даты. Я создал фрагмент, который меняет только месяцы, поэтому он меняет адаптер, как при изменении месяца.

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

}

//Вот макет календаря фрагментов

<?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 understand, there is not anything that would trouble you. However if you have any problem. 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()

}

Макет адаптера

<?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 Output will be like that.

введите здесь описание изображения

person Rakesh Yadav    schedule 08.08.2017
comment
Привет @Rakesh Можете ли вы объяснить мне вкратце, потому что некоторые ваши занятия отсутствуют. Мне нужно создать календарь, в котором я могу показать доступный слот с несколькими датами, после чего пользователь может выбрать одну из дат из календаря. Возможно ли это из вашего кода? - person Menu; 22.12.2017
comment
@A.R., я попытался поместить некоторые комментарии, где это возможно, в свой код, как вы можете видеть, и имена переменных и имена классов не требуют пояснений. Этот код предназначен для выбора нескольких дат из календаря. Но у меня тоже такое же требование, как у вас. Вы можете задать другой вопрос по вашему требованию, у меня также есть код для вашего требования. Если вы хотите разрешить пользователю выбирать только одну дату, вам придется внести изменения в адаптер, изменения будут в логике держателя.btnDate.setOnClickListener(). - person Rakesh Yadav; 23.12.2017
comment
Я уже задавал вопрос, связанный с моим запросом. Перейдите по этой ссылке stackoverflow.com/questions/47868732/ и, пожалуйста, опубликуйте свою логику или ответ. - person Menu; 26.12.2017
comment
Эй, @Rakesh Yadav, где твой xml-файл для просмотра календаря? - person Menu; 26.12.2017
comment
@ А.Р. Я добавил макет для фрагмента календаря - person Rakesh Yadav; 26.12.2017

Кроме того, вы можете попробовать этот репозиторий, который я сделал до сих пор в своем собственном проекте.

https://github.com/Diwakarsingh9/MultiDatePickerCalendar

person Diwakar Singh    schedule 10.08.2018
comment
Замечательно! Благодарю вас! - person Sravan Patti; 31.01.2019