代码之家  ›  专栏  ›  技术社区  ›  Jim Wilcox

MvxTimePicker不会绑定到时间跨度

  •  2
  • Jim Wilcox  · 技术社区  · 8 年前

    我有一个使用MvvmCross 6.0的android应用程序。我正在尝试将MvxTimePicker绑定到时间跨度。我的布局是:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:local="http://schemas.android.com/apk/res-auto"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
      <TextView
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          style="@style/TableHeaderTextView"
          android:text="Start Time"/>
      <MvxTimePicker
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:timePickerMode="spinner"
        android:textSize="20dp"
        local:MvxBind="Value StoreOpens" />
      <Button
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:text="Close"
          local:MvxBind="Click CloseCommand" />
    </LinearLayout>
    

    我的ViewModel是:

    public class StoreOpenDialogViewModel : MvxViewModel<Site, bool>
    {
    
        private readonly IMvxNavigationService _navigationService;
    
        public StoreOpenDialogViewModel(IMvxNavigationService navigationService)
        {
            _navigationService = navigationService;
    
            CloseCommand = new MvxAsyncCommand(async () => await _navigationService.Close(this, true));
        }
    
        public override System.Threading.Tasks.Task Initialize()
        {
            return base.Initialize();
        }
    
        public override void Prepare(Site parm)
        {
            base.Prepare();
            this.Site = parm;
        }
    
        public IMvxAsyncCommand CloseCommand { get; private set; }
    
        private Site _Site;
        public Site Site
        {
            get
            {
                return _Site;
            }
            set
            {
                _Site = value;
                RaisePropertyChanged(() => Site);
                RaisePropertyChanged(() => StoreOpens);
            }
        }
    
    
        public TimeSpan StoreOpens
        {
            get
            {
                if (Site == null || Site.Opens == null)
                    return new TimeSpan(8, 0, 0);
                else
                    return Site.Opens;
            }
            set
            {
                if (Site != null)
                {
                    Site.Opens = value;
                    RaisePropertyChanged(() => StoreOpens);
                }
            }
        }
    }
    

    我的观点是:

    [MvxDialogFragmentPresentation]
    [Register(nameof(StoreOpenDialogView))]
    public class StoreOpenDialogView : MvxDialogFragment<StoreOpenDialogViewModel>
    {
        public StoreOpenDialogView()
        {
        }
    
        protected StoreOpenDialogView(IntPtr javaReference, JniHandleOwnership transfer)
            : base(javaReference, transfer)
        {
        }
    
        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            var ignore = base.OnCreateView(inflater, container, savedInstanceState);
    
            var view = this.BindingInflate(Resource.Layout.StoreOpenDialogView, null);
    
            return view;
        }
    }
    

    这应该是一个非常普通的实现。地点这是一个时间跨度。打开对话框时,出现以下错误:

    [错误](MvxBind)在绑定执行期间发现绑定问题 StoreOpens的值-问题TargetInvocationException:异常 已由调用的目标引发。

    此时将显示对话框并显示当前时间。当我尝试更改时间时,我得到:

    04-29 21:26:55.562输入/单声道标准输出(20515):java。lang.NoSuchMethodError: 没有非静态方法“Landroid/widget/TimePicker;.getHour()I” mvvmcross。平台。安卓结合视图。MVXLAyoutFlater。n\u onCreateView(本机 方法)04-29 21:26:55.562 I/单标准输出(20515):at mvvmcross。平台。安卓结合视图。MVXLAyoutFlater。n\u onCreateView(本机 方法)

    我从另一个仍在运行MvvmCross 5的项目中复制了此内容。x,它正在工作。我不知道我是否错过了一步,或者6.0中是否有什么东西坏了。有人对此有什么想法吗?

    谢谢 吉姆

    1 回复  |  直到 8 年前
        1
  •  0
  •   Jim Wilcox    8 年前

    从API 23开始,Android计时器的属性似乎已更改名称。MvxTimePicker绑定到仅在API 23和更新版本上存在的小时。我的解决方法如下。我将MvxTimePicker更改为TimePicker,如下所示:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:local="http://schemas.android.com/apk/res-auto"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            style="@style/TableHeaderTextView"
            android:text="Start Time" />
      <TimePicker
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:timePickerMode="spinner"
          android:id="@+id/tpTime"
          android:textSize="20dp" />
            <!--local:MvxBind="Value StartTime" />-->
        <LinearLayout
            android:orientation="horizontal"
            android:gravity="right"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Close"
                style="@style/DialogButton"
                local:MvxBind="Click CloseCommand" />
        </LinearLayout>
    </LinearLayout>
    

    我将MvxDialogFragment中的OnCreateView更改为:

        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            var ignore = base.OnCreateView(inflater, container, savedInstanceState);
    
            var view = this.BindingInflate(Resource.Layout.HoursStartDialogView, null);
    
            var tp = view.FindViewById<TimePicker>(Resource.Id.tpTime);
            if (Build.VERSION.SdkInt <= BuildVersionCodes.LollipopMr1)
            {
    #pragma warning disable CS0618
                tp.CurrentHour = (Java.Lang.Integer)ViewModel.StartTime.Hours;
                tp.CurrentMinute = (Java.Lang.Integer)ViewModel.StartTime.Minutes;
            }
            else
            {
                tp.Hour = ViewModel.StartTime.Hours;
                tp.Minute = ViewModel.StartTime.Minutes;
            }
    
            tp.TimeChanged += (s, e) =>
            {
                ViewModel.StartTime = new TimeSpan(e.HourOfDay, e.Minute, 0);
            };
    
            return view;
        }
    

    是的,这是一个与我原来的问题不同的应用程序,但我先修复了这个,因此一些名称发生了变化。这适用于早期版本的Android。

    我将在MvvmCross网站上提出一个bug建议,但这将暂时解决您的问题。

    ****更新****

    这个bug将在MvvmCross版本6.0.2中修复,我的原始帖子将按预期运行。

    推荐文章