Search code examples
androidandroid-fragmentsandroid-xmlandroid-nested-fragment

Vertical layouts with dynamically generated nested fragments in Android


So after much ridiculous jumping through of hoops and general contortionism I convinced Android to do an elementary and often required task. That is to generate zero to any number of views with any number of different layouts and associated variables and insert them into another view so that they stack vertically.

Well almost.

Android begrudgingly agreed to include all the views after I read and modified the code from this question.

public void setPeriods(ArrayList <HashMap> periods) {
    for(HashMap<String, Object> period: periods){
        FragmentManager childFragMan = getChildFragmentManager();

        FragmentTransaction childFragTrans = childFragMan.beginTransaction();
        ForecastPeriod forecastPeriod = new ForecastPeriod();
        childFragTrans.add(R.id.forecast_period, forecastPeriod);
        childFragTrans.commit();
        forecastPeriod.setTitle((String)period.get("name"));
    }
}

The problem is that the views will not stack, or at least Android, as if to taunt me "stacked" them but on the Z plane so they overlap one another completely. How can this be?

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:paddingTop="20dp"
    android:paddingLeft="20dp"
    android:paddingRight="20dp"
    android:paddingBottom="0dp"
    tools:context="com.blah.deblah.ForecastPeriods">

    <fragment
        android:id="@+id/forecast_period"
        android:name="com.blah.deblah.ForecastPeriod"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        tools:layout="@layout/fragment_forecast_period" />

</LinearLayout>

How can I change (hopefully) the XML to make these guys stack vertically as they should?

Below is the XML for the fragment being inserted.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context="com.blah.deblah.ForecastPeriod">

        <TextView
            android:id="@+id/period_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="top|center"
            android:fontFamily="sans-serif-bold"
            android:gravity="start"
            android:singleLine="true"
            android:text="@string/title"
            android:textColor="#cccccc"
            android:textSize="24dp" />

        <TextView
            android:id="@+id/period_headline"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="top|center"
            android:layout_below="@id/period_title"
            android:layout_marginTop="20dp"
            android:fontFamily="sans-serif-light"
            android:maxHeight="90dp"
            android:gravity="left"
            android:text="@string/loremipsum"
            android:textColor="#cccccc"
            android:textSize="24dp" />

        <TextView
            android:id="@+id/period_body"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="top|center"
            android:layout_below="@id/period_headline"
            android:layout_marginTop="20dp"
            android:fontFamily="sans-serif-light"
            android:gravity="left"
            android:text="@string/loremipsum"
            android:textColor="#cccccc"
            android:textSize="18dp" />

 </RelativeLayout>

Solution

  • The reason you are having so much trouble is because your understanding of Fragments is fundamentally incorrect. Refer to this question, which I posed when I had trouble understanding them as well and greatly cleared this all up. Android simply doesn't want you to use Fragments like you are trying to, so of course it's not going to do what you expect it to.

    In general, a Fragment shouldn't necessarily be a single UI component, but rather function more like an Activity that acts much more like any other UI component, thus making it much more useful. What you are trying to use a Fragment as, should really be done using a custom View or a ListView.

    As an aside, you are also declaring your Fragment in your code incorrectly. You should either use the package name as the XML tag, or else a FrameLayout and insert your Fragment in the specified FrameLayout, not <fragment>