7

In unserer App versuchen wir, Fragmente dynamisch zu einem GridLayout hinzuzufügen. Das leere Grid-Layout wird in XML definiert, ebenso wie das Layout für das Fragment. Zur Laufzeit untersuchen wir einige Daten und bestimmen daraus die Anzahl der Fragmente, die dem Layout hinzugefügt werden sollen, sowie das Layout, das für jedes Fragment verwendet werden soll. Wenn das Fragment der generierten Ansicht eine Größe zugewiesen hat, funktioniert alles. Wenn wir jedoch die Größe in der Layoutdatei für das Fragment angeben, wird im Rasterlayout nichts angezeigt. Natürlich könnten wir einfach die Größe beim Erstellen der Ansicht angeben, aber wir würden es lieber in den XML-Layouts für die Fragmente machen, da wir dann das integrierte Android-System zur Auswahl der richtigen Layouts für jedes Gerät nutzen könnten.Das dynamische Hinzufügen von Fragmenten mit XML-Layout zu GridLayout funktioniert nicht

Ich verwende Support-Bibliothek Fragmente. Ich bin nicht mit Support-Bibliothek Grid ob das einen Unterschied

Der entsprechende Code und xml macht folgt:

Die Grid XML:

<?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> 

Ein Beispiel für das Fragment XML

<?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> 

Das Fragment onCr eateView() Methode

@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; 
} 

hinzufügen Fragmente in das 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's 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; 
} 

denke ich, dass es abdecken soll. Um es kurz zu wiederholen: Wenn ich die Zeilen, die explizit die Dimension in onCreateView() festlegen, auskommentiere, werden sie in GridLayout korrekt angezeigt, sodass ich alles weiß, was die Fragmente und solche Arbeiten verfolgt, ebenso wie die Fragmenttransaktion. Das Problem tritt auf, wenn ich versuche, die Größe in der XML-Datei des Fragments anzugeben. In diesem Fall erhalte ich einen leeren Bildschirm.

Ihre Gedanken, Vorschläge und Überlegungen werden geschätzt. Danke, Jared

Antwort

6

Dies kommt sehr spät, aber in der Off-Chance kann dies immer noch von Nutzen sein. Das Problem besteht darin, dass Sie die XML-Layoutparameter überschreiben, wenn Sie die neuen LayoutParams dynamisch festlegen. IE, wenn Sie das tun:

view.setLayoutParams(childParams); 

Dies wird die XMLs ursprüngliche Höhe und Breite Einstellung löschen. Nur weil Sie die childParams width/height im Code leer lassen, bedeutet das nicht, dass ein Wert nicht gesetzt ist. In einem GridLayout-Fall sind sie auf undefined festgelegt.

Die Lösung wäre, zunächst die Höhe/Breite des LayoutParam zu speichern und diese beim dynamischen Erstellen des neuen LayoutParam zu verwenden. Beispiel:

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; 
} 

Damit können Sie die Breite/Höhe in XML beibehalten, während Sie die Zeilen-/Spaltenspezifikationen im Code anwenden.

+1

Dies ist in der Tat, was wir getan haben. Ich werde dir die ausgewählte Antwort geben, da du dir die Zeit genommen hast, es aufzuschreiben und klar. – Jared

Verwandte Themen