When you open my app, I start off by having a viewpager with various tabs at the top that you can click on that displays different fragments per tab.
Inside the fragment called "TEST" is a recyclerview with each item in the recyclerview being child fragments.
There are a few buttons that rest on top of each fragment in the recyclerview so that if you click on the map button, the fragment can change to another fragment that displays a map etc.
In my recyclerview adapter, I inflate the following xml (example.xml) which would represent each line of the recyclerview:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
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:id="@+id/groupholder"
android:background="#FFF">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/fragment_container">
</RelativeLayout>
</RelativeLayout>
The fragment_container is to hold an inflated fragment.
The below is the relevant parts from the RecyclerView.Adapter class that is used to populate the recyclerview:
//the view holder class
class ExampleViewHolder extends RecyclerView.ViewHolder {
RelativeLayout fragmentContainer;
public ExampleViewHolder(View view) {
super(view);
//we are creating a framecontainer for the fragment
fragmentContainer = (RelativeLayout) view.findViewById(R.id.fragment_container);
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//inflating the layout that contains the fragment for the ExampleViewHolder
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.example, parent, false);
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
if (holder instanceOf ExampleViewHolder) {
//The "f" below is the fragment that gets past into this Recycler.Adapter through the adapter's constructor.
f.getChildFragmentManager().beginTransaction().add(((ExampleViewHolder) holder).fragmentContainer.getId(), new PlaceImageFragment()).commit();
//this must execute immediately.
//This is the part that crashes the app
f.getChildFragmentManager().executePendingTransactions();
}
}
Since the commit command is scheduled to be executed asynchronously on the process's main thread (http://developer.android.com/reference/android/app/FragmentManager.html#executePendingTransactions()), I have to call the executePendingTransactions() to get the fragmentmanager to execute the command immediately.
If I do not call the executePendingTransactions(), the app works but the fragments are not populated immediately and I can also see that on screen as the fragments are populated really slowly or not at all in some cases.
However, if I do call executePendingTransactions(), the app crashes with the error saying that the line executePendingTransactions()
was the reason why the app crash:
java.lang.IllegalArgumentException: No view found for id 0x7f0f0096 (com.example.simon:id/fragment_container) for fragment PlaceImageFragment{52e819f8 #0 id=0x7f0f0096}
Any ideas how I can get this to work?
EDIT:
I think that the reason why this is giving me a no view found is that the getChildFragmentManager is looking within the parent fragments layout xml for the id/fragment_container but it will not be in there as the parent fragment only contains the recyclerview in the xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:id="@+id/main_recyclerview_holder">
<!--The padding here creates the space at the top of the ad-->
<android.support.v7.widget.RecyclerView
android:id="@+id/main_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>