繁体   English   中英

Android ActionBar.Tab,片段,子片段

[英]Android ActionBar.Tab, Fragments, Sub-fragments

我目前有一个Android应用,该应用在导航区域中有几个选项卡(准确地说是3个)。 单击每个选项卡将显示与该选项卡关联的片段。

我希望能够单击正在显示的片段中的按钮并显示一个新的片段,该片段不属于任何选项卡。 基本上,它就像上一页的子屏幕。

我能够显示“子片段”,然后单击“后退”按钮会将我带到我想要的上一个片段。

我的问题是,当我单击另一个选项卡时,“子片段”没有消失。 如果单击后退按钮,则会收到一个IllegalStateException,表示Fragment1已添加。

这是一些代码,希望可以帮助回答我的问题。

主要活动:

public void OnTabSelected(ActionBar.Tab tab, FragmentTransaction ft)
    {
        string tabTag = tab.Tag.ToString();

        Fragment f = FragmentManager.FindFragmentByTag(tabTag);

        if (f != null)
        {
            ft.Show(f);
        }
        else
        {
            switch (tabTag)
            {
                case "Tab1":
                    f = new Fragment1();
                    break;
                case "Tab2":
                    f = new Fragment2();
                    break;
                case "Tab3":
                    f = new Fragment3();
                    break;
                default:
                    f = new NotImplementedTabFragment();
                    break;
            }

            ft.Add(Resource.Id.fragmentContainer, f, tabTag);
         }
    }

    public void OnTabUnselected(ActionBar.Tab tab, FragmentTransaction ft)
    {
        string tabTag = tab.Tag.ToString();

        Fragment f = FragmentManager.FindFragmentByTag(tabTag);

        if (f != null)
        {
            ft.Hide(f);
        }
    }

片段1:

public class Fragment1 : Fragment
{

    public override Android.Views.View OnCreateView(Android.Views.LayoutInflater inflater, Android.Views.ViewGroup container, Bundle savedInstanceState)
    {
        base.OnCreateView(inflater, container, savedInstanceState);

        var view = inflater.Inflate(Resource.Layout.Fragment1, container, false);
        return view;
    }

    protected void OnButtonClick(object sender, Android.Widget.AdapterView.ItemClickEventArgs e)
    {
        var t = items[e.Position].ToString();
        FragmentTransaction fragmentTransaction = FragmentManager.BeginTransaction();
        fragmentTransaction.Replace(Resource.Id.fragmentContainer, new SubFragment());
        fragmentTransaction.AddToBackStack(null);
        fragmentTransaction.Commit();
    }
}

这是用Xamarin(C#)编写的,但是我确实了解Java代码,因此使用Java的任何帮助/示例都可以。

更新:

我意识到我的MainActivityLayout.axml文件使用的是RelativeLayout而不是FrameLayout,这就是为什么我不得不使用attach / detach而不是show / hide的原因。 这是我的新布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <FrameLayout
        android:id="@+id/fragmentContainer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1" />
</LinearLayout>

它仍然无法按预期工作,但是我再也没有收到异常消息,说明该片段已被添加。

更新2:

我决定放弃尝试使用OnTabSelected和OnTabUnselected的方法,因为我使用的是C#,所以仅使用委托。 重要的代码是这样的:

private void AddTab(Tab tab, Fragment fragment)
{
    Android.App.ActionBar.Tab droidTab = this.ActionBar.NewTab();
    droidTab.SetCustomView(new TabLayout(this));
    droidTab.SetTag(tab.ToString());

    droidTab.TabSelected += delegate(object sender, ActionBar.TabEventArgs e)
    {
        e.FragmentTransaction.Replace(Resource.Id.fragmentContainer, fragment);
    };

    this.ActionBar.AddTab(droidTab);
}

我认为您需要做的是保存对SubFragment的引用

Fragment subFrag;
protected void OnButtonClick(object sender, Android.Widget.AdapterView.ItemClickEventArgs e)
{
    var t = items[e.Position].ToString();
    FragmentTransaction fragmentTransaction = FragmentManager.BeginTransaction();
    subFrag =  new SubFragment();
    fragmentTransaction.Replace(Resource.Id.fragmentContainer, subFrag);
    fragmentTransaction.AddToBackStack(null);
    fragmentTransaction.Commit();
}

然后,当Fragment1被释放时,删除subFrag

@Override public void onDetach() {
    if (subFrag != null) {
         FragmentTransaction fragmentTransaction = FragmentManager.BeginTransaction();
         fragmentTransaction.Remove(subFrag );
         fragmentTransaction.Commit();
    }
    super.onDetach();
}

另一个(虽然我认为有点粗糙)选项可能是在Fragment1中实现getSubFragment()方法并执行:

public void OnTabUnselected(ActionBar.Tab tab, FragmentTransaction ft)
{
    string tabTag = tab.Tag.ToString();

    Fragment f = FragmentManager.FindFragmentByTag(tabTag);

    if (f instanceof Fragment1) {
        Fragment subFrag = ((Fragment1)f).getSubFragment();
        if (subFrag != null) {
            ft.Remove(f); 
        }
    }
    if (f != null)
    {
        ft.Hide(f);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM