我正在使用GridView和自定义BaseAdapter制作日历。我在函数中使用GregorianCalendar生成一个字符串数组,以便填充单元格。这是我的MainActivity,它处理日历的布局:
public class MainActivity extends Activity {
private GridView calendarView, daysView;
private final String[] weekdays = new String[]{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat","Sun"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
daysView = (GridView) this.findViewById(R.id.daysGridView);
daysView.setAdapter(new WeekDayGridAdapter(MainActivity.this, weekdays));
calendarView = (GridView) this.findViewById(R.id.calendarGridView);
calendarView.setAdapter(new DayGridAdapter(MainActivity.this, getMonth()));
}
private String[] getMonth(){
int gridSizeX = 7, gridSizeY = 6;
int gridsize = gridSizeX * gridSizeY;
String[] myStringArray = new String[gridSizeX*gridSizeY];
final Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
GregorianCalendar gregorianCalendar = new GregorianCalendar(year, month, 1);
//this gets the day of week range 1-7, Monday - Sunday
int dayOfWeek = gregorianCalendar.get(Calendar.DAY_OF_WEEK);
//backtracks to the beginning of current week (Monday)
gregorianCalendar.add(Calendar.DAY_OF_YEAR, Calendar.MONDAY - dayOfWeek);
for (int i = 0; i < gridsize; i++)
{
myStringArray[i] = String.valueOf(gregorianCalendar.get(Calendar.DAY_OF_MONTH));
gregorianCalendar.add(Calendar.DAY_OF_YEAR, 1);
}
return myStringArray;
}
}
以下是我的日历的外观:
我想要的是一种确定哪些单元格相对于当前月份属于上一个月或下个月的方法。在上图中,单元格将为:
答案 0 :(得分:1)
我根据JeroenVannevel的评论解决了这个问题。
获取1(包括)和1(不包括)之间的每个日期
这是我的自定义BaseAdapter:
public class DayGridAdapter extends BaseAdapter {
private Context context;
private final String[] days;
// global var to keep track of whether a day-cell belongs to the current month
Boolean in = false;
public DayGridAdapter(Context context, String[] days) {
this.context = context;
this.days = days;
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
if (convertView == null) {
gridView = new View(context);
gridView = inflater.inflate(R.layout.day_gridcell, null);
// coming from the previous month and encounter (for the first time) the cell "1"
if(days[position].equals("1") && in == false){
in = true;
}
// coming from the current month and encounter (for the second time) the cell "1"
else if (days[position].equals("1") && in == true){
in = false;
}
Button button = (Button) gridView.findViewById(R.id.day_grid_item);
button.setText(days[position]);
if(in){
//white background color
button.setBackgroundColor(context.getResources().getColor(R.color.white));
}else {
//light grey background color
button.setBackgroundColor(context.getResources().getColor(R.color.ligth2));
}
} else {
gridView = convertView;
}
return gridView;
}
@Override
public int getCount() {
return days.length;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
}
以下是现在的样子:
答案 1 :(得分:0)
我很久以前在一个快速项目中做了这件事(所以它没有经过优化)。这是我的GridAdapter(你的DayGridAdapter)
public class CalendarGridAdapter extends BaseAdapter {
private Context _context;
public String[] _days;
int _startPosition;
int _endPosition;
private java.util.Calendar _month;
public CalendarGridAdapter(Context c, Calendar monthCalendar) {
_month = monthCalendar;
_context = c;
_month.set(Calendar.DAY_OF_MONTH, 1);
refreshDays();
}
public int getCount() {
return _days.length; //(42) 6 weeks
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
/**
* Creates the calendar date view, using the correct background based on the month the date
* is in
*/
public View getView(int position, View convertView, ViewGroup parent) {
TextView dateView;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) _context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.calendar_day, null);
}
dateView = (TextView)convertView.findViewById(R.id.calendar_day_date);
//Sets the background
if(position < _startPosition -1 || position > _endPosition -1)
convertView.setBackgroundResource(R.drawable.calendar_day_unselected_month_background);
else convertView.setBackgroundResource(R.drawable.calendar_day_selected_month_background);
dateView.setText(_days[position]);
return convertView;
}
//Assumes the first day of the week is Sunday
public void refreshDays() {
int lastDay = _month.getActualMaximum(Calendar.DAY_OF_MONTH);
int firstDay = _month.get(Calendar.DAY_OF_WEEK);
_startPosition = firstDay;
//determines size of the "week" array
int size = firstDay == 1 ? lastDay : (lastDay + firstDay -1);
_endPosition = size;
_days = new String[42]; //6 weeks
int j;
//populate the beginning of the calendar with the previous months days when appropriate
Calendar prevMonth = (Calendar)_month.clone();
int prevLastDay = previousMonthDays(prevMonth);
for(j = 0; j < firstDay; j++)
_days[j] = "" + (prevLastDay - firstDay + j +2);
// populate selected months days
int dayNumber = 1;
for(int i = j-1; i < size; i++)
_days[i] = "" + dayNumber++;
//next month days (need a total of 6 rows)
for(int i = size; i < 42; i++)
_days[i] = "" + (i - size + 1);
}
private int previousMonthDays(Calendar calendar) {
if(calendar.get(Calendar.MONTH) == calendar.getActualMinimum(Calendar.MONTH)) {
calendar.set((calendar.get(Calendar.YEAR)-1),calendar.getActualMaximum(Calendar.MONTH),1);
} else {
calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH)-1);
}
return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
}
}
基本上我创建一个数组来列出所有可见的日子,然后检查一周中的哪一天是当前(选定)月份的第一天和最后一天。其他日子将有不同的背景。
然后,由于您传递了对Calendar monthCalendar
的引用,因此您所做的任何更改都会反映在CalendarGridAdapter中。
您可以通过以下方式修改月份(_selectedMonth是您的日历)
public void previousMonth() {
if(_selectedMonth.get(Calendar.MONTH) == _selectedMonth.getActualMinimum(Calendar.MONTH)) {
_selectedMonth.set((_selectedMonth.get(Calendar.YEAR)-1),_selectedMonth.getActualMaximum(Calendar.MONTH),1);
} else {
_selectedMonth.set(Calendar.MONTH, _selectedMonth.get(Calendar.MONTH)-1);
}
refreshCalendar();
}
public void nextMonth() {
if(_selectedMonth.get(Calendar.MONTH)== _selectedMonth.getActualMaximum(Calendar.MONTH)) {
_selectedMonth.set((_selectedMonth.get(Calendar.YEAR)+1),_selectedMonth.getActualMinimum(Calendar.MONTH),1);
} else {
_selectedMonth.set(Calendar.MONTH,_selectedMonth.get(Calendar.MONTH)+1);
}
refreshCalendar();
}
public void refreshCalendar() {
_calendarAdapter.refreshDays();
_calendarAdapter.setItems(days == null ? new HashSet<Integer>() : days);
_calendarAdapter.notifyDataSetChanged();
}
答案 2 :(得分:-1)
您有当月,即month
。您知道如何获取日期calendar.get(Calendar.MONTH)
。你只需要比较2:
if (calendar.get(Calendar.MONTH) == month) {
// Same month
} else {
// Not same month
}
这里的事情是你预先计算它们给适配器之前的几天,同时丢失一些信息。你应该在getView()中使用:
// Create a calendar for your month/year (these parameters you can pass to the adapter with little modifications)
GregorianCalendar gregorianCalendar = new GregorianCalendar(year, month, 1);
// Move back to the first day of the week (could be sunday)
gregorianCalendar.set(Calendar.DAY_OF_WEEK, gregorianCalendar.getFirstDayOfWeek());
// Move by *position*, being the index of the cell.
gregorianCalendar.add(Calendar.DAY_OF_MONTH, position);
String day = String.valueOf(gregorianCalendar.get(Calendar.DAY_OF_MONTH));
// Check the month for this particular day
if (calendar.get(Calendar.MONTH) == month) {
// Same month
} else {
// Not same month
}