Dynamically adding snippets with xml layout in GridLayout not working

In our application, we are trying to dynamically add fragments to the GridLayout. An empty grid layout is defined in XML as a layout for a fragment. At run time, we examine some data and from them determine the number of fragments that need to be added to the layout, as well as which layout to use for each fragment. When we have a fragment that assigns a size to its generated view, all this works, however, if we specify the size in the layout file for the fragment, nothing is displayed in the grid layout. Obviously, we could just specify the size when creating the view, but we would prefer to do this in the xml layouts for the fragments, as this would allow us to use the built-in Android system to select the correct layouts for each device.

I use fragments of the support library. I DO NOT use the GridLayout support library if that matters

The appropriate code and xml should be:

GridLayout XML file:

<?xml version="1.0" encoding="utf-8"?> <merge xmlns:android="http://schemas.android.com/apk/res/android"> <ScrollView android:id="@+id/grid_scroll" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/bottom_fragment" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginRight="8dp" android:layout_marginTop="?android:attr/actionBarSize" android:overScrollMode="ifContentScrolls" > <GridLayout android:id="@+id/grid" android:layout_width="match_parent" android:layout_height="wrap_content" android:alignmentMode="alignMargins" android:animateLayoutChanges="true" android:columnCount="3" android:columnOrderPreserved="true" android:orientation="horizontal" android:overScrollMode="ifContentScrolls" android:rowOrderPreserved="true" > </GridLayout> </ScrollView> </merge> 

XML snippet example

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="200dp" android:layout_height="100dp" android:alpha="1" > <Button android:id="@+id/button1" android:layout_width="match_parent" android:layout_height="match_parent" android:alpha="1.0" /> </RelativeLayout> 

OnCreateView () fragment method

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); View view; GridLayout.Spec rowSpec = GridLayout.spec(mRowStart, mRowSpan); GridLayout.Spec columnSpec; GridLayout.LayoutParams childParams; if (large) {; view = inflater.inflate(R.layout.my_place_large, container, false); columnSpec = GridLayout.spec(mColumnStart, 2); childParams = new GridLayout.LayoutParams(rowSpec, columnSpec); //childParams.width = 200; //If I do this everything works regardless of the layout size } else { view = inflater.inflate(R.layout.my_place_small, container, false); columnSpec = GridLayout.spec(mColumnStart, 1); childParams = new GridLayout.LayoutParams(rowSpec, columnSpec); //childParams.width = 100; //If I do this everything works regardless of the layout size } childParams.setMargins(0, 0, 0, 0); //childParams.height = 100; //If I do this everything works regardless of the layout size view.setLayoutParams(childParams); view.setId(ID); return view; } 

Adding fragments to the layout

 private void populateGrid() { RelativeLayout gridParent = (RelativeLayout) mParentActivity.findViewById(R.id.locations); mLocationsGrid = (GridLayout) gridParent.findViewById(R.id.grid); nColumns = mLocationsGrid.getColumnCount(); mAdapter = new MyAdapter(mContext, this, mResolver); //This is how I keep track of the various fragments depending on my app state int nCards = mAdapter.getNumberOfCards(); FragmentManager fragmentManager = mParentActivity.getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); for (int i = 0; i < nCards; ++i) { fragmentTransaction.add(mLocationsGrid.getId(), mAdapter.getFragmentAtIndex(i), String.valueOf(i)); } fragmentTransaction.commit(); mPopulated = true; } 

I think that should have covered him. To repeat, if I uncomment rows that explicitly specify a dimension in onCreateView (), they display correctly in GridLayout, so I know everything that tracks fragments and such works, as well as fragment transaction. The problem occurs when I try to specify the size in the xml fragment, in which case I get a blank screen.

You value thoughts, suggestions and thoughts. Thanks, Jared

+7
source share
1 answer

This happens very late, but on time it can still be useful. The problem is that you are overriding XML layout options when you dynamically set new LayoutParams. IE when you do this:

  view.setLayoutParams(childParams); 

This will erase the original height and width of the XMLs. Just because you leave the width / height of childParams in the code does not mean that the value is not set. In the case of GridLayout, they are set to undefined .

The fix will be to first preserve the view of the existing width and width of the LayoutParam and use this when dynamically creating a new LayoutParam. Example:

 if (large) {; view = inflater.inflate(R.layout.my_place_large, container, false); ViewGroup.LayoutParams oldParams = view.getLayoutParams(); columnSpec = GridLayout.spec(mColumnStart, 2); childParams = new GridLayout.LayoutParams(rowSpec, columnSpec); childParams.width = oldParams.width; } 

This will allow you to keep the width / height in XML when applying the row / col specifications in the code.

+6
source

All Articles