6

How to create a ListFragment (of the support v4 library) layout from xml? ListFragment sets up its layout programmatically, so if you want to modify it, you need to mess with add/remove view.

Community
  • 1
  • 1
sherpya
  • 4,890
  • 2
  • 34
  • 50

2 Answers2

14

I've converted the created layout to xml, you can add/remove your widgets or e.g. add pulltorefresh solutions. You shouldn't change the needed ids. Because of internal ids needed for some of the widgets an helper function needs to be called and it needs to be in support v4 namespace since constants are internal with default visibility.

list_loader.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:id="@+id/progress_container_id"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical"
        android:visibility="gone" >

        <ProgressBar
            style="?android:attr/progressBarStyleLarge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>

    <FrameLayout
        android:id="@+id/list_container_id"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <TextView
            android:id="@+id/empty_id"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center" />

        <ListView
            android:id="@android:id/list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:drawSelectorOnTop="false" >
        </ListView>
    </FrameLayout>
</FrameLayout>

and the class ListFragmentLayout in android.support.v4.app (in your project, you don't need to modify support v4 jar)

package android.support.v4.app;

import your.package.R;
import android.view.View;

public class ListFragmentLayout
{
    public static void setupIds(View view)
    {
        view.findViewById(R.id.empty_id).setId(ListFragment.INTERNAL_EMPTY_ID);
        view.findViewById(R.id.progress_container_id).setId(ListFragment.INTERNAL_PROGRESS_CONTAINER_ID);
        view.findViewById(R.id.list_container_id).setId(ListFragment.INTERNAL_LIST_CONTAINER_ID);
    }
}

in your fragment that extends ListFragment

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    View view = inflater.inflate(R.layout.list_loader, container, false);
    ListFragmentLayout.setupIds(view);
    return view;
}
seb
  • 4,279
  • 2
  • 25
  • 36
sherpya
  • 4,890
  • 2
  • 34
  • 50
  • you mean with this changes it will work as if it's not a custom view? – seb Sep 06 '12 at 23:51
  • Doesn't work for me. Looks like i'm using older revision of the support lib. It doesn't even contain ListFragmentLayout class. I don't suggest using this approach. In future revisions of support lib it might not work. – WindRider Jan 31 '13 at 21:32
  • @sherpya, I followed your answer and got `The field ListFragment.INTERNAL_EMPTY_ID is not visible` error – Maksim Dmitriev Apr 26 '13 at 13:23
  • you have to put the code in the package android.support.v4.app because the field has default visibility – sherpya Apr 26 '13 at 19:06
  • perhaps you can still pick the values from the *corresponding* source, in r12 they are: static final int INTERNAL_EMPTY_ID = 0x00ff0001; static final int INTERNAL_PROGRESS_CONTAINER_ID = 0x00ff0002; static final int INTERNAL_LIST_CONTAINER_ID = 0x00ff0003; – sherpya Apr 26 '13 at 19:19
  • Hi @sherpya, thanks for the soultion :) But I'm not able to use a button in my layout as onClickListener doesn't work. Do you know any workaround for that? – Nick Jul 15 '14 at 20:29
  • did you tried `view.findViewById(R.id.mybutton).setOnClieckListener()` before `return view`? – sherpya Jul 16 '14 at 03:10
-2

From the android sdk (ListFragment) (http://developer.android.com/reference/android/app/ListFragment.html):

public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)

Provide default implementation to return a simple list view. Subclasses can override to replace with their own layout. If doing so, the returned view hierarchy must have a ListView whose id is android.R.id.list and can optionally have a sibling view id android.R.id.empty that is to be shown when the list is empty.

If you are overriding this method with your own custom content, consider including the standard layout list_content in your layout file, so that you continue to retain all of the standard behavior of ListFragment. In particular, this is currently the only way to have the built-in indeterminant progress state be shown.

So when you want your own layout.xml for a FragmentList overide onCreateView and inflate your own layout.

For example:

Create a android layout (yourlistlayout.xml) and put the following xml on the position where you want to show your ListFragment.

    <ListView
    android:id="@android:id/list"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true" >
    </ListView>

in your ListFragment class put the following code:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.yourlistlayout, null);       
    return v;       
}
Bas
  • 881
  • 1
  • 10
  • 23