0

MvvmCross は初めてなので、小さな Xamarin.Forms アプリを作成することにしました。最初に表示されるMainPage.xamlViewModelに関連付けられています。MainViewModel.cs私はFirstView.axmlその活動とともにドロイドプロジェクトにいます。関連付けられた ViewModel は、MainViewModel と並んでコア プロジェクトに配置され、名前が付けられます。FirstViewModel.cs

ナビゲート ボタンをクリックすると、MvvmCross にFirstView.axmlレイアウトが表示され、VM にバインドされます。でも、

コマンドが呼び出されるたびに、私は取得します

03-10 10:11:38.704 D/ViewRootImpl(18964): ViewPostImeInputStage ACTION_DOWN
mvx:Diagnostic: 17,87 Showing ViewModel FirstViewModel
03-10 10:11:38.854 I/mono-stdout(18964): mvx:Diagnostic: 17,87 Showing ViewModel FirstViewModel
[0:] mvx:Diagnostic: 17,87 Showing ViewModel FirstViewModel
mvx:Error: 17,91 Failed to create ContentPage FirstPage
03-10 10:11:38.894 I/mono-stdout(18964): mvx:Error: 17,91 Failed to create ContentPage FirstPage
[0:] mvx:Error: 17,91 Failed to create ContentPage FirstPage
mvx:Error: 17,92 Skipping request for FirstViewModel
03-10 10:11:38.904 I/mono-stdout(18964): mvx:Error: 17,92 Skipping request for FirstViewModel
[0:] mvx:Error: 17,92 Skipping request for FirstViewModel`

現在、プロジェクトは次のようになっています。

スタートアップ活動

[Activity(Label = "Hello MvvmCrossForms", MainLauncher = true)]
public class CrossFormsApp : FormsApplicationActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        //Init forms
        Forms.Init(this, bundle);

        InitialiseMvx();

        //Create mvxformsApp
        var mvxFormsApp = new MvxFormsApp();
        var presenter = Mvx.Resolve<IMvxViewPresenter>() as MvxFormsDroidPagePresenter;

        //Assign the viewPresenter
        presenter.MvxFormsApp = mvxFormsApp;
        LoadApplication(mvxFormsApp);

        //Start mvxApp
        Mvx.Resolve<IMvxAppStart>().Start();
    }

    private void InitialiseMvx()
    {
        if (MvxSingleton<IMvxIoCProvider>.Instance == null)
            Mvx.RegisterSingleton(MvxSimpleIoCContainer.Initialize());

        MvxAndroidSetupSingleton.EnsureSingletonAvailable(this.ApplicationContext)
                                .EnsureInitialized();
    }
}

MainViewModel

public class MainViewModel : MvxViewModel
{
    private string _inputString;

    public ICommand NavigateCommand
    {
        get { return new MvxCommand(() => ShowViewModel<FirstViewModel>()); }
    }

    public string InputString
    {
        get { return _inputString; }
        set { SetProperty(ref _inputString, value); }
    }
}

基本的に私が探しているのは、これの逆です: MvvmCross: Android で通常のビューから Mvvm ビューモデルに移動する方法は?

4

2 に答える 2

2

MvvmCross では、ViewPresenter はビュー間のナビゲーションを処理するコンポーネントです。

したがって、独自のものを作成する必要があります

  • MvxFormsDroidPagePresenterForms アプリがあるため、 から継承します。
  • の非フォーム呼び出しをリダイレクトします

    • ChangePresentation(これは通常、Close() に使用されます)
    • Show

    アクティビティを処理する ViewPresenter に ( MvxAndroidViewPresenter)

  • フォーム以外の ViewModel のリスト ( _androidViews)
class HybridDroidViewPresenter : MvxFormsDroidPagePresenter
{
    private readonly MvxAndroidViewPresenter _androidPesenter;
    private readonly List<Type> _androidViews;
    protected Activity Activity => Mvx.Resolve<IMvxAndroidCurrentTopActivity>().Activity;


    public HybridDroidViewPresenter()
    {
        _androidPesenter = new MvxAndroidViewPresenter();
        _androidViews = new List<Type>
        {
            typeof (FirstViewModel)
        };
    }

    public override void ChangePresentation(MvxPresentationHint hint)
    {
        if (Activity.GetType() != typeof (MainActivity))
        {
            // if we are not on the Forms Activity, we assume, we are on an Android Activity
            _androidPesenter.ChangePresentation(hint);
            return;
        }

        base.ChangePresentation(hint);
    }

    public override void Show(MvxViewModelRequest request)
    {
        if (_androidViews.Contains(request.ViewModelType))
        {
            _androidPesenter.Show(request);
            return;
        }

        base.Show(request);
    }
}

新しい ViewPresenter を登録するにCreateViewPresenterは、セットアップでオーバーライドする必要があります

public class Setup : MvxAndroidSetup
{
    // ...

    protected override IMvxAndroidViewPresenter CreateViewPresenter()
    {
        var presenter = new HybridDroidViewPresenter();
        Mvx.RegisterSingleton<IMvxViewPresenter>(presenter);
        return presenter;
    }
}

私たちの ViewPresenter とMvxAndroidViewPresenterニーズIMvxAndroidCurrentTopActivity. そのため、 のライフサイクルについて知らせる必要がありますMainActivityIMvxAndroidActivityLifetimeListenerこれは、次のようにアクティビティを変更して行うことができます。

[Activity(Label = "MainActivity", ScreenOrientation = ScreenOrientation.Portrait)]
public class MainActivity
    : FormsApplicationActivity
{
    private IMvxAndroidActivityLifetimeListener _lifetimeListener;

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        Forms.Init(this, bundle);
        var mvxFormsApp = new MvxFormsApp();
        LoadApplication(mvxFormsApp);

        var presenter = (MvxFormsDroidPagePresenter) Mvx.Resolve<IMvxViewPresenter>();
        presenter.MvxFormsApp = mvxFormsApp;

        Mvx.Resolve<IMvxAppStart>().Start();
        _lifetimeListener = Mvx.Resolve<IMvxAndroidActivityLifetimeListener>();
        _lifetimeListener.OnCreate(this);
    }

    protected override void OnDestroy()
    {
        _lifetimeListener.OnDestroy(this);
        base.OnDestroy();
    }

    protected override void OnNewIntent(Intent intent)
    {
        base.OnNewIntent(intent);
        _lifetimeListener.OnViewNewIntent(this);
    }

    protected override void OnResume()
    {
        base.OnResume();
        _lifetimeListener.OnResume(this);
    }

    protected override void OnPause()
    {
        _lifetimeListener.OnPause(this);
        base.OnPause();
    }

    protected override void OnStart()
    {
        base.OnStart();
        _lifetimeListener.OnStart(this);
    }

    protected override void OnRestart()
    {
        base.OnRestart();
        _lifetimeListener.OnRestart(this);
    }

    protected override void OnStop()
    {
        _lifetimeListener.OnStop(this);
        base.OnStop();
    }
}

FirstViewModelこれで、 viaに移動できるようになりました

ShowViewModel<FirstViewModel>()

FirstActivity は通常の MvvMCross Android アクティビティのように見え、 as を設定しFirstView.axmlますContentView

[Activity(Label = "FirstActivity")]
public class FirstActivity : MvxActivity<FirstViewModel>
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        SetContentView(Resource.Layout.FirstView);
    }
}

次の点に注意してください。

  • これにより、フォーム ビュー フォーム、非フォーム ビュー (ただし非フォーム ビュー) に移動することはできませんClose()
  • ライフサイクルにいくつかの問題が残っている可能性があります (トゥームストーンなど)。
  • MvvMCross の開発者は、MvvMCross の Forms サポートに不満を持っているため、Forms Presenter に重大な変更が加えられる可能性があります。
于 2016-03-10T19:14:01.240 に答える