android - Mvvmcross:无法创建首选项 Activity

标签 android mvvmcross

我正在开发一个与 MvvmCross 一起运行的 Xamarin 项目。我正在尝试在 Android 中添加一个首选项 View ,但我无法让它工作。

当我尝试导航到 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 文件夹中创建了一个 View (名为 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>

还有 fragment 代码:

[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到样本。

最佳答案

第一个问题是 MvxFragmentPresentation 的使用,第一个参数是用于宿主 Activity 的 ViewModel 的类型,而不是 Activity 本身的类型.在您的情况下是 MainPreferenceViewModel

下一个问题是,当您使用 MvxAppCompatViewPresenter 演示器时,您将需要使用 MvxPreferenceFragmentCompatMvxPreferenceFragmentCompat 可以在 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);
    }
}

最后,您需要为 Activity 中的首选项指定一个主题

<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>

我使用了 Xamarin.Android.Support.v14.Preference 中的 Material 设计主题,但您也可以使用其他主题之一:

  • @style/PreferenceThemeOverlay
  • @style/PreferenceThemeOverlay.v14

参见 pull request有关更改的完整详细信息。

MvxPreferenceFragmentCompat example

关于android - Mvvmcross:无法创建首选项 Activity ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46428616/

相关文章:

java - 如何防止从 HttpsURLConnection 调用 CONNECT 方法

Android MotionLayout autoTransition 在 beta7 中不起作用

android - 抽屉导航在没有数据网络 android 时不会打开

c# - 使用 MVVMCross 在 WPF 中捕获 OnExit 事件

android - 让 MvxAutoCompleteTextView 工作

java - 如何使 setContentView() 在线程中正常工作?

三星 galaxy 选项卡的 Android 自定义相机视频捕获问题

android-fragments - 在MvvmCross 4.1.4中实现片段的正确方法是什么

button - Xamarin.Forms 按钮在触摸后将被禁用

c# - 如何通过简单的绑定(bind)使用多个 ViewModel