If I declare a fragment in an XML layout, how do I pass it to the Bundle?

I have an action that I replaced with a fragment. This activity took an intention in which there was additional information about what data was to be displayed.

Now that my activity is just a wrapper around a fragment that does the same job, how do I get this package for a fragment if I declare a fragment in XML with a tag?

If I used FragmentTransaction to put a Fragment in a ViewGroup, I would be able to pass this information in the fragment constructor, but I wonder where the fragment is defined in XML.

+60
java android xml fragment
Oct 23
source share
5 answers

Now that my activity is just a wrapper around a fragment that does the same job, how do I get this package for a fragment if I declare a fragment in XML with a tag?

You can not.

However, you can call findFragmentById() on the FragmentManager to get the fragment after inflation, and then call some method on the fragment to bind the data to it. Although, apparently, this cannot be setArguments() , your fragment can organize data storage immediately after changing the configuration in other ways ( onSaveInstanceState() , setRetainInstance(true) , etc.).

+44
Oct 23 '12 at 16:10
source share

This is not an encapsulated path, but I ended up “pulling” the package from parent activity:

 Bundle bundle = getActivity().getIntent().getExtras(); 
+43
Jan 05 '15 at 11:58
source share

Another option is not to declare the fragment in XML. I know that this is not exactly what you want to do. However, you can declare a simple layout in your view as follows:

  <LinearLayout android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" /> 

And then in your Activity class, you programmatically inflate a layout with a fragment. This way you can go through the parameters with arguments.

  FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); MyFragment fragment = MyFragment.newInstance(); Bundle args = new Bundle(); args.putInt(Global.INTENT_INT_ROLE, 1); fragment.setArguments(args); fragmentTransaction.add(R.id.fragment_container, fragment, "MyActivity"); fragmentTransaction.commit(); 

This approach is not as clean and simple as declaring it in XML, but I switched to it, as it gives you much more control over the fragment.

+9
Dec 21 '15 at 3:24
source share

You cannot pass a Bundle, but you CAN pass parameters (or rather attributes) through an XML fragment.

The process is similar to how you define the View custom attributes . Except AndroidStudio (currently) does not help you in this process.

suppose this is your fragment with arguments (I will use kotlin, but it works completely in Java too):

 class MyFragment: Fragment() { // your fragment parameter, a string private var screenName: String? = null override fun onAttach(context: Context?) { super.onAttach(context) if (screenName == null) { screenName = arguments?.getString("screen_name") } } } 

And you want to do something like this:

 <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"/> 

Pay attention to the app:screen_name="@string/screen_a"

for this to work, just add this to the values ​​file ( fragment_attrs.xml or select any name):

 <!-- 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> 

Almost done, you just need to read it in your fragment, so add a method:

 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() } } 

et voilá, your XML attributes in your fragment :)

Limitations:

  • Android Studio (at the moment) does not autocomplete such arguments in the XML layout
  • You cannot pass Parcelable but only what can be defined as Android attributes
+7
Sep 13 '18 at 7:42
source share

The only solution I see is not to use arguments as a data exchange channel. Instead, make your snippet to get the necessary information from another place. Call back to get the right activity, consult temporary storage, Singleton, etc.

Another solution that may be useful is to use frameworks that allow unrelated objects to exchange messages using an intermediary design pattern like Otto .

+3
Jun 17 '14 at 14:10
source share



All Articles