I have one layout in two orientations - 1 landscape and 1 portrait.
/layout-land/main.xml
has two fragments:
<fragment android:id="@+id/fragment1" .. />
<fragment android:id="@+id/fragment2" .. />
/layout/main.xml
has only one fragment:
<fragment android:id="@+id/fragment1" .. />
Here's the MainActivity.java
:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
firstFragment = (FirstFragment) getFragmentManager().findFragmentById(R.id.fragment1);
secondFragment = (SecondFragment) getFragmentManager().findFragmentById(R.id.fragment2);
}
Next, I start the MainActivity.java
in landscape mode. In this case,
firstFragment
and secondFragment
refers to the fragments in the layout layout-land/main.xml
Then I rotate the screen to portrait mode, and the layout file layout/main.xml
should be loaded. In this case,
firstFragment
refers to the R.id.fragment1
secondFragment
referes to a non-existant fragment. Accessing any elements inside this throws a NullPointerException. (To be more precise, secondFragment
is not null
here)How this secondFragment
is initialized when there's no fragment defined inside the layout?
Edit: Reason found on Android Developer Documentation at http://developer.android.com/training/basics/fragments/creating.html:
When a configuration change causes the activity hosting these fragments to restart, its new instance may use a different layout that doesn't include the same fragments as the previous layout. In this case all of the previous fragments will still be instantiated and running in the new instance. However, any that are no longer associated with a tag in the view hierarchy will not have their content view created and will return false from isInLayout(). (The code here also shows how you can determine if a fragment placed in a container is no longer running in a layout with that container and avoid creating its view hierarchy in that case.)
Fragments — Scenario 3: Activity with retained Fragment is rotated. The fragment is not destroyed nor created after the rotation because the same fragment instance is used after the activity is recreated.
You can add your fragment to the activity's view hierarchy either by defining the fragment in your activity's layout file or by defining a fragment container in your activity's layout file and then programmatically adding the fragment from within your activity.
FragmentManager is the class responsible for performing actions on your app's fragments, such as adding, removing, or replacing them, and adding them to the back stack.
If you add one Fragment into the back stack, when you press the android device back menu, you can find the Fragment that is saved in the back stack popup. Until all the saved Fragments in the back stack popup, then the activity will exit.
You can check like below : I assume that you have Fragment1 class for the fragment you get by findFragmentById
Fragment1 frg1 =getFragmentManager().findFragmentById(R.id.FrgDetalleEvento);
boolean hayDetalle = ( frg1!= null && frg1.isInLayout());
It solved the same problem with me, hope it helpful for every of you
maybe it's too late, but I leave it for future programmers with this problem, I had a similar problem and solved it this way.
Logic: Check the screen orientation, and call
findViewById(R.id.fragment2)
only if the screen is on landscape mode. Otherwise start a new intent to the other screen
Non working code;
@Override
public void onEventoSeleccionado(Evento e) {
boolean hayDetalle = (getFragmentManager().findFragmentById(R.id.FrgDetalleEvento) != null);
if(hayDetalle) {
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy hh:mm",Locale.ENGLISH);
Log.i("EOLog", "Hay Detalle");
((DetalleEventoFragment)getFragmentManager().findFragmentById(R.id.FrgDetalleEvento)).mostrarDetalle(Long.toString(e.getId()),formatter.format(e.getFecha()));
}
else {
Log.i("EOLog", "No hay detalle");
Intent i = new Intent(this,DetalleEventoActivity.class);
Bundle b = new Bundle();
b.putLong("IDEV", e.getId());
b.putLong("FECHA", e.getFecha());
i.putExtras(b);
startActivity(i);
}
}
Working code:
@Override
public void onEventoSeleccionado(Evento e) {
int orientation = getResources().getConfiguration().orientation;
if(orientation == Configuration.ORIENTATION_LANDSCAPE) {
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy hh:mm",Locale.ENGLISH);
Log.i("EOLog", "Hay Detalle");
((DetalleEventoFragment)getFragmentManager().findFragmentById(R.id.FrgDetalleEvento)).mostrarDetalle(Long.toString(e.getId()),formatter.format(e.getFecha()));
}
else if(orientation == Configuration.ORIENTATION_PORTRAIT) {
Log.i("EOLog", "No hay detalle");
Intent i = new Intent(this,DetalleEventoActivity.class);
Bundle b = new Bundle();
b.putLong("IDEV", e.getId());
b.putLong("FECHA", e.getFecha());
i.putExtras(b);
startActivity(i);
}else
{
Log.i("EOLog", "Dispositivo erroneo");
}
}
I hope that is helpful
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With