我有一个我用片段替换过的活动。该活动采用了一个Intent,它有一些关于活动应该显示的数据的额外信息。
现在我的Activity只是一个执行相同工作的Fragment的包装器,如果我用XML标记带有标记的XML片段,如何将该包绑定到Fragment?
如果我使用FragmentTransaction将Fragment放入ViewGroup,我将有机会在Fragment构造函数中传递此信息,但我想知道片段是用XML定义的情况。
答案 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属性:)
限制:
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);
}
}