android - MvxTimePicker 不会绑定(bind)到 TimeSpan

标签 android xamarin xamarin.android mvvmcross

我有一个使用 MvvmCross 6.0 的安卓应用。我正在尝试将 MvxTimePicker 绑定(bind)到 TimeSpan。我的布局是:

<?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;
    }
}

这应该是一个非常普通的实现。 Site.Opens 是一个 TimeSpan。当我打开对话框时,出现以下错误:

[ERROR] (MvxBind) Problem seen during binding execution for binding Value for StoreOpens - problem TargetInvocationException: Exception has been thrown by the target of an invocation.

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

04-29 21:26:55.562 I/mono-stdout(20515): java.lang.NoSuchMethodError: no non-static method "Landroid/widget/TimePicker;.getHour()I" at mvvmcross.platforms.android.binding.views.MvxLayoutInflater.n_onCreateView(Native Method)04-29 21:26:55.562 I/mono-stdout(20515): at mvvmcross.platforms.android.binding.views.MvxLayoutInflater.n_onCreateView(Native Method)

我从另一个仍在运行 MvvmCross 5.x 的项目中复制了它,它正在运行。我不知道我是否错过了一步,或者 6.0 中是否出现了问题。有人对此有任何想法吗?

谢谢, 吉姆

最佳答案

从 API 23 开始,Android TimePicker 的属性似乎已更改名称。MvxTimePicker 绑定(bind)到仅存在于 API 23 和更新版本上的 Hour。我的解决方法如下。我将 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 网站上提出错误建议,但这暂时可以解决问题。

**** 更新 ****

此错误将在 MvvmCross 版本 6.0.2 中修复,我的原始帖子将按预期运行。

关于android - MvxTimePicker 不会绑定(bind)到 TimeSpan,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50093069/

相关文章:

android - DrawableLeft 与文本居中

java - 如何在Android中的GridView中在fragment中显示ArrayList对象

android - 检查您的 google-services 插件配置,未填充 default_web_client_id 字符串

android - xamarin android fragment 重叠

azure - 如何解决初始化 MobileServiceClient Xamarin.Forms 时出现的错误?

c# - 使用 xamarin 的移动跨平台本地化和仅 iOS 问题

java - 在运行时切换 fragment

xamarin - Xamarin Forms 中的 Google 钱包/Android Pay 集成

android - 错误 : Only the original thread that created a view hierarchy can touch its views in Xamarin

visual-studio - 我可以在 F# 中创建跨平台 Xamarin Forms 应用程序吗?