我正在开发一个与MvvmCross一起运行的Xamarin项目。我试图在Android中添加偏好视图,但我无法让它工作。
当我尝试导航到MvxPreferenceFragment
时,我收到以下错误:
[0:] mvx:Diagnostic: 12.11 Activity host with ViewModelType PreferenceTest.Droid.Activities.MainPreferenceActivity is not CurrentTopActivity. Showing Activity before showing Fragment for PreferenceTest.Core.ViewModels.Fragments.PreferenceViewModel
An unhandled exception occured.
09-26 13:54:45.753 I/MonoDroid(12779): UNHANDLED EXCEPTION:
09-26 13:54:45.810 I/MonoDroid(12779): System.Collections.Generic.KeyNotFoundException: Could not find view for PreferenceTest.Droid.Activities.MainPreferenceActivity
09-26 13:54:45.810 I/MonoDroid(12779): at MvvmCross.Core.Views.MvxViewsContainer.GetViewType (System.Type viewModelType) [0x0006a] in C:\projects\mvvmcross\MvvmCross\Core\Core\Views\MvxViewsContainer.cs:72
09-26 13:54:45.810 I/MonoDroid(12779): at MvvmCross.Droid.Support.V7.AppCompat.MvxAppCompatViewPresenter.ShowHostActivity (MvvmCross.Droid.Views.Attributes.MvxFragmentPresentationAttribute attribute) [0x00000] in C:\projects\mvvmcross\MvvmCross-AndroidSupport\MvvmCross.Droid.Support.V7.AppCompat\MvxAppCompatViewPresenter.cs:166
09-26 13:54:45.810 I/MonoDroid(12779): at MvvmCross.Droid.Support.V7.AppCompat.MvxAppCompatViewPresenter.ShowFragment (System.Type view, MvvmCross.Droid.Views.Attributes.MvxFragmentPresentationAttribute attribute, MvvmCross.Core.ViewModels.MvxViewModelRequest request) [0x0007d] in C:\projects\mvvmcross\MvvmCross-AndroidSupport\MvvmCross.Droid.Support.V7.AppCompat\MvxAppCompatViewPresenter.cs:196
09-26 13:54:45.810 I/MonoDroid(12779): at MvvmCross.Droid.Views.MvxAndroidViewPresenter.<RegisterAttributeTypes>b__39_2 (System.Type view, MvvmCross.Core.Views.MvxBasePresentationAttribute attribute, MvvmCross.Core.ViewModels.MvxViewModelRequest request) [0x00000] in C:\projects\mvvmcross\MvvmCross\Droid\Droid\Views\MvxAndroidViewPresenter.cs:188
09-26 13:54:45.810 I/MonoDroid(12779): at MvvmCross.Droid.Views.MvxAndroidViewPresenter.Show (MvvmCross.Core.ViewModels.MvxViewModelRequest request) [0x00055] in C:\projects\mvvmcross\MvvmCross\Droid\Droid\Views\MvxAndroidViewPresenter.cs:295
09-26 13:54:45.810 I/MonoDroid(12779): at MvvmCross.Droid.Views.MvxAndroidViewDispatcher+<>c__DisplayClass2_0.<ShowViewModel>b__0 () [0x00000] in C:\projects\mvvmcross\MvvmCross\Droid\Droid\Views\MvxAndroidViewDispatcher.cs:26
09-26 13:54:45.810 I/MonoDroid(12779): at MvvmCross.Droid.Views.MvxAndroidMainThreadDispatcher.RequestMainThreadAction (System.Action action, System.Boolean maskExceptions) [0x00020] in C:\projects\mvvmcross\MvvmCross\Droid\Droid\Views\MvxAndroidMainThreadDispatcher.cs:20
09-26 13:54:45.811 I/MonoDroid(12779): at MvvmCross.Droid.Views.MvxAndroidViewDispatcher.ShowViewModel (MvvmCross.Core.ViewModels.MvxViewModelRequest request) [0x00014] in C:\projects\mvvmcross\MvvmCross\Droid\Droid\Views\MvxAndroidViewDispatcher.cs:26
09-26 13:54:45.811 I/MonoDroid(12779): at MvvmCross.Core.Navigation.MvxNavigationService+<Navigate>d__32.MoveNext () [0x0003a] in C:\projects\mvvmcross\MvvmCross\Core\Core\Navigation\MvxNavigationService.cs:179
09-26 13:54:45.811 I/MonoDroid(12779): --- End of stack trace from previous location where exception was thrown ---
09-26 13:54:45.811 I/MonoDroid(12779): at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <896ad1d315ca4ba7b117efb8dacaedcf>:0
09-26 13:54:45.811 I/MonoDroid(12779): at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <896ad1d315ca4ba7b117efb8dacaedcf>:0
09-26 13:54:45.811 I/MonoDroid(12779): at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <896ad1d315ca4ba7b117efb8dacaedcf>:0
09-26 13:54:45.811 I/MonoDroid(12779): at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <896ad1d315ca4ba7b117efb8dacaedcf>:0
09-26 13:54:45.811 I/MonoDroid(12779): at System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult () [0x00000] in <896ad1d315ca4ba7b117efb8dacaedcf>:0
09-26 13:54:45.811 I/MonoDroid(12779): at MvvmCross.Core.Navigation.MvxNavigationService+<Navigate>d__40.MoveNext () [0x00078] in C:\projects\mvvmcross\MvvmCross\Core\Core\Navigation\MvxNavigationService.cs:293
09-26 13:54:45.811 I/MonoDroid(12779): --- End of stack trace from previous location where exception was thrown ---
09-26 13:54:45.811 I/MonoDroid(12779): at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <896ad1d315ca4ba7b117efb8dacaedcf>:0
09-26 13:54:45.811 I/MonoDroid(12779): at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <896ad1d315ca4ba7b117efb8dacaedcf>:0
09-26 13:54:45.811 I/MonoDroid(12779): at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <896ad1d315ca4ba7b117efb8dacaedcf>:0
09-26 13:54:45.811 I/MonoDroid(12779): at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <896ad1d315ca4ba7b117efb8dacaedcf>:0
09-26 13:54:45.811 I/MonoDroid(12779): at System.Runtime.CompilerServices.TaskAwaiter.GetResult () [0x00000] in <896ad1d315ca4ba7b117efb8dacaedcf>:0
09-26 13:54:45.811 I/MonoDroid(12779): at PreferenceTest.Core.ViewModels.FirstViewModel+<ExecutePreferences>d__8.MoveNext () [0x00026] in C:\git\PreferenceTest\PreferenceTest\PreferenceTest\PreferenceTest.Core\ViewModels\FirstViewModel.cs:28
09-26 13:54:45.811 I/MonoDroid(12779): --- End of stack trace from previous location where exception was thrown ---
09-26 13:54:45.811 I/MonoDroid(12779): at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <896ad1d315ca4ba7b117efb8dacaedcf>:0
09-26 13:54:45.811 I/MonoDroid(12779): at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) [0x00000] in <896ad1d315ca4ba7b117efb8dacaedcf>:0
09-26 13:54:45.811 I/MonoDroid(12779): at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0 () [0x00000] in <2e14bb2dd93a405e81838369ed72695b>:0
09-26 13:54:45.811 I/MonoDroid(12779): at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in <2e14bb2dd93a405e81838369ed72695b>:0
09-26 13:54:45.811 I/MonoDroid(12779): at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in <2e14bb2dd93a405e81838369ed72695b>:0
09-26 13:54:45.811 I/MonoDroid(12779): at (wrapper dynamic-method) System.Object:a278159c-f25c-4da4-ac29-d4bae0d2de73 (intptr,intptr)
这是我试图运行的代码(有关完整代码,请参阅下面的github链接): 首先,我在xml文件夹(名为preference.xml)
中创建了一个视图<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<EditTextPreference android:title="Your Name"
android:key="username"
android:summary="Please provide your username"></EditTextPreference>
<CheckBoxPreference android:title="Application Updates"
android:defaultValue="false"
android:summary="This option if selected will allow the application to check for latest versions."
android:key="applicationUpdates" />
<ListPreference android:title="Download Details"
android:summary="Select the kind of data that you would like to download"
android:key="downloadType"
android:defaultValue="1"
android:entries="@array/listArray"
android:entryValues="@array/listValues" />
<CheckBoxPreference
android:key="prefer wifi"
android:title="Prefer WiFi" />
</PreferenceScreen>
片段代码:
[MvxFragmentPresentation(typeof(MainPreferenceActivity), Resource.Id.content_frame, true)]
[Register(nameof(PreferenceFragment))]
public class PreferenceFragment : MvxPreferenceFragment<PreferenceViewModel>
{
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
base.OnCreateView(inflater, container, savedInstanceState);
var view = this.BindingInflate(Resource.Xml.preferences, container, false);
return view;
}
}
使用导航服务进行呼叫:
private async void ExecutePreferences()
{
await _navigationService.Navigate<PreferenceViewModel>();
}
我找不到此代码的错误:)。
以下是样本的a github link。
答案 0 :(得分:5)
第一个问题是使用MvxFragmentPresentation
第一个参数是用于主机活动的ViewModel
的类型,而不是活动本身的类型。在您的情况下,MainPreferenceViewModel
。
下一个问题是,当您使用MvxAppCompatViewPresenter
演示者时,您需要使用MvxPreferenceFragmentCompat
。 MvxPreferenceFragmentCompat
可以在MvvmCross.Droid.Support.V7.Preference
NuGet包中找到。
[MvxFragmentPresentation(typeof(MainPreferenceViewModel), Resource.Id.content_frame)]
[Register(nameof(PreferenceFragment))]
public class PreferenceFragment : MvxPreferenceFragmentCompat<PreferenceViewModel>
{
public override void OnCreatePreferences(Bundle savedInstanceState, string rootKey)
{
SetPreferencesFromResource(Resource.Xml.preferences, rootKey);
}
}
最后,您需要为活动中的偏好设置主题
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
我已经使用Xamarin.Android.Support.v14.Preference
中的材料设计主题,但你也可以使用其中一个:
@style/PreferenceThemeOverlay
@style/PreferenceThemeOverlay.v14
有关更改的完整详情,请参阅pull request。