我正在尝试实现从抽屉菜单调用的设置视图。
使用从MvxPreferenceFragmentCompat继承的Fragment实现设置视图。代码如下:
[MvxFragmentPresentation(typeof(MainViewModel), Resource.Id.main_content_frame)]
[Register(nameof(SettingsFragment))]
public class SettingsFragment : MvxPreferenceFragmentCompat<SettingsViewModel>
{
public override void OnCreatePreferences(Bundle savedInstanceState, string rootKey)
{
SetPreferencesFromResource(Resource.Xml.preferences, rootKey);
}
}
我的preferences.xml如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="@string/pref_debug_info_title"
android:key="pref_key_debug_info">
<CheckBoxPreference
android:key="pref_key_provide_debug_info"
android:title="@string/pref_title_provide_debug_info"
android:summary="@string/pref_summary_provide_debug_info"
android:defaultValue="false" />
<CheckBoxPreference
android:key="pref_key_provide_debug_info_over_wifi"
android:title="@string/pref_title_debug_info_over_wifi"
android:summary="@string/pref_summary_debug_info_over_wifi"
android:defaultValue="true" />
</PreferenceCategory>
</PreferenceScreen>
片段布局如下:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:id="@+id/fragment_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
layout="@layout/include_toolbar_actionbar_addlistitem" />
<fragment
android:name="SettingsFragment"
android:id="@+id/settings_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<include
layout="@layout/include_floatingactionbutton" />
</android.support.design.widget.CoordinatorLayout>
最后,主要活动XML在这里:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:fitsSystemWindows="true">
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_content_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true" />
<FrameLayout
android:id="@+id/navigation_frame"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_gravity="left|start" />
</android.support.v4.widget.DrawerLayout>
我的偏好显示正常,但我没有看到带有标题的AppBar(我可以设置),并且没有箭头导航回活动。当我按下后面的&#34;硬件按钮&#34;一旦,没有任何反应。当我第二次按它时,应用程序&#34;最小化&#34;当我把它带回来时,我又回到了主要的活动中。
我已经使用&#34;常规&#34;片段继承自MvxFragment但似乎我无法使用MvxPreferenceFragmentCompat这样做。
更新1
根据Trevor的输入,我更新了fragment_settings.xml和SettingsFragment.cs,如下所示:
fragment_settings.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:id="@+id/fragment_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
layout="@layout/include_toolbar_actionbar" />
<!-- Required ViewGroup for PreferenceFragmentCompat -->
<FrameLayout
android:id="@android:id/list_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
local:layout_behavior="@string/appbar_scrolling_view_behavior"/>
<include
layout="@layout/include_floatingactionbutton" />
</android.support.design.widget.CoordinatorLayout>
SettingsFragment.cs
[MvxFragmentPresentation(typeof(MainViewModel), Resource.Id.main_content_frame)]
[Register(nameof(SettingsFragment))]
public class SettingsFragment : MvxPreferenceFragmentCompat<SettingsViewModel>, View.IOnClickListener
{
#region properties
protected Toolbar Toolbar { get; set; }
protected AppCompatActivity ParentActivity { get; set; }
#endregion
#region Fragment lifecycle overrides
public override void OnCreatePreferences(Bundle savedInstanceState, string rootKey)
{
AddPreferencesFromResource(Resource.Xml.preferences);
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var view = base.OnCreateView(inflater, container, savedInstanceState);
ParentActivity = ((MainActivity)Activity);
Toolbar = view.FindViewById<Toolbar>(Resource.Id.main_tool_bar);
ParentActivity.SetSupportActionBar(Toolbar);
ParentActivity.SupportActionBar.SetDisplayHomeAsUpEnabled(true);
ParentActivity.SupportActionBar.SetDisplayShowHomeEnabled(true);
...
// TODO: Pull it from a resource
Toolbar.Title = Resources.GetText(Resource.String.settings_view_title);
return view;
}
#endregion
#region View.IOnClickListener implementation
public void OnClick(View v)
{
ParentActivity.OnBackPressed();
}
#endregion
}
但是我仍然在线获取ParentActivity.SupportActionBar.SetDisplayHomeAsUpEnabled(true),因为我的SupportActionBar为空(但工具栏不是)。怎么样?
更新2
好的,我进一步了。我拿回了AppBar和箭头,外观和感觉就像我预料的那样。还有一个问题,但下面还有更多。
有什么帮助? This post
简而言之,我需要为我的偏好声明一个自定义样式,并在其中引用我的首选项视图的布局。这是一点:
Styles.xml
<style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
...
<item name="preferenceTheme">@style/AppTheme.Preference</item>
</style>
<!-- Custom Preference Theme -->
<style name="AppTheme.Preference"
parent="@style/PreferenceThemeOverlay.v14.Material">
<item name="preferenceFragmentCompatStyle">
@style/AppPreferenceFragmentCompatStyle
</item>
</style>
<!-- Custom Style for PreferenceFragmentCompat -->
<style name="AppPreferenceFragmentCompatStyle"
parent="@style/PreferenceFragment.Material">
<item name="android:layout">@layout/fragment_settings</item>
</style>
对我来说,这是SettingsFragment中的视图声明和布局资源之间缺少的链接。
剩下的唯一问题是能够从此片段返回到主要活动。来自&#34;常规&#34; MvxFragment(从抽屉调用),我使用IOnClickListener的OnClick方法来调用ParentActivity.OnBackPressed()。
SettingsFragment.cs
public class SettingsFragment : MvxPreferenceFragmentCompat<SettingsViewModel>, View.IOnClickListener
{
...
public void OnClick(View v)
{
ParentActivity.OnBackPressed();
}
}
但这不适用于此MvxPreferenceFragmentCompat。仍在寻找答案。
更新3
最后一个难题是该类顶部的AddToBackStack声明,如下所示。一旦到位,OnBackPressed()就能正常工作。
SettingsFragment.cs
[MvxFragmentPresentation(typeof(MainViewModel), Resource.Id.main_content_frame, AddToBackStack = true)]
[Register(nameof(SettingsFragment))]
public class SettingsFragment : MvxPreferenceFragmentCompat<SettingsViewModel>, View.IOnClickListener
答案 0 :(得分:0)
您缺少一些设置AppCompatActivity.SupportActionBar
的代码,就像您在其他任何片段中一样。以下是我解决问题的方法:
以下是SettingsFragment
布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/coordinator"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:fitsSystemWindows="true"
tools:context=".Activities.MainActivity">
<include
layout="@layout/toolbar_actionbar" />
<!-- Required ViewGroup for PreferenceFragmentCompat -->
<FrameLayout
android:id="@android:id/list_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
以下是SettingsFragment
实施:
public class SettingsFragment : MvxPreferenceFragmentCompat<SettingsViewModel>,
View.IOnClickListener
{
private Toolbar _toolbar;
private View _view;
private MainActivity MainActivity => (MainActivity)Activity;
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Since the view is created in PreferenceFragmentCompat's OnCreateView we don't use BindingInflate like a typical MvxFragment.
_view = base.OnCreateView(inflater, container, savedInstanceState);
// TODO: Setup MvvmCross Databinding manually since we didn't use BindingInflate like a typical MvxFragment.
_toolbar = _view.FindViewById<Toolbar>(Resource.Id.toolbar);
if (_toolbar != null)
{
MainActivity.SetSupportActionBar(_toolbar);
MainActivity.SupportActionBar.SetDisplayHomeAsUpEnabled(true);
MainActivity.SupportActionBar.SetDisplayShowHomeEnabled(true);
_toolbar.SetNavigationOnClickListener(this);
// TODO: Bind the Toolbar.Title
}
return _view;
}
public override void OnCreatePreferences(Bundle savedInstanceState, string rootKey)
{
AddPreferencesFromResource(Resource.Xml.preferences);
}
public async void OnClick(View v)
{
// Toolbar was clicked
await ViewModel.CloseCommand.ExecuteAsync().ConfigureAwait(false);
}
}