I've seen many questions that seemed relevant, but I have failed to found the one that is exactly what I'm looking for.
I have an App, with a ViewPager in MainActivity.
one of the Fragments in the ViewPager is a ListFragment.
I want to enable a creation of new Fragment when the user clicks a List item,
using onListItemClick function.
The new Fragment will replace the ViewPager, and will display its layout and data.
I also want to allows clicking the Back button, which will return the User to the previous state of the PageViewer.
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
StationDescriptionFragment newFragment = new StationDescriptionFragment();
Bundle args = new Bundle();
args.putString(StationDescriptionFragment.ARG_DESCRIPTION, this.stationsList.get(position).getDescription());
newFragment.setArguments(args);
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
transaction.commit();
getListView().setItemChecked(position, true);
}
This code is inside the Fragment which is part of the ViewPager.
This code ends and than the app crashes right after this function ends. I know for sure that this function ends.
The crash is:
FragmentManagerImpl.throwException(RuntimeException) line: 462
The StationDescriptionFragment class:
public class StationDescriptionFragment extends Fragment {
final static String ARG_DESCRIPTION = "description";
String mCurrentDescription = "";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (savedInstanceState != null) {
mCurrentDescription = savedInstanceState.getString(ARG_DESCRIPTION);
}
return inflater.inflate(R.layout.description_view, container, false);
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
updateDescription("Some Description");
}
public void updateDescription(String description) {
TextView desc = (TextView) getActivity().findViewById(R.id.description);
desc.setText(description);
mCurrentDescription = description;
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(ARG_DESCRIPTION, mCurrentDescription);
}
}
description_view.xml
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/description"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:textSize="18sp" />
Any help will be much appreciated.
Thanks.
The new Fragment will replace the ViewPager, and will display its
layout and data. I also want to allows clicking the Back button, which
will return the User to the previous state of the PageViewer.
If you want to replace the ViewPager(which I assume is in another fragment) along with its page fragments then use the normal FragmentManager and not the one returned by getChildFragmentManager() which is targeted at implementing nested fragments. getChildFragmentManager() will look for that id(to put the new fragment) in the current fragment's view and I assume R.id.fragment_container is the id of the container that holds the fragment with the ViewPager:
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
getListView().setItemChecked(position, true); // call this before the transaction
StationDescriptionFragment newFragment = new StationDescriptionFragment();
Bundle args = new Bundle();
args.putString(StationDescriptionFragment.ARG_DESCRIPTION, this.stationsList.get(position).getDescription());
newFragment.setArguments(args);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
Related
I'm using some fragments programmatically in activity. There is one button in my first fragment and when i click to this button, it replaces to second fragment.My second fragment's background is 90% transparent, and when it starts, i can see button which is situated in first fragment, and it also works. I want to stop or do something, because i dont want to see first fragment features and use it.
First Fragment
public class RegistrationFirstFragment extends Fragment {
RegistrationSecondFragment rf;
ImageButton btnNewUser,btnNewAgent;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//return super.onCreateView(inflater, container, savedInstanceState);
View v =inflater.inflate(R.layout.fragment_registration_first,container,false);
rf = new RegistrationSecondFragment();
btnNewUser = (ImageButton)v.findViewById(R.id.btnNewUserRegistrationFirstFragment);
btnNewAgent = (ImageButton)v.findViewById(R.id.btnNewAgentRegistrationFirstFragment);
btnNewUser.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(), "Transaction completed succesfully", Toast.LENGTH_LONG).show();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.flRegistrationFirst, rf);
ft.commit();
}
});
return v;
}
}
Second Fragment
public class RegistrationSecondFragment extends Fragment {
RegistrationFirstFragment rtl;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rtl = new RegistrationFirstFragment();
//return super.onCreateView(inflater, container, savedInstanceState);
View v =inflater.inflate(R.layout.fragment_registration_second,container,false);
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
// ft.replace(R.id.flRegistrationFirst, rf);
ft.remove(rtl);
ft.commit();
return v;
}
}
Main Activity
public class RegistrationActivity extends AppCompatActivity{
RegistrationFirstFragment fr;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_registration);
fr = new RegistrationFirstFragment();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.flRegistrationFragment,fr);
ft.commit();
}
}
You can put
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
(the parameter fragment would be an instance of your second fragment)
into your onClick(View view){...} method to change the fragment instead of adding it.
Next time code for understanding your problem btw ;)
Add to fragment layout android:clickable="true". Int his way fragment will catch event so the click will not be caught by "main fragment".
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true" />
Give android:clickable="true" for Second Fragment root layout parent, when ever fragment opens It catches the click event of root and ignored previous click events.
Second One: If u use replace Fragment it's better than add fragment.
getActivity().getSupportFragmentManager().beginTransaction().replace
(R.id.YOUR_CONTAINER, 'FragmentObject').addToBackStack("TAG").commitAllowingStateLoss();
I am facing a problem in regarding fragment.
In my scenario,
There are two fragment associated with FragmentActivity.
In FragmentActivity, there are a container layout (Frame Layout) in which all fragment will replace.
public void replaceFragment(Fragment fragmentClass) {
String selectedFragment = fragmentClass.getClass().getName();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction
.replace(R.id.content_frame, fragmentClass);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
First time , I set a List type fragment (Fragment A) in which get the data from web service and papulate over listview. I execute the AsyncTask from onCreateView() method.
In MainActivity: onCreate
SherlockFragment fragment = new FragmentA();
replaceFragment(fragment);
On list item click of Fragment A, Fragment A will callback the activity method to replace it to details type fragment Fragment B.
#Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
callback = (ICallBack) activity;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
/*View rootView = inflater.inflate(R.layout.fragment_locate, container,
false);*/
View rootView = inflater.inflate(R.layout.fragment_a, container,
false);
ListView list = (ListView) rootView
.findViewById(R.id.listView);
adapter = new MyListAdapter();
list.setAdapter(adapter);
list
.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent,
View convertView, int position, long id) {
SherlockFragment fragment = new SalonDetailFragment();
callback.replaceFragment(fragment);
}
});
ListDataTask task = new ListDataTask();
task.execute();
return rootView;
}
class ListDataTask extends AsynTask<Void,Void,List<Data>>{
public Void doInBackground(Void parems){
List<Data> = getDataFromServer();
}
onPostExecute(List<Data> data){
adapter.addAllData(data);
adapter.notifyDataSetChanged();
}
}
When I press back button, from Fragment B then Application will show Fragment A but it execute Asynctask again and get the data to papulate the listview.
So I need to know, How to maintain the pervious state of Fragment like Activity.
Is there are any way to not to create Fragment after come back from Other activity
Have a look my pseudo code.
I got solution. Simple.... do the check null value of rootview
public class FragmentA extends Fragment {
View _rootView;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (_rootView == null) {
// Inflate the layout for this fragment
_rootView = inflater.inflate(R.layout.fragment_a, container, false);
// Find and setup subviews
_listView = (ListView)_rootView.findViewById(R.id.listView);
...
} else {
// Do not inflate the layout again.
// The returned View of onCreateView will be added into the fragment.
// However it is not allowed to be added twice even if the parent is same.
// So we must remove _rootView from the existing parent view group
// (it will be added back).
((ViewGroup)_rootView.getParent()).removeView(_rootView);
}
return _rootView
I have the same problem and solved by replacing
fragmentTransaction
.replace(R.id.content_frame, fragmentClass);
to
fragmentTransaction
.add(R.id.content_frame, fragmentClass);
Replace will always create new instance on back press while Add is just add a new fragment in Stack. for more information check this link
My Fragment
public class CustomFrag extends Fragment {
private Button btn;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.button_fragment, container, false);
btn = (Button)view.findViewById(R.id.button1);
return view;
}
public void sendItem(String item) {
btn.setText(item);
}
}
And in my activity
public void loadFragment(String data) {
// Load up new fragment
Fragment fragment = new CustomFrag();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.add(R.id.contentFragment, fragment, "custFrag");
transaction.addToBackStack("custFrag");
transaction.commit();
// Required before calling fragment methods
getSupportFragmentManager().executePendingTransactions();
// Load fragment with data
CustomFrag frag = (CustomFrag) getSupportFragmentManager().findFragmentByTag("custFrag");
frag.sendItem(data);
}
I'm getting a nullpointer exception any time I attempt to use the views of my fragment. If I try to load the view inside the method as well, it will not work
i.e. inside sendItem()
btn = (Button)getView().findViewById(R.id.button1);
My layout (button_fragment) contains the button:
<Button
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Because you have executed the transaction does not mean that the fragment has actually created its view. Which is why btn is still null.
To pass data from the activity to the fragment, use the argument bundle:
Fragment fragment = new CustomFrag();
Bundle args = new Bundle();
args.putString("item", data);
fragment.setArguments(args);
Then, in onCreateView:
btn = (Button)view.findViewById(R.id.button1);
btn.setText(getArguments().getString("item"));
See this Best practice for instantiating a new Android Fragment question and the first answer.
The problem here is that the fragment's layout is not drawn yet when sendItem(...) is called. Which means btn is null at that point. Instead, this is how you're supposed to do it (see http://developer.android.com/guide/components/fragments.html):
public class CustomFrag extends Fragment {
private Button btn;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.button_fragment, container, false);
btn = (Button)view.findViewById(R.id.button1);
btn.setText(getArguments.getString("item"));
return view;
}
}
And
public void loadFragment(String data) {
// Load up new fragment
Fragment fragment = new CustomFrag();
Bundle args = new Bundle();
args.putString("item", data);
fragment.setArguments(args);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.add(R.id.contentFragment, fragment, "custFrag");
transaction.addToBackStack("custFrag");
transaction.commit();
// Required before calling fragment methods
getSupportFragmentManager().executePendingTransactions();
}
Edit:
njzk2 was faster, but I hope the details I gave will help you further. In any case, the link he gave explains nicely why you should do it like that.
I have a fragment (let's call it MyFragment) that inflates different layouts according to a parameter passed in the arguments.
All works well if MyFragment is started from a different fragment. But if MyFragment is active and I want to launch a new MyFragment with a different layout parameter, the fragmentManager does not create a new fragment at all.
data.setInt("Layout index",i);
fragmentTab0 = (Fragment) new MyFragment();
fragmentTab0.setArguments(data);
fragmentTransaction.replace(R.id.fragmentContent, fragmentTab0, "MY");
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
How can I force convince the fragmentTransaction to launch the fragment again?
NOTE: The important point here is I need to inflate again a layout, which is different from the layout inflated before. The code looks like:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
switch( getArguments().getInt("Layout index") ) {
case 1:
rootView = inflater.inflate(R.layout.firstlayout, container, false);
break;
case 2:
rootView = inflater.inflate(R.layout.secondlayout, container, false);
break;
case 3:
rootView = inflater.inflate(R.layout.thirdlayout, container, false);
break;
default: break;
}
Bypass Solution
Explanation (hoover to see it)
Since the source code for fragmentTransaction.replace/add/remove is
not available I could not find what really happens. But it is
reasonable to think that at some point it compares the current class
name with the replacement class name and it exits if they are the
same.. Thanks to #devconsole for pointing out the source
code. I know now why this happens. The FragmentManager.removeFragment()
method does not reset the fragment state, it remains RESUMED, then the
method moveToState(CREATED) only initilizes a fragment if (f.mState <
newState) = if (RESUMED < CREATED) = false. Else, ergo, it just resumes the fragment.
So to solve this problem I created an almost empty fragment which only purpose is to replace itself with the target fragment.
public class JumpFragment {
public JumpFragment() {
}
#Override
public void onStart() {
Bundle data = getArguments();
int containerId = data.getString("containerID");
String tag = data.getString("tag");
//Class<?> c = data.get???("class");
//Fragment f = (Fragment) c.newInstance();
Fragment f = (Fragment) new MyFragment();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
f.setArguments(data);
fragmentTransaction.replace(containerId, f, tag);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
}
And I use it:
data.setInt("Layout index",i);
data.setInt("containerID",R.id.fragmentContent);
data.setString("tag","MY");
fragmentTab0 = (Fragment) new JumpFragment();
fragmentTab0.setArguments(data);
fragmentTransaction.replace(R.id.fragmentContent, fragmentTab0);
fragmentTransaction.commit();
Now no fragment is replaced by a same class fragment:
MyFragment -> JumpFragment -> MyFragment
I haven't figured out how to pass the class through the arguments bundle, to make it totally generic.
The following worked without problems for me. Notice that I used the Android Support Library.
activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<Button
android:id="#+id/button_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ONE" />
<Button
android:id="#+id/button_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/button_one"
android:text="TWO" />
<FrameLayout
android:id="#+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/button_one" >
</FrameLayout>
</RelativeLayout>
MainActivity.java:
public class MainActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
Fragment fragment = DetailsFragment.newInstance("INITIAL");
transaction.add(R.id.main_container, fragment);
transaction.commit();
}
findViewById(R.id.button_one).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
update("Button 1 clicked");
}
});
findViewById(R.id.button_two).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
update("Button 2 clicked");
}
});
}
protected void update(String value) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
Fragment fragment = DetailsFragment.newInstance(value);
transaction.replace(R.id.main_container, fragment);
transaction.commit();
}
public static final class DetailsFragment extends Fragment {
public static DetailsFragment newInstance(String param) {
DetailsFragment fragment = new DetailsFragment();
Bundle args = new Bundle();
args.putString("param", param);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
TextView textView = new TextView(container.getContext());
textView.setText(getArguments().getString("param"));
return textView;
}
}
}
Did you try to first remove your fragment with remove(fragMgr.findFragmentByTag("MY"))and then add the new one ?
PS : I assume you don't keep any reference to this fragment.
If I understand you correctly: the fragment you want to replace what is currently being displayed and the user does something to cause it to re-display itself?
If this is correct then have done something similar this way:
public class MyFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View V = inflater.inflate(R.layout.myLayout, container, false);
// Call method that fills the layout with data
displayData(V);
// Put a listener here that checks for user input
Button redisplayButton = (Button) V.findViewById(R.id.my_button);
// if the button is clicked....
redisplayButton.setOnClickListener(new OnClickListener() {
public void onClick(View v){
//
// do some stuff
//
// ....then eventually...
displayData(V);
}
});
return V;
}
Later on you can have the displayData() method that defines what the fragment displays....
public void displayData(View V){
// Do something
return;
}
Hope this helps!
I am working on an android project and I am trying to work out how I can use fragments to make a tablet friendly UI for my app. But I am unsure how to update fragment B depending on what happens in fragment A. I know I need some sort of interface but I can't work out how to implement it.
Basically, what I have is an activity called MainActivity which sets the layout for the fragments.
In landscape mode the XML file is.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment android:name="com.BoardiesITSolutions.FragmentTest.FragmentA"
android:id="#+id/list"
android:layout_weight="1"
android:layout_width="0px"
android:layout_height="match_parent">
</fragment>
<FrameLayout android:id="#+id/viewer"
android:layout_weight="1"
android:layout_width="0px"
android:layout_height="match_parent"
android:background="?android:attr/detailsElementBackground">
</FrameLayout>
</LinearLayout>
In portrait mode its
Currently the MainActivity just sets the content view to the XML file above using SetContentView within in the onCreate method. Below is how it looks.
In the FragmentA class file it extends ListFragment and contains a ListView of items and what I want to be able to do is to update the textview within Fragment B based on what is selected in Fragment A.
Below is the code for fragment A.
#Override
public View onCreateView(LayoutInflater inflator, ViewGroup container, Bundle savedInstanceState)
{
return inflator.inflate(R.layout.fragment_a, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
myListView = getListView();
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("Item1");
arrayList.add("Item2");
arrayList.add("Item3");
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(getActivity().getApplicationContext(),
android.R.layout.simple_list_item_activated_1, arrayList);
setListAdapter(arrayAdapter);
View fragmentB = getActivity().findViewById(R.id.viewer);
mDualPane = fragmentB != null && fragmentB.getVisibility() == View.VISIBLE;
if (savedInstanceState != null)
{
mCurCheckPosition = savedInstanceState.getInt("curChoice", 0);
}
if (mDualPane)
{
myListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
showDetails(mCurCheckPosition);
}
}
#Override
public void onListItemClick(ListView l, View view, int position, long id)
{
showDetails(position);
}
private void showDetails(int index)
{
mCurCheckPosition = index;
if (mDualPane)
{
myListView.setItemChecked(index, true);
FragmentB details = (FragmentB)getFragmentManager().findFragmentById(R.id.viewer);
if (details == null || details.getShownIndex() != index)
{
details = FragmentB.newInstance(index);
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.viewer, details);
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
fragmentTransaction.commit();
}
}
else
{
Intent intent = new Intent(getActivity(), FragmentBActivity.class);
intent.putExtra("index", index);
startActivity(intent);
}
}
#Override
public void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
outState.putInt("curChoice", mCurCheckPosition);
}
FragmentB contains the following code, this class extends Fragment
public View onCreateView(LayoutInflater inflator, ViewGroup container, Bundle savedInstanceState)
{
if (container == null)
{
return null;
}
View view = inflator.inflate(R.layout.fragment_b, container, false);
return view;
}
public static FragmentB newInstance(int index)
{
FragmentB fragmentB = new FragmentB();
Bundle args = new Bundle();
args.putInt("index", index);
//rgs.putString("content", content);
fragmentB.setArguments(args);
return fragmentB;
}
public int getShownIndex()
{
return getArguments().getInt("index", 0);
}
And in the Activity file for FragmentB it contains the following
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
{
finish();
return;
}
if (savedInstanceState == null)
{
FragmentB fragmentB = new FragmentB();
fragmentB.setArguments(getIntent().getExtras());
getFragmentManager().beginTransaction().add(android.R.id.content, fragmentB).commit();
}
}
As you can see from the screenshot above, I have the basis of the fragments working and when I click on each item, it shows what the currently selected item is, but I have no idea how to tell it to update the textview in fragment b based on what the user clicked from fragment a and how this is handled in both portrait and landscape mode.
Thanks for any help you can provide.
You may override the onActivityCreated() method of FragmentB, find view by id of that TextView, and update it.
Here's a mock:
public class FragmentB extends Fragment{
//......
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
TextView textView = getActivity().findViewById(R.id.my_textview);
textView.setText("Hello World!");
}
}
but I have no idea how to tell it to update the textview in fragment b based on what the user clicked from fragment a and how this is handled in both portrait and landscape mode.
Have Fragment A call a method on the hosting activity to let it know that the user clicked on something. The hosting activity can then either call a method on Fragment B (if that fragment exists), or start up Fragment B (if the fragment does not exist but there is room for it), or start an activity that will be responsible for displaying Fragment B (e.g., on a phone).
What I wouldn't do is what you are doing: having Fragment A create Fragment B. Fragment A should not care if Fragment B exists or not; that is the activity's job. Fragment A should only worry about Fragment A, plus passing necessary events to the activity.