我已经在我的项目中实现了CalendarView,我希望在点击日期时获得DD / MM / YY格式
我尝试了以下内容:
calendar =(CalendarView) findViewById(R.id.calendarforstart);
calendar.setShowWeekNumber(false);
calendar.setFirstDayOfWeek(2);
calendar.setOnDateChangeListener(new OnDateChangeListener()
{
@Override
public void onSelectedDayChange(CalendarView view, int year, int month, int day)
{
Toast.makeText(getApplicationContext(), day + "/" + month + "/" + year, Toast.LENGTH_LONG).show();
}
});
以上工作正常但如果我将日历滚动到下个月或上个月。我得到了Toast,我不想要,我只想在点击日期时才能获得祝酒?
我该如何实现?
让我知道!
谢谢!
答案 0 :(得分:1)
解决cannot select the current date
是一个艰难的方法。想法是保存每个列表项的屏幕位置,并检查每个dispatchTouchEvent
if(x,y)是否在日期视图项内。
private long lastDate = 0;
private int downX;
private int downY;
private int upX;
private int upY;
private int lastX=0;
private int lastY=0;
private ItemArea currentArea;
private int year = -1;
private int month;
private int day;
private ListView listView;
private int[] startPoint = new int[2];
private int listItemCount = 0;
private int listItemWidth = 0;
private int listItemHeight = 0;
ArrayList<ItemArea> areaList = new ArrayList<>();
private CalendarView calendar;
private boolean isInitialized = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
calendar =(CalendarView) findViewById(R.id.calendarforstart);
calendar.setShowWeekNumber(false);
calendar.setFirstDayOfWeek(2);
calendar.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
@Override
public void onSelectedDayChange(CalendarView view, int year, int month, int day) {
if(view.getDate() != lastDate) {
lastDate = view.getDate();
MainActivity.this.year = year;
MainActivity.this.month = month;
MainActivity.this.day = day;
makeToast();
currentArea = getItemArea(upX, upY);
isInitialized = true;
}
}
});
listView = (ListView)calendar.findViewById(android.R.id.list);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = (int)event.getX();
downY = (int)event.getY();
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
upX = (int)event.getX();
upY = (int)event.getY();
if (areaList.size()==0) {
generateList();
}
// make sure it's not move
if (Math.abs(downX-upX)<3 && Math.abs(downY-upY)<3) {
ItemArea area = getItemArea(upX, upY);
// on application start up and click the current date, there are stored status.
if (currentArea==null || !isInitialized) {
long time = calendar.getDate();
Calendar currentCalendar = new GregorianCalendar();
currentCalendar.setTimeInMillis(time);
year = currentCalendar.get(Calendar.YEAR);
month = currentCalendar.get(Calendar.MONTH);
day = currentCalendar.get(Calendar.DAY_OF_MONTH);
makeToast();
}
if (area!=null && area.equals(currentArea)) {
makeToast();
}
} else {
// FIXME: still have bug when drag/scroll back
// it's move event, list view will scroll up/down, and update the y
if (currentArea!=null) {
if (downY<upY) {
// move down
int times = (upY-downY)/listItemHeight;
currentArea.top+=listItemHeight*(times+1);
currentArea.bottom+=listItemHeight*(times+1);
} else {
// move up
int times = (downY-upY)/listItemHeight;
currentArea.top-=listItemHeight*(times+1);
currentArea.bottom-=listItemHeight*(times+1);
}
}
}
break;
}
return super.dispatchTouchEvent(event);
}
private void generateList() {
listItemCount = listView.getChildCount();
listItemHeight = listView.getChildAt(0).getHeight();
listItemWidth = listView.getChildAt(0).getWidth();
listView.getChildAt(0).getLocationOnScreen(startPoint);
int deltaX = (int)(listItemWidth/7.0);
for (int i=0; i< listItemCount; i++) {
for (int j=0; j<7; j++) {
areaList.add(new ItemArea(startPoint[0]+deltaX*j, startPoint[1]+listItemHeight*i,
startPoint[0]+deltaX*(j+1), startPoint[1]+listItemHeight*(i+1)));
}
}
}
private void makeToast() {
Log.d("TAG", "do your job here");
lastX = upX;
lastY = upY;
Toast.makeText(this, "" + day + "/" + month + "/" + year, Toast.LENGTH_LONG).show();
}
private ItemArea getItemArea(int x, int y) {
for (int i=0; i < areaList.size(); i++) {
if (areaList.get(i).contains(x, y)) {
return areaList.get(i);
}
}
return null;
}
private class ItemArea {
int left;
int top;
int right;
int bottom;
ItemArea(int left, int top, int right, int bottom) {
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
boolean contains(int x, int y) {
return x>=left && x<=right && y>=top && y<=bottom;
}
boolean equals(ItemArea area) {
return area!=null &&
this.right==area.right &&
this.left==area.left &&
this.bottom==area.bottom &&
this.top==area.top;
}
}
<强>更新强>
在API 22(android 5.1)中,android已将CalendarView
更改为MATERIAL
。根本没有ListView
,请检查CalendarView MODE_MATERIAL和calendarViewMode
因此,如果使用默认样式,上述代码将失败,唯一的方法是强制使用CalendarViewLegacyDelegate
,这意味着将calendarViewMode
设置为MODE_HOLO
。你可以通过添加style="@android:style/Widget.CalendarView"
来实现这一点,就像这样:
<CalendarView
android:id="@+id/calendarforstart"
style="@android:style/Widget.CalendarView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
但是你会丢失你的素材UI。您可以根据自己的需要扩展Widget.CalendarView
,但我认为它距离材料还很远。