How to create Spinner to show current and next 30 dates

android, android-spinner, custom-datetimepicker, date, java

Solution

There are a simple example of adapter for `Spinner` below.

public class CalendarSpinnerAdapter extends BaseAdapter {

    private SimpleDateFormat mDateFormat = new SimpleDateFormat("d MMM yyyy");

    private LayoutInflater mInflater;
    private Calendar mCalendar;
    private int mDayCount;
    private int mLastRequestedDay = 0;

    public CalendarSpinnerAdapter(Context context, int dayCount) {
        mInflater = LayoutInflater.from(context);
        mDayCount = dayCount;
        mCalendar = Calendar.getInstance();
    }

    @Override
    public int getCount() {
        return mDayCount;
    }

    @Override
    public Calendar getItem(int position) {
        mCalendar.add(Calendar.DAY_OF_YEAR, position - mLastRequestedDay);
        mLastRequestedDay = position;
        return mCalendar;
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = mInflater.inflate(android.R.layout.simple_spinner_dropdown_item, parent, false);
        }

        Calendar item = getItem(position);
        ((TextView) convertView).setText(mDateFormat.format(item.getTimeInMillis()));

        return convertView;
    }

    @Override
    public View getDropDownView(int position, View convertView, ViewGroup parent) {
        return getView(position, convertView, parent);
    }
}

How to use it for display current date and next 29 days:

mDateSpinner.setAdapter(new CalendarSpinnerAdapter(getActivity(), 30));

UPD:

We should add a parameter to adapter's constructor for setting the starting date:

public CalendarSpinnerAdapter(Context context, Calendar startDate, int dayCount) {
    mInflater = LayoutInflater.from(context);
    mDayCount = dayCount;
    mCalendar = Calendar.getInstance();
    mCalendar.setTimeInMillis(startDate.getTimeInMillis());
}

Then add listener for `spinnerDateIn` where we can initialize the second spinner:

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

    Spinner spinnerDateIn = (Spinner) findViewById(R.id.spinnerDateIn);
    final Spinner spinnerDateOut = (Spinner) findViewById(R.id.spinnerDateOut);

    mSpinnerDateInAdapter = new CalendarSpinnerAdapter(SpinnerDateActivity.this, Calendar.getInstance(), 30);
    spinnerDateIn.setAdapter(mSpinnerDateInAdapter);

    spinnerDateIn.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            Calendar dateIn = Calendar.getInstance();
            dateIn.setTimeInMillis(mSpinnerDateInAdapter.getItem(position).getTimeInMillis());
            dateIn.add(Calendar.DAY_OF_YEAR, 1); // add one day
            mSpinnerDateOutAdapter = new CalendarSpinnerAdapter(SpinnerDateActivity.this, dateIn, 30);
            spinnerDateOut.setAdapter(mSpinnerDateOutAdapter);
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    });
}

I didn't try this code but it should work.

UPD2:

`spinnerDate.setSelection(position)` returns `Calendar` class instance. If you want to get selected date as `String` you should format it. Try to use following method:

private String getSelectedDateAsString(Spinner dateSpinner) {
    Calendar selectedDate = (Calendar) dateSpinner.getSelectedItem();
    return new SimpleDateFormat("d MMM yyyy").format(selectedDate.getTimeInMillis());
}

Problem

How can I create a date Spinner, which shows current date in EditText as default and future dates in Spinner (like, for next 30 days) I used date picker in many apps, so I am familiar with date picker dialog but don't have any idea about date spinner. Note Please don't tell me How to style EditText as Spinner EDITED: 1 AS RECOMMENDED BY `@erakitin` ``` @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_date); Spinner spinnerDateIn = (Spinner) findViewById(R.id.spinnerDateIn); Spinner spinnerDateOut = (Spinner) findViewById(R.id.spinnerDateOut); spinnerDateIn.setAdapter(new CalendarSpinnerAdapter(SpinnerDateActivity.this, 30)); } ``` EDITED: 2 AS RECOMMENDED BY `@erakitin` in new update ``` CalendarSpinnerAdapter mSpinnerDateInAdapter = new CalendarSpinnerAdapter(SpinnerDateActivity.this, 30); spinnerDate.setAdapter(mSpinnerDateInAdapter); spinnerDate.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { spinnerDate.setSelection(position); } @Override public void onNothingSelected(AdapterView<?> parent) { } }); ``` Now, trying to get value of selected Item in String but getting: `java.util.GregorianCalendar`, where i am doing mistake ? ``` strDate = spinnerDate.getSelectedItem().toString(); ```

Original source

Related problems