当调用“FragmentManager.PopBackStack()”时,是否可以将数据返回到前一个片段?

时间:2016-08-17 13:48:10

标签: c# android-fragments xamarin xamarin.android

我正在开发一个包含Xamarin.Android的应用,其中我有 root 活动,其中包含用于显示不同片段的frame root 活动仅包含导航项。整个内容以不同的片段显示 其中一个片段显示用户列表。我想为此列表提供过滤器。所以我创建了一个包含所有过滤器选项的新片段和一个应该应用前一个“User-List-Fragment”上所有过滤器的按钮。
我通过向我的“User-List-Fragment”添加frame来显示“过滤器”片段,并将“过滤器”片段加载到其中:

FragmentManager.BeginTransaction()
   .AddToBackStack(null)
   .Replace(Resource.Id.members_filterFrame, new FilterFragment())
   .Commit();

要应用我调用的过滤器

FragmentManager.PopBackStack();

在“应用过滤器按钮”的“单击事件监听器”中,再次显示“用户列表片段”。但是这里突然结束了,因为我不知道是否或如何将过滤器数据填充回我的“User-List-Fragment”。

这是“User-List-Fragment”的.axml版面的一部分。 <FrameLayout />覆盖了<ListView />,只有在用户按下“过滤器按钮”时才会显示。

    .
    .
    .
<ListView
    android:id="@+id/members_listView"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:paddingBottom="150dp" />

<FrameLayout
   android:id="@+id/members_filterFrame"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:visibility="gone" />
    .
    .
    .

问题
调用FilterFragment时是否可以将数据从FragmentManager.PopBackStack();填充回“用户列表片段”? 如果是这样,怎么样?

2 个答案:

答案 0 :(得分:1)

您应该可以将Action传递给FilterFragment

调用OnDestroyView()后,您可以调用Action并发回数据。

示例

First Fragment

FragmentManager.BeginTransaction()
.AddToBackStack(null)
.Replace(Resource.Id.members_filterFrame, new FilterFragment((parameter) => {
    // Do something with the given parameter
}))
.Commit();

FilterFragment

private Action<T> _onCompletionAction;
public FilterFragment(Action<T> onCompletionAction) 
{
    _onCompletionAction = onCompletionAction;
}

public override void OnDestroyView()
{
    base.OnResume();

    _onCompletionAction(parameter) // parameter could be a filter object.
}

答案 1 :(得分:1)

我在按下EventArgs中的“应用过滤器按钮”后,通过触发自定义FilterFragment的事件解决了这个问题:

Searched?.Invoke(this, new FilterAppliedEventArgs(FilterObject)); // fire search event
FragmentManager.PopBackStack();

FilterAppliedEventArgs类看起来像:

public class FilterAppliedEventArgs : EventArgs
{
    public Filter FilterObject { get; set; }

    public FilterAppliedEventArgs(Filter filter)
    {
        this.FilterObject = filter;
    }
}

在显示FilterFragment之前,在“User-List-Fragment”中注册该事件:

var filterFragment = new FilterFragment();
// get the filter attributes
filterFragment.Searched += (s, ea) =>
{
   var eventArgs = ea as FilterAppliedEventArgs;
   LoadFilteredMembers(eventArgs.FilterObject);
};

FragmentManager.BeginTransaction()
   .AddToBackStack(null)
   .Replace(Resource.Id.members_filterFrame, filterFragment)
   .Commit();

来自@Pilatus的方法似乎也非常方便。两者都有效,我不知道哪一个更好。