gurehbgui
gurehbgui

Reputation: 14684

setEmptyView on ListView not showing its view in a android app?

I have a problem with the setEmptyView method from a ListView.

Here is my Java code:

ListView view = (ListView)findViewById(R.id.listView1);
view.setEmptyView(findViewById(R.layout.empty_list_item));

ArrayAdapter<Session> adapter1 = new ArrayAdapter<Session>(this, android.R.layout.simple_list_item_1, 
        android.R.id.text1, MainController.getInstanz().getItems());
view.setAdapter(adapter1);

empty_list_item:

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

</TextView>

listview:

<ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

What is wrong with my code? When I have items I see them in the list. But when the list is empty I don't see the TextView.

Upvotes: 45

Views: 40827

Answers (12)

Yurii Solopov
Yurii Solopov

Reputation: 1

I have just been learned android, but the snippet from https://developer.android.com/guide/topics/ui/layout/listview.html depicts some different approach:

// Create a progress bar to display while the list loads
ProgressBar progressBar = new ProgressBar(this);
progressBar.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
        LayoutParams.WRAP_CONTENT, Gravity.CENTER));
progressBar.setIndeterminate(true);
getListView().setEmptyView(progressBar);
// Must add the progress bar to the root of the layout
ViewGroup root = (ViewGroup) findViewById(android.R.id.content);
root.addView(progressBar); 

ViewGroup root = (ViewGroup) findViewById(android.R.id.content);

Upvotes: 0

Harvey
Harvey

Reputation: 5821

After trying all of the solutions presented here and experimenting, I believe the code below is the best method to use when your ListView and empty View are not side-by-side in a layout with the automatic ids set.

ViewGroup parentGroup = (ViewGroup)getListView().getParent();
View empty = getActivity().getLayoutInflater().inflate(R.layout.list_empty_view,
                                                       parentGroup,
                                                       false);
parentGroup.addView(empty);
getListView().setEmptyView(empty);

Reasoning:

  • By passing the parent group into inflate, the layout_* attributes of your empty view layout are respected
  • By not attaching the view in inflate (the false parameter), the empty view is returned. Otherwise, inflate would return the parent requiring us to use parentGroup.findViewById(empty_view_id) to get the empty view for use with setEmptyView(). Here we avoid the extra lookup, the need for another id, and the need to expose that id in our code. If we didn't need to preserve the reference to empty, telling inflate to attach would be the correct action removing the need for the addView call.
  • An anti-pattern, addContentView(), is not the correct approach. It will appear equivalent as long as your ListView occupies all of your Activity's visible space. Instead of your empty view being a sibling to your ListView, it ends up being a sibling to your other root-level layouts in your Activity. It appears to work because it's floating (z-order) on top of all other Views in the activity. See: Activity.addContentView(View) == ViewGroup.addContentView(View)?

Upvotes: 13

mmbrian
mmbrian

Reputation: 1662

Your TextView should be placed right under the ListView item with its visibility set to gone (android:visibility="gone"), do not place it in another layout. This is how your main layout would look like

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/listViewFangbuch"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>
    <TextView
        android:id="@+id/empty_list_item"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone"
        android:text="@string/emptyList" >
    </TextView>

</LinearLayout>

And this is how your code might look like

ListView view = (ListView)findViewById(R.id.listViewFangbuch);
view.setEmptyView(findViewById(R.id.empty_list_item));

ArrayAdapter<Session> adapter1 = new ArrayAdapter<Session>(this, android.R.layout.simple_list_item_1, 
        android.R.id.text1, MainController.getInstanz().getItems());
view.setAdapter(adapter1);

Upvotes: 100

Stefan
Stefan

Reputation: 582

My problem was, that I added a footer view which seems not working with the empty view. After removing the footer view the empty view is displayed.

Upvotes: 0

Sazzad Hissain Khan
Sazzad Hissain Khan

Reputation: 40156

Just use,

View emptyView = getLayoutInflater().inflate(R.layout.empty_view, null);
((ViewGroup)listView.getParent()).addView(emptyView);

Instead of listView.setEmptyView(emptyView);

Upvotes: 1

user2162746
user2162746

Reputation: 25

also these two methods helped me with displaying empty view:

    adapter.notifyDataSetChanged();
    list.invalidateViews();

Upvotes: 1

cesards
cesards

Reputation: 16319

There are some correct solutions, but I think this is the best approach!

View emptyView = getLayoutInflater().inflate(R.layout.empty_list_cart, null);
addContentView(emptyView, listView.getLayoutParams()); // You're using the same params as listView
listView.setEmptyView(emptyView);
listView.setAdapter(adapter);

Upvotes: 3

Dave
Dave

Reputation: 155

The core of the problem is that the AdapterView class does not actually add the view you pass to setEmptyView() to any container. It just changes the visibility. There are lots of ways to put your "empty view" object into a container, as the other answers describe.

The documentation for AdapterView should really be updated to reflect this, since it is not obvious.

Upvotes: 6

Sam
Sam

Reputation: 86948

The simplest way to use setEmptyView() is with your "empty" TextView and ListView in the same layout like this:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/empty_list_item"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/emptyList"
        android:visibility="gone" />

</LinearLayout>

Now you can use:

view.setEmptyView(findViewById(R.id.empty_list_item));

Upvotes: 18

Nima
Nima

Reputation: 6563

Create a layout in XML that specifies both the ListView and the empty view you want to use. If you give them IDs of @android:id/list and @android:id/empty, android will automatically use the view with id:empty when list is empty.

Upvotes: 4

danigonlinea
danigonlinea

Reputation: 1113

For me, none of this answers worked for me. What I had to do was add the empty view manually (inflated) to the "parent" view of the Listview:

ListView my_list = (ListView) findViewById(R.id.my_list);
View emptyView = getLayoutInflater().inflate(R.layout.empty_view,null);
((ViewGroup)my_list.getParent()).addView(emptyView); 
listView.setEmptyView(emptyView);

Upvotes: 30

gurehbgui
gurehbgui

Reputation: 14684

the problem is, i have to do a addContentView:

View empty = getLayoutInflater().inflate(R.layout.empty_list_item, null, false);
addContentView(empty, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
view.setEmptyView(empty);

now its fine

Upvotes: 32

Related Questions