安卓:日历视图日期更改监听器

16
我已经实现了这个监听器,以便在单击特定日期时显示某些内容,但问题是当我向下滚动CalendarView时,它会自动显示一些内容,而我没有点击任何东西,只是向下滚动到CalendarView的另一个月份,然后就会出现一个例如Toast或Log的消息(我想这是有意义的,因为监听器本身会触发'onDateChange',而向下滚动日历也会更改当前选择的日期)。所以我的问题是,是否有适用于CalendarView的任何监听器,可以作为ondateChange监听器的替代方案,以避免当我滚动CalendarView以转到另一个月份时,它自动触发监听器。
有没有知道CalendarView的其他监听器或者有任何解决办法的人?请分享一下。
5个回答

8
当您滚动日历时,onSelectedDayChange方法的行为就像您点击不同的日期,但是这不会改变当前日期设置。 所以HFDO5是正确的,您只需要在创建日历时保存当前日期:Long date = calendar.getDate();,并在onSelectedDayChange中检查它。
if(callendar.getDate() != date){
date = calendar.getDate(); //new current date
//date is changed on real click...do things..

}

我在我的应用程序中做过这个,但当滚动日历时移动不够平滑。这是否与解决方案有关? - jack_the_beast

7

我刚遇到了同样的问题,并找到了一个解决方法。

创建“长日期”变量,当您开始打开日历窗口时,请将当前日期保存在此变量中。

Long date;
cv = (CalendarView)findViewById(R.id.calendarView1);
date = cv.getDate();

现在在监听器中,只需要检查新日期是否与日历相同:

cv.setOnDateChangeListener(new OnDateChangeListener(){
        public void onSelectedDayChange(CalendarView view, int year, int month, int dayOfMonth) {
            if(cv.getDate() != date){
                date = cv.getDate();
                Toast.makeText(view.getContext(), "Year=" + year + " Month=" + month + " Day=" + dayOfMonth, Toast.LENGTH_LONG).show();
            }               
        }
    });

对我有用:)


3
这并没有帮助setOnDateChangeListener,它始终返回最初选择的日期,因此Toast永远不会显示。如果我错了,请纠正我。 - Jay Mayu
1
你没错,这是一个解决方法...Toast 气泡提示将不会在滚动时显示,只有在选择不同日期时才会显示。 - HFDO5
@HFDO5 - 你的工作逻辑没问题,但我该如何选择当前日期? - TheDevMan
如果我实现这个功能,它会告诉我日期必须被声明为final:Variable date is accessed from within inner class, needs to be declared final 如果我这样做,就无法使用date=cv.getDate()来设置日期。 我做错了什么? - Jamie-505

3
最终,我决定在 CalendarView 下方显示一个“确定”按钮,以便选择日期并关闭日历。
因为当您单击当前日期时,没有任何反应,而当您滚动时,会调用您的 OnDateChangeListener
以下是带有黑色遮罩背景的日历布局示例,您可以单击以关闭:
<LinearLayout
    android:id="@+id/calendar_layout"
    android:onClick="dismissCalendar"
    android:visibility="gone"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="20dp"
    android:background="@color/black_mask">

    <CalendarView
        android:id="@+id/calendar"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="@color/white"
        android:showWeekNumber="false"
        android:firstDayOfWeek="2"
        />

    <TextView
        android:onClick="selectDate"
        android:text="@string/select_date"
        android:background="@color/colorPrimary"
        style="@style/settings_button"/>

</LinearLayout>

然后是示例代码:

private void openCalendar(Date date) {
    calendar.setDate(date.getTime());
    calendarLayout.setVisibility(View.VISIBLE);
}

public void selectDate(View view) {
    Date date = new Date(calendar.getDate());
    // do whatever you need with date
    dismissCalendar(view);
}

public void dismissCalendar(View view) {
    calendarLayout.setVisibility(View.INVISIBLE);
}

0
我的解决方法是使用来自HoloEverywhere的日历(可定制的源代码),将导致其调用的代码注释掉,并在onDateTapped方法中调用它,这样做可以实现期望的效果。而且在ICS之前的设备上也可以正常工作。

-1
也许我之前解决问题的方法可以给你一些启示。 当我从日历视图中选择一个日期时,会显示一个谷歌地图,展示我在那个日期走过的路线。因为纬度和经度是从数据库中检索出来的,所以我会查询该日期的数据库记录,如果没有记录,应用程序会弹出一个toast消息。否则,它会显示一个带有路线的谷歌地图。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接