我有一个由一个活动组成的应用程序。所有其他屏幕都使用片段实现。根据导航抽屉中选择的项目,将加载相应的片段。其中一个视图(片段)有另一种做事方式。扫描QR码或手动填写表格。我不知道它是否违反了设计最佳做法,因为此视图应包含制表符,但其他视图则不包含。
http://cd8ba0b44a15c10065fd-24461f391e20b7336331d5789078af53.r23.cf1.rackcdn.com/xamarin.vanillaforums.com/FileUpload/d6/40b7173a09619d47c144ebf444feeb.png http://cd8ba0b44a15c10065fd-24461f391e20b7336331d5789078af53.r23.cf1.rackcdn.com/xamarin.vanillaforums.com/FileUpload/d3/f50fe292739faa65f70fef82a46a34.png
我也使用AppBarLayout
,因为此控件实现了开箱即用的材质设计(高程)。如果我在TabLayout
中实施PairingFragment
,那么在视觉上标签会被放置在工具栏的阴影下。所以我已将TabLayout
移至MainActivity
。
MainLayout.axml
<?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/MainDrawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/MainToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize" />
<android.support.design.widget.TabLayout
android:id="@+id/MainTabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
<RelativeLayout
android:id="@+id/MainContentRelativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="@+id/MainDrawerNavigationView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="@menu/main_drawerlayout_menu" />
</android.support.v4.widget.DrawerLayout>
注意:这是一个Xamarin项目。我不认为Java开发人员很难读取C#代码。
MainActivity.cs
using Support4 = Android.Support.V4;
using Support7 = Android.Support.V7;
[Activity(MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Support7.App.AppCompatActivity, NavigationView.IOnNavigationItemSelectedListener
{
private TabLayout mainTabLayout;
private RelativeLayout mainRelativeLayout;
private NavigationView mainDrawerNavigationView;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
this.SetContentView(Resource.Layout.MainLayout);
this.mainTabLayout = this.FindViewById<TabLayout>(Resource.Id.MainTabLayout);
this.mainRelativeLayout = this.FindViewById<RelativeLayout>(Resource.Id.MainContentRelativeLayout);
this.mainDrawerNavigationView = this.FindViewById<NavigationView>(Resource.Id.MainDrawerNavigationView);
this.mainDrawerNavigationView.SetNavigationItemSelectedListener(this);
if (savedInstanceState == null)
{
this.ShowFragment(new DefaultFragment(this.mainTabLayout));
}
else
{
// Configuration change. The last fragment was recreated by the runtime
// using the fragment's default constructor.
}
}
public bool OnNavigationItemSelected(IMenuItem menuItem)
{
if (menuItem.ItemId == Resource.Id.DefaultDrawerMenuItem)
{
this.ShowFragment(new DefaultFragment(this.mainTabLayout));
}
else if (menuItem.ItemId == Resource.Id.PairingDrawerMenuItem)
{
this.ShowFragment(new PairingFragment(this.mainTabLayout));
}
this.mainDrawerLayout.CloseDrawer(Support4.View.GravityCompat.Start);
return true;
}
private void ShowFragment(Support4.App.Fragment fragment)
{
Support4.App.FragmentManager fm = this.SupportFragmentManager;
fm.BeginTransaction().Replace(this.mainRelativeLayout.Id, fragment).Commit();
}
}
PairingFragment.cs
public class PairingFragment : Support4.App.Fragment
{
private TabLayout tabLayout;
public PairingFragment()
{
// This constructor is needed by the runtime because of
// calling base.OnCreate(savedInstanceState) within
// MainActivity.OnCreate(Bundle savedInstanceState) calls
// this constructor.
}
public PairingFragment(TabLayout tabLayout)
{
this.tabLayout = tabLayout;
}
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
this.tabLayout.Visibility = ViewStates.Visible;
View view = inflater.Inflate(Resource.Layout.PairingFragment, container, false);
Support4.View.ViewPager pairingViewPager = view.FindViewById<Support4.View.ViewPager>(Resource.Id.PairingViewPager);
pairingViewPager.Adapter = new PairingPagerAdapter(this.ChildFragmentManager);
this.tabLayout.SetupWithViewPager(pairingViewPager);
return view;
}
}
public class PairingPagerAdapter : Support4.App.FragmentStatePagerAdapter
{
public PairingPagerAdapter(Support4.App.FragmentManager fragmentManager)
: base(fragmentManager)
{
}
// Removed code for readability
}
正如您所见,TabLayout
通过构造函数注入到片段中。没有标签的片段会将注入的TabLayout
的可见性设置为ViewStates.Gone
。
只要没有配置更改,这就足够了。如果有,那么活动将被重新创建。在这种情况下,片段不会通过构造函数注入,代码会因NullReferenceException
而中断。
我该怎么办?我应该改变应用程序的设计吗?我不认为这是一个设计缺陷。如果有配置更改,我应该获取实际片段,然后注入TabLayout
via方法或属性?这将在今天工作,因为总有一个片段。但是当我明天需要多个片段时会发生什么?检查每个片段&#34;是否可以处理TabLayout
&#34;似乎不对。
关心Yavuz