2014-02-06 15 views
0

我想在MonoDroid和MvvmCross中構建自己的選項卡。如何在MvvmCross中創建自己的選項卡?

構建我自己的選項卡的原因是我可以進一步控制它們。即使它們不在選項卡中,我也希望每個屏幕上都有它們,我想控制某些選項卡上的點擊。

加載頁面上的兩個片段是好的,但是當我點擊導航到下一個內容片段的選項卡片段或內容片段上的按鈕時,我收到錯誤消息「發生了未處理的異常。」。這不是很有幫助。

02-06 10:15:13.947 W/dalvikvm(2040): JNI WARNING: JNI method called with exception pending 
02-06 10:15:13.947 W/dalvikvm(2040):    in Lcirrious/mvvmcross/droid/fragging/MvxEventSourceFragmentActivity;.n_startActivityForResult:(Landroid/content/Intent;I)V (NewString) 
In mgmain JNI_OnLoad 
02-06 10:15:13.947 W/dalvikvm(2040): Pending exception is: 
02-06 10:15:13.947 I/dalvikvm(2040): android.content.ActivityNotFoundException: Unable to find explicit activity class {frags.droid/frags.droid.views.frags.ChildTwoView}; have you declared this activity in your AndroidManifest.xml? 
02-06 10:15:13.947 I/dalvikvm(2040): (raw stack trace not found) 
02-06 10:15:13.947 I/dalvikvm(2040): "main" prio=5 tid=1 NATIVE 
02-06 10:15:13.947 I/dalvikvm(2040): | group="main" sCount=0 dsCount=0 obj=0x41aaf710 self=0x41a96210 
02-06 10:15:13.957 I/dalvikvm(2040): | sysTid=2040 nice=0 sched=0/0 cgrp=apps handle=1074675708 
02-06 10:15:13.957 I/dalvikvm(2040): | state=R schedstat=(0 0 0) utm=164 stm=41 core=0 
02-06 10:15:13.967 I/dalvikvm(2040): #00 pc 000012fe /system/lib/libcorkscrew.so (unwind_backtrace_thread+29) 
02-06 10:15:13.967 I/dalvikvm(2040): #01 pc 0006324e /system/lib/libdvm.so (dvmDumpNativeStack(DebugOutputTarget const*, int)+33) 
02-06 10:15:13.967 I/dalvikvm(2040): #02 pc 000572b8 /system/lib/libdvm.so (dvmDumpThreadEx(DebugOutputTarget const*, Thread*, bool)+395) 
02-06 10:15:13.967 I/dalvikvm(2040): #03 pc 00057326 /system/lib/libdvm.so (dvmDumpThread(Thread*, bool)+25) 
02-06 10:15:13.967 I/dalvikvm(2040): #04 pc 0003b530 /system/lib/libdvm.so 
02-06 10:15:13.967 I/dalvikvm(2040): #05 pc 0003eef2 /system/lib/libdvm.so 
02-06 10:15:13.967 I/dalvikvm(2040): at cirrious.mvvmcross.droid.fragging.MvxEventSourceFragmentActivity.n_startActivityForResult(Native Method) 
02-06 10:15:13.967 I/dalvikvm(2040): at cirrious.mvvmcross.droid.fragging.MvxEventSourceFragmentActivity.startActivityForResult(MvxEventSourceFragmentActivity.java:110) 
02-06 10:15:13.967 I/dalvikvm(2040): at android.app.Activity.startActivity(Activity.java:3661) 
02-06 10:15:13.967 I/dalvikvm(2040): at android.app.Activity.startActivity(Activity.java:3629) 
02-06 10:15:13.967 I/dalvikvm(2040): at mono.android.view.View_OnClickListenerImplementor.n_onClick(Native Method) 
02-06 10:15:13.967 I/dalvikvm(2040): at mono.android.view.View_OnClickListenerImplementor.onClick(View_OnClickListenerImplementor.java:29) 
02-06 10:15:13.967 I/dalvikvm(2040): at android.view.View.performClick(View.java:4475) 
02-06 10:15:13.967 I/dalvikvm(2040): at android.view.View$PerformClick.run(View.java:18786) 
02-06 10:15:13.967 I/dalvikvm(2040): at android.os.Handler.handleCallback(Handler.java:730) 
02-06 10:15:13.967 I/dalvikvm(2040): at android.os.Handler.dispatchMessage(Handler.java:92) 
02-06 10:15:13.967 I/dalvikvm(2040): at android.os.Looper.loop(Looper.java:137) 
02-06 10:15:13.967 I/dalvikvm(2040): at android.app.ActivityThread.main(ActivityThread.java:5419) 
02-06 10:15:13.967 I/dalvikvm(2040): at java.lang.reflect.Method.invokeNative(Native Method) 
02-06 10:15:13.967 I/dalvikvm(2040): at java.lang.reflect.Method.invoke(Method.java:525) 
02-06 10:15:13.967 I/dalvikvm(2040): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187) 
02-06 10:15:13.967 I/dalvikvm(2040): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003) 
02-06 10:15:13.967 I/dalvikvm(2040): at dalvik.system.NativeStart.main(Native Method) 

我所有的自定義代碼如下。

我有我自己的CustomPresenter

public class CustomPresenter : MvxAndroidViewPresenter, ICustomPresenter 
{ 
    // map between view-model and fragment host which creates and shows the view based on the view-model type 
    private Dictionary<Type, IFragmentHost> dictionary = new Dictionary<Type, IFragmentHost>(); 

    public override void Show(MvxViewModelRequest request) 
    { 
     IFragmentHost host; 
     if (this.dictionary.TryGetValue(request.ViewModelType, out host)) 
     { 
      if (host.Show(request)) 
      { 
       return; 
      } 
     } 
     base.Show(request); 
    } 

    public void Register(Type viewModelType, IFragmentHost host) 
    { 
     this.dictionary[viewModelType] = host; 
    } 
} 

我使用的是MvxFragmentActivity作爲我的主視圖將包含在頂部的內容部分和底部的標籤,這也實現了IFragmentHost。所有頁面都將是碎片,包括標籤。

public class FirstView : MvxFragmentActivity, IFragmentHost 
{ 

    ChildTwoView _childTwo; 

    public bool Show(Cirrious.MvvmCross.ViewModels.MvxViewModelRequest request) 
    { 
     // create view model 
     var loaderService = Mvx.Resolve<IMvxViewModelLoader>(); 
     var viewModel = loaderService.LoadViewModel(request, null /* saved state */); 

     _childTwo = (ChildTwoView)SupportFragmentManager.FindFragmentById(Resource.Layout.childtwoview); 

     var customPresenter = Mvx.Resolve<ICustomPresenter>(); 
     //customPresenter.Register(Type) 

     // decide which fragment to create based on the view-model type 

     var fm = this.SupportFragmentManager; 
     var ft = fm.BeginTransaction(); 


     if (viewModel.GetType().Name == "ChildTwoViewModel") 
     { 
      var fragmentView = new ChildTwoView(); 
      ft.Replace(Resource.Id.childViewHost, fragmentView); 
     } 

     //var fragmentView = viewModel.GetType().Name; 
     // load fragment into view 


     ft.AddToBackStack(null); 
     ft.Commit(); 
     return true; 
    } 

    protected override void OnCreate(Bundle bundle) 
    { 
     base.OnCreate(bundle); 
     SetContentView(Resource.Layout.FirstView); 

     var childView = new ChildView() 
     { 
      ViewModel = new ChildViewModel() 
     }; 

     var tabView = new TabView() 
     { 
      ViewModel = new TabViewModel() 
     }; 
     var fm = this.SupportFragmentManager; 
     var ft = fm.BeginTransaction(); 
     //ft.Add(childView, "child"); 

     ft.Replace(Resource.Id.childViewHost, childView, "child"); 


     ft.Replace(Resource.Id.tabViewHost, tabView, "tab"); 
     ft.Commit(); 
    } 

} 

我在Setup.cs

protected override IMvxAndroidViewPresenter CreateViewPresenter() 
{ 
    var customPresenter = new CustomPresenter(); 
    Mvx.RegisterSingleton<ICustomPresenter>(customPresenter); 
    return customPresenter; 
} 

所有幫助建立這些是極大的讚賞。

編輯

我決定反對這種做法,並與標準Android TabHost去,以保持應用程序之間的一致性。

回答

2

錯誤說明了一切。你最有可能忘記了一個Activity屬性添加到您的ChildTwoView像:

[Activity] 
public class ChildTwoView : Activity { ... } 

哦,等一下,你ChildTwoView不是Activity,當那麼你就不能使用內置在主持人Show方法。它不支持Fragments

+0

好的,我該如何用ShowViewModelCommand替換當前片段?你是否建議我不能使用該命令? – Jake

+0

當然可以。你只需要讓演示者做出努力。 – Cheesebaron

+0

關於如何讓主持人做到這一點的任何建議? – Jake