MvxTimePicker не будет привязан к TimeSpan - PullRequest
0 голосов
/ 30 апреля 2018

У меня есть приложение для Android, использующее MvvmCross 6.0. Я пытаюсь привязать MvxTimePicker к 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>

Моя модель просмотра:

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 - это интервал времени. Когда я открываю диалог, я получаю следующую ошибку:

[ОШИБКА] (MvxBind) Проблема при выполнении привязки для привязки Значение для StoreOpens - проблема TargetInvocationException: исключение был брошен целью вызова.

Появится диалоговое окно и показано текущее время. Когда я пытаюсь изменить время, я получаю:

04-29 21: 26: 55.562 I / mon-stdout (20515): java.lang.NoSuchMethodError: нет нестатического метода "Landroid / widget / TimePicker; .getHour () I" в mvvmcross.platforms.android.binding.views.MvxLayoutInflater.n_onCreateView (Native Метод) 04-29 21: 26: 55,562 I / моностадия (20515): в mvvmcross.platforms.android.binding.views.MvxLayoutInflater.n_onCreateView (Native Метод)

Я скопировал это из другого проекта, в котором все еще работает MvvmCross 5.x, и он работает. Я не знаю, пропустил ли я шаг или что-то сломалось в 6.0. У кого-нибудь есть идеи по этому поводу?

Спасибо, Jim

1 Ответ

0 голосов
/ 01 мая 2018

Похоже, что свойства Android TimePicker изменили имена с API 23. MvxTimePicker привязывается к Hour, который существует только в 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>

Я изменил OnCreateView в моем MvxDialogFragment на:

    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, и мой оригинальный пост будет работать как положено.

...