问题
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();
回答1:
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());
}
回答2:
Spinner works with an Adapter. If you want to show in your spinner the date from today up to the end of the month you can do. Let's create a model class, with one can use to feed the Adapter,
public class MyDateInterval {
public String mDateString;
public Date mDate;
public MyDateInterval(String dateString, Date date) {
mDateString = dateString;
mDate = date;
}
@Override
public String toString() {
return mDateString;
}
}
Now we define an ArrayList<MyDateInterval>
, that we will fill up with the date you want to show:
ArrayList<MyDateInterval> items = new ArrayList<>();
Retrieve the end date on the format of your example:
SimpleDateFormat dateFormat = new SimpleDateFormat("dd MMM yyyy");
Calendar c = Calendar.getInstance();
c.set(Calendar.MONTH, 6);
c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
// for the sake of the example 31 Jul 2015
Date endDate = c.getTime();
Log.e(getClass().getSimpleName(), dateFormat.format(endDate));
Now we calculated the interval from today up to the end date
Calendar todayCalendar = Calendar.getInstance();
while(endDate.after(todayCalendar.getTime())) {
items.add(new MyDateInterval(dateFormat.format(todayCalendar.getTime()), todayCalendar.getTime());
todayCalendar.add(Calendar.DAY_OF_MONTH, 1);
}
Now we all the pieces. You have to create the Adapter for the Spinner.
ArrayAdapter<MyDateInterval> dataAdapter = new ArrayAdapter<>(this,
android.R.layout.simple_spinner_item, items);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(dataAdapter);
and that should be all.
来源:https://stackoverflow.com/questions/21526982/how-to-create-spinner-to-show-current-and-next-30-dates