Android - adding MapFragment inside RecyclerViewAdapter fails if view is not displayed

Update

my usecase is solved by putting it MapFragment

in the xml directly, rather than adding it later - but I'm keeping the question open because I'm still not clear on why its programming fails.

Original question

I have a list CardView

that is data inside RecyclerViewAdapter

.

In one of my maps, I add SupportMapFragment

a FrameLayout with an id of map_container in the layout that has been inflated for the map.

map_card.xml

<merge
    android:id="@+id/map_card"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    card_view:cardCornerRadius="3dp"
    card_view:cardElevation="2sp"
    card_view:cardUseCompatPadding="true">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/white"
        android:orientation="vertical">
        <!-- Root layout for the card content that is created dynamically -->
        <LinearLayout
            android:id="@+id/card_content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <FrameLayout
                android:id="@+id/map_container"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
        </LinearLayout>
    </LinearLayout>
</merge>

      

this is how my adapter works

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    FrameLayout frame = new FrameLayout(parent.getContext());
    frame.setLayoutParams(new RecyclerView.LayoutParams(LayoutParams.MATCH_PARENT,
            LayoutParams.WRAP_CONTENT));
    return new ViewHolder(frame);
}

@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
    ViewGroup container = (ViewGroup) viewHolder.itemView;
    container.removeAllViews();

    CardView cardView = cards.get(position);
    ViewGroup parent = (ViewGroup) cardView.getParent();
    if (parent != null) {
        parent.removeView(cardView);
    }
    container.addView(cardView);
    ((CustomCard)cardView).onCardBind(fragment);
}

      

I am getting MapFragment using

GoogleMapOptions options = new GoogleMapOptions();
SupportMapFragment mapFragment = SupportMapFragment.newInstance(options);

      

and then I need to add a MapFragment to the map ...

If the map is visible on the screen from the very beginning - i.e. this is the 1st or 2nd item in the list - execution

FragmentManager fragmentManager = fragment.getChildFragmentManager();
fragmentManager.beginTransaction().add(R.id.map_container, mapFragment).commitAllowingStateLoss();

      

works!!

but if the map becomes the 3rd element and is therefore initially invisible, the same code fails because the fragment manager cannot find the map_container

ava.lang.IllegalArgumentException: No view found for id 0x7f0d018d (com.myapp.android:id/map_container) for fragment MapFragment{2b012f2b #0 id=0x7f0d018d}
       at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:886)
       at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
       at android.app.BackStackRecord.run(BackStackRecord.java:833)
       at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1454)
       at android.app.FragmentManagerImpl$1.run(FragmentManager.java:447)

      

I tried to move the code into a OnLayout

map method by calling it in the adapter onBindViewHolder

- before adding the view after adding the view - and I always get the same exception - How can I make it work?

+3


source to share


1 answer


you should destroy the view before closing it



fm = fragment.getChildFragmentManager();
mMapFragment = (SupportMapFragment) fm.findFragmentById(map.getId());
fm.beginTransaction().remove(mMapFragment).commitAllowingStateLoss();
container.removeView(map);

      

+1


source







All Articles