关于MvvmCross的示例with many first-ever-s on the way from Kickstarter to a DARPA-acquired [PARALLEL]
-hardware know-how.并尝试重构我自己的应用程序以将AppBar和Toolbar资源定义移动到片段。我在片段上调用SetSupportActionbar时遇到问题,而调用过去在Activity上工作正常。这是重构的代码:
activity_main.axml
<?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"
android:id="@+id/main_coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<!-- Actual content of the screen -->
<FrameLayout
android:id="@+id/main_content_frame"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:layout_below="@+id/toolbar"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
MainActivity.cs
using Android.App;
using Android.OS;
using Android.Content.PM;
using MvvmCross.Droid.Support.V7.AppCompat;
using Mobile.Core.ViewModels;
namespace Mobile.Droid.Activities
{
[Activity(
Label = "@string/applicationName",
Icon = "@drawable/ic_icon",
Theme = "@style/AppTheme.Default",
LaunchMode = LaunchMode.SingleTop,
ScreenOrientation = ScreenOrientation.Portrait,
Name = "droid.mobile.activities.MainActivity")]
public class MainActivity : MvxAppCompatActivity<MainViewModel>
{
...
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.activity_main);
ViewModel.ShowLists();
}
....
}
}
fragment_lists.axml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/list_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.design.widget.AppBarLayout
android:id="@+id/main_app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.ActionBar">
<android.support.v7.widget.Toolbar
android:id="@+id/main_tool_bar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.ToolBar"
app:layout_scrollFlags="scroll|enterAlways" />
</android.support.design.widget.AppBarLayout>
<MvvmCross.Droid.Support.V4.MvxSwipeRefreshLayout
android:id="@+id/listsRefresher"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:MvxBind="Refreshing IsLoading; RefreshCommand ReloadCommand">
<MvvmCross.Droid.Support.V7.RecyclerView.MvxRecyclerView
android:id="@+id/listsRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:MvxItemTemplate="@layout/item_list"
app:MvxBind="ItemsSource Lists; ItemClick ShowListItemsCommand" />
</MvvmCross.Droid.Support.V4.MvxSwipeRefreshLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="@dimen/margin_medium"
android:src="@drawable/ic_add_white_24dp"
android:visibility="invisible"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:layout_anchor="@id/main_content_frame"
app:layout_anchorGravity="bottom|right|end" />
</RelativeLayout>
ListsFragment.cs
using Android.OS;
using Android.Views;
using MvvmCross.Droid.Support.V4;
using MvvmCross.Binding.Droid.BindingContext;
using Android.Runtime;
using List.Mobile.Droid.Common;
using MvvmCross.Binding.BindingContext;
using Android.Support.V4.View;
using Android.Widget;
using List.Mobile.Core.ViewModels;
using MvvmCross.Droid.Support.V7.RecyclerView;
using Android.Support.V7.Widget;
using MvvmCross.Droid.Views.Attributes;
namespace List.Mobile.Droid.Views
{
[MvxFragmentPresentation(typeof(MainViewModel), Resource.Id.main_content_frame, true)]
[Register("list.mobile.droid.views.ListsFragment")]
public class ListsFragment : BaseFragment<ListsViewModel>, ActionMode.ICallback
{
...
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
base.OnCreateView(inflater, container, savedInstanceState);
...
}
}
}
BaseFragment.cs
using MvvmCross.Droid.Support.V4;
using List.Mobile.Droid.Common;
using MvvmCross.Core.ViewModels;
using Android.OS;
using Android.Views;
using Android.Support.Design.Widget;
using Android.Support.V7.Widget;
using Android.Support.V7.App;
namespace List.Mobile.Droid.Views
{
public abstract class BaseFragment<T> : MvxFragment<T> where T : MvxViewModel
{
protected AppBarLayout AppBar { get; set; }
protected FloatingActionButton FAB { get; set; }
protected Toolbar Toolbar { get; set; }
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var view = base.OnCreateView(inflater, container, savedInstanceState);
AppBar = Activity.FindViewById<AppBarLayout>(Resource.Id.main_app_bar);
FAB = Activity.FindViewById<FloatingActionButton>(Resource.Id.fab);
Toolbar = Activity.FindViewById<Toolbar>(Resource.Id.main_tool_bar);
AppCompatActivity parentActivity = ((AppCompatActivity)Activity);
parentActivity.SetSupportActionBar(Toolbar);
parentActivity.SupportActionBar.SetDisplayHomeAsUpEnabled(false);
parentActivity.SupportActionBar.SetHomeButtonEnabled(false);
return view;
}
}
}
问题在于行:
parentActivity.SetSupportActionBar(Toolbar);
因为它似乎没有设置操作栏,并且随后对 parentActivity.SupportActionBar 的调用因NullReferenceException而失败。有任何想法吗?请注意,当在活动而不是片段上定义Appbar和工具栏时,这是有效的。
答案 0 :(得分:1)
如果你看不到答案,请休息一下,喝杯咖啡,它会来找你。由于AppBar和工具栏是在片段XML中定义的,因此我无法调用 Activity.FindViewById()来对其进行充气。上述代码同样适用于AppBar和FAB。一旦我重构了上面提到的示例的代码我接下来(子类Fragment提供片段布局的ResourceId和基类膨胀它),我能够改变调用:
AppBar = Activity.FindViewById<AppBarLayout>(Resource.Id.main_app_bar);
Fab = Activity.FindViewById<FloatingActionButton>(Resource.Id.fab);
Toolbar = Activity.FindViewById<Toolbar>(Resource.Id.main_tool_bar);
于:
AppBar = FragmentView.FindViewById<AppBarLayout>(Resource.Id.main_app_bar);
Fab = FragmentView.FindViewById<FloatingActionButton>(Resource.Id.fab);
Toolbar = FragmentView.FindViewById<Toolbar>(Resource.Id.main_tool_bar);
其中:
FragmentView = this.BindingInflate(FragmentResourceId, null);
一切都开始好起来了。