如果我在XML布局中声明一个片段,我该如何将它传递给Bundle?

时间:2012-10-23 16:07:03

标签: java android xml fragment

我有一个我用片段替换过的活动。该活动采用了一个Intent,它有一些关于活动应该显示的数据的额外信息。

现在我的Activity只是一个执行相同工作的Fragment的包装器,如果我用XML标记带有标记的XML片段,如何将该包绑定到Fragment?

如果我使用FragmentTransaction将Fragment放入ViewGroup,我将有机会在Fragment构造函数中传递此信息,但我想知道片段是用XML定义的情况。

5 个答案:

答案 0 :(得分:43)

  

现在我的Activity只是一个执行相同工作的Fragment的包装器,如果我用XML标记带有标记的XML片段,如何将该包绑定到Fragment?

你不能。

但是,欢迎您在findFragmentById()上致电FragmentManager以检索通胀后的片段,然后在片段上调用一些方法将数据与其关联。虽然显然不能setArguments(),但您的片段可以通过其他方式(onSaveInstanceState()setRetainInstance(true)等)安排通过配置更改来保留数据本身。

答案 1 :(得分:39)

这不是一种封装的方式,但我结束了#34;拉动"来自父活动的捆绑包:

Bundle bundle = getActivity().getIntent().getExtras();

答案 2 :(得分:4)

您不能传递Bundle,但可以通过XML将参数(或属性)传递给片段。

该过程类似于how you define View custom attributes。 除了AndroidStudio(当前)之外,该过程无法为您提供帮助。

假设这是使用参数的片段(我将使用kotlin,但它也完全适用于Java):

class MyFragment: Fragment() {

    // your fragment parameter, a string
    private var screenName: String? = null

    override fun onAttach(context: Context?) {
        super.onAttach(context)
        if (currentScreen == null) {
            currentScreen = arguments?.getString("screen_name")
        }
    }
}

您想做这样的事情:

<fragment
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/myFragment"
    android:name="com.example.MyFragment"
    app:screen_name="@string/screen_a"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

请注意app:screen_name="@string/screen_a"

要使其正常工作,只需将其添加到值文件中(fragment_attrs.xml或一个tua scelta):

<!-- define your attribute name and type -->
<attr name="screen_name" format="string|reference"/>

<!-- define a bunch of constants you wanna use -->
<string name="screen_a" translatable="false">ScreenA</string>
<string name="screen_b" translatable="false">ScreeenB</string>

<!-- now define which arguments your fragment is gonna have (can be more then one) -->
<!-- the convention is "FragmentClassName_MembersInjector" -->
<declare-styleable name="MyFragment_MembersInjector">
    <attr name="screen_name"/>
</declare-styleable>

几乎完成了,您只需要在片段中读取它,因此添加方法:

override fun onInflate(context: Context?, attrs: AttributeSet?, savedInstanceState: Bundle?) {
    super.onInflate(context, attrs, savedInstanceState)
    if (context != null && attrs != null && screenName == null) {
        val ta = context.obtainStyledAttributes(attrs, R.styleable.MyFragment_MembersInjector)
        if (ta.hasValue(R.styleable.MyFragment_MembersInjector_screen_name)) {
            screenName = ta.getString(R.styleable.MyFragment_MembersInjector_screen_name)
        }
        ta.recycle()
    }
}

等等,您片段中的XML属性:)

限制:

  • Android Studio(到目前为止)不会在布局XML中自动完成此类参数
  • 您不能传递Parcelable,而只能传递可以定义为Android属性的内容

答案 3 :(得分:3)

我看到的唯一解决方案是不将参数用作数据交换通道。相反,让你的片段从其他地方获取必要的信息。回调以获取正确的活动,查阅临时存储器,Singleton对象等。

另一个可能有用的解决方案是使用允许不相关对象通过Mediator设计模式交换消息的框架,如Otto

答案 4 :(得分:0)

我知道答案太迟了,但是我认为有人需要它:)

仅在活动中覆盖<right click>

onAttachFragment()

以及onCreateView方法的片段

@Override
public void onAttachFragment(Fragment fragment)
{
    super.onAttachFragment(fragment);

    if (fragment.getId() == R.id.frgBlank)
    {
        Bundle b = new Bundle();
        b.putString("msg", "Message");

        fragment.setArguments(b);
    }
}