I am trying to make an app with two fragments, one containing a list of groups (called OverviewFragment) and one fragment containing the details of selected group (called DetailsFragment). I want only one fragment to be visible at a time in portrait mode and both to be visible simultaneously in landscape mode.
I have two problems. First of all the transition between portrait and landscape is very unstable and leads to a variety of crashes, i.e: a blank screen, "No view found", "Error inflating class fragment" and "overlapping rendering".
My other more concrete problem is that when in landscape mode, the textview containing the group name is duplicated and added at the top of the layout. To me this is very strange since the other textview (containing the group info) does NOT get duplicated. Very puzzling!
Running the app in portrait mode alone works fine and I experience no crashes or duplicated textviews.
MainActivity.java
package com.example.o2k.lab2naviedition;
import android.net.Uri;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements OverviewFragment.OnOverviewInteractionListener, DetailsFragment.OnDetailsInteractionListener{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null) { // if we are being restored we dont need to do stuff
System.out.println("saved");
return;
}
System.out.println("tag is: "+findViewById(R.id.activity_main).getTag());
if (findViewById(R.id.activity_main).getTag().equals("portrait")) {
OverviewFragment overFrag = new OverviewFragment();
System.out.println("PORTRAIT IF ---------------------");
// Add the fragment to the 'fragment_container' FrameLayout
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, overFrag).commit();
} else if (findViewById(R.id.activity_main).getTag().equals("landscape")) {
System.out.println("LANDSCAPE IF ---------------------");
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.overview_fragment, new OverviewFragment());
transaction.replace(R.id.details_fragment, new DetailsFragment());
transaction.commit();
}
}
@Override
public void onOverviewInteraction(int position) {
DetailsFragment detailsFrag = (DetailsFragment)
getSupportFragmentManager().findFragmentById(R.id.details_fragment);
Group group = OverviewFragment.getGroups()[position];
DetailsFragment newFragment = new DetailsFragment();
Bundle args = new Bundle();
args.putString("groupName", group.getName());
args.putString("groupInfo", group.getInfo());
newFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
if (detailsFrag != null) {
transaction.replace(R.id.details_fragment, newFragment);
} else {
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
}
transaction.commit();
}
@Override
public void onDetailsInteraction(Uri uri) {
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:configChanges="keyboardHidden|orientation|screenSize"
android:id="@+id/activity_main"
android:tag="portrait"
tools:context="com.example.o2k.lab2naviedition.MainActivity">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/fragment_container">
</FrameLayout>
</LinearLayout>
activity_main.xml (land)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:configChanges="keyboardHidden|orientation|screenSize"
android:orientation="horizontal"
android:id="@+id/activity_main"
android:tag="landscape">
<fragment android:name="com.example.o2k.lab2naviedition.OverviewFragment"
android:id="@+id/overview_fragment"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment android:name="com.example.o2k.lab2naviedition.DetailsFragment"
android:id="@+id/details_fragment"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
OverviewFragment.java
package com.example.o2k.lab2naviedition;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class OverviewFragment extends ListFragment {
private OnOverviewInteractionListener mListener;
private static Group[] groups = {new Group("group 1", "5"), new Group("group 2", "13"),
new Group("group 3", "12"), new Group("group 4", "32"), new Group("group 5", "45")};
public OverviewFragment() {
}
public static OverviewFragment newInstance(String param1, String param2) {
OverviewFragment fragment = new OverviewFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int layout = android.R.layout.simple_list_item_1;
List<String> groupNames = new ArrayList();
for (Group g: groups
) {
groupNames.add(g.getName());
}
setListAdapter(new ArrayAdapter<String>(getActivity(), layout, groupNames));
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_overview, container, false);
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
mListener.onOverviewInteraction(position);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnOverviewInteractionListener) {
mListener = (OnOverviewInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnOverviewInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnOverviewInteractionListener {
void onOverviewInteraction(int position);
}
public static Group[] getGroups() {
return groups;
}
}
DetailsFragment.java
package com.example.o2k.lab2naviedition;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class DetailsFragment extends Fragment {
private OnDetailsInteractionListener mListener;
private String groupName;
private String groupInfo;
public DetailsFragment() {
}
public static DetailsFragment newInstance() {
DetailsFragment fragment = new DetailsFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_details, container, false);
TextView groupNameTextView = (TextView)v.findViewById(R.id.groupNameText);
TextView groupInfoTextView = (TextView)v.findViewById(R.id.groupInfoText);
if (this.getArguments() != null) {
groupName = this.getArguments().getString("groupName");
groupInfo = this.getArguments().getString("groupInfo");
} else {
groupName = "<emptyNAME>";
groupInfo = "<emptyINFO>";
}
groupInfoTextView.setText("No of members: "+groupInfo);
groupNameTextView.setText(groupName);
return v;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnDetailsInteractionListener) {
mListener = (OnDetailsInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnDetailsInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnDetailsInteractionListener {
void onDetailsInteraction(Uri uri);
}
}
try using FrameLayouts instead of your custom fragments in the xml file:
in your way, you are creating each fragment twice. good luck :)