0

CalendarView直接使用 a ,而不是 a DatePicker, b/c 它被用作下拉/弹出式对话框,其中空间是因素(用户单击日期字段右侧的按钮,然后CalendarView下拉,直接出现在字段下方,对齐/锚定到按钮)。

我遇到了两个令人震惊的问题,并且花了整整 10 个小时的时间进行调试,但没有得到解决。

问题 #1 - 缺少数周

星期似乎丢失了,根据日期,有时丢失的星期将对应于“默认”/当前日期(显示的记录包含从数据库加载的日期),所以当我显示CalendarView, 并调用 setDate () 来自动选择它,似乎不会选择任何日期(尽管CalendarView它将以缺少的一周为中心)。

在此处输入图像描述

我一直在解决这个问题的方法是手动向下滚动,然后备份几个月,刷新通常会修复显示。但是,我还没有找到一种方法来自动化这种滚动,这可能是一个潜在的解决方法。我尝试setDate()连续打电话来做这件事,但它似乎只适用于第一个电话,这将我带到了我的下一个问题。

问题 #2 -setDate()自动滚动不起作用

似乎只有第一次调用setDate()才会导致CalendarView以相应日期为中心。如果我选择一个新日期(并将其存储在私人成员中)并关闭弹出窗口,然后通过另一个下拉按钮单击将其重新打开,现在将setDate()使用这个新日期调用,那么CalendarView将以旧日期为中心/上一个日期,即使新日期实际上已被选中(我可以手动向下滚动到它确认)。

如果需要,我可以附加代码,但在花时间这样做之前,我只是想看看这是否是一个众所周知的问题。

谢谢你。

4

1 回答 1

0

This is just a work-around (also, I've been working in Monodroid/C#, not raw Android)

By first calling SetDate() with a value for the last day of the month previous to the desired display date, and then calling it with the desired date, it seems to work consistently as expected (make sure this date falls between the Max/Min dates of the CalendarView).

However, the second call needs to be posted as a runnable to the UI thread.

Here is some code (note the boolean flags to SetDate, for centering and scroll-animation, neither of which work, hence this work-around):

View view = _inflater.Inflate( Resource.Layout.CalendarViewPicker, null );

CalendarView cvPicker = view.FindViewById<Android.Widget.CalendarView>( Resource.Id.cv_picker );

DateTime lastDay = new DateTime(_date.Year, _date.Month, 1).AddDays(-1);
long lastDayTicks = Ticks( lastDay.Date );

cvPicker.SetDate( lastDayTicks, true, true );
cvPicker.Post( () => {cvPicker.SetDate(Ticks(_date.Date),true,true)} );

Passing _date.Date to Ticks() passes a DateTime with a Time of 12:00am (basically "zeros out" time element), as opposed to passing just _date, which is also a DateTime. Also, a conversion function is needed, since I'm using C#/.NET, to convert the tick-offset

private long Ticks( DateTime date )
{  
   DateTime _1970 = (new DateTime(1970, 1, 1)).AddDays(-1);

   return (date.Ticks - _1970.Ticks) / 10000;
}

Resource.Layout.CalendarViewPicker.axml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="@dimen/calendar_view_width"
  android:layout_height="@dimen/calendar_view_height"
  android:background="#FF666666">

  <Button
    android:id="@+id/btn_picker_exit"
    android:layout_width="60dp"
    android:layout_height="36dp"
    android:layout_alignParentTop="true"
    android:background="@drawable/cv_button_background"
    android:gravity="center"
    android:textColor="#FFFFFFFF"
    android:textSize="20sp"
    android:text="+"/>

  <CalendarView
    android:id="@+id/cv_picker"
    android:layout_width="@dimen/calendar_view_width"
    android:layout_height="@dimen/calendar_view_height"
    android:shownWeekCount="6"/>

<RelativeLayout/>

My reasoning for the first call to SetDate() with the last day of the previous month, was b/c many times the calendar would popup with the second week of a given month showing as the first visible week, and when scrolling up to see the first week, I would find it missing. So, I figured setting the date with the last day of the previous month might force the first week (ie, the problematic week) to show.

Now with the first week showing, I call SetDate again, but it only works when posted, b/c when posting a runnable to the UI, the event is scheduled to occur after the associated view is rendered. If 2 SetDate()'s are called consecutively (neither in a runnable), say in OnCreate(), then the effects take place before the view is rendered, and so only the second call would take effect, overwriting the first (and therefore loosing the effect of forcing the first week to show).

These two calls also fix the centering/auto-scrolling issue, which is nice too.

于 2013-08-30T20:22:45.447 回答