Correct use of setEmtpyView in AdapterView
Solution 1
You need to add this same view in the layout in which you have added the AdapterView.
AdapterView only changes its visibility based on the contents in the adapter.
EDITED :
Following layout and code works fine :
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:layout_width="fill_parent"
android:layout_height="300dip"
android:id="@+id/list_view" />
<TextView
android:id="@+id/empty_list_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="List view is empty"
android:visibility="gone" />
</LinearLayout>
Code :
ListView listView = (ListView) findViewById( R.id.list_view );
listView.setEmptyView( findViewById( R.id.empty_list_view ) );
listView.setAdapter( new ArrayAdapter( this, R.layout.selected_spinner_view, new ArrayList() ) );
Solution 2
Karan's answer is spot-on. The AdapterView indeed displays the empty view by merely changing its own visibility vs the empty view's visibility. However, the empty view layout does not necessarily need to be in the same XML file as that of the AdapterView. I found it useful to separate the two because I use a single layout XML file (containing a GridView) for multiple activities, but I wanted to specify different emptyView layouts for each of them.
The key is to add the empty view to the activity with addContentView. Remember to do this after you have called setContentView specifying your main AdapterView.
My code (in AbstractBaseActivity.onCreate) :
View mainView = inflater.inflate(R.layout.imagegrid, null);
GridView gridView = (GridView)mainView.findViewById(R.id.gridView);
View emptyView = inflater.inflate(getIdOfEmptyView(), null, false);
gridView.setEmptyView(emptyView);
// Any additional processing on mainView
setContentView(mainView);
addContentView(emptyView, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
In each child activity I override getIdOfEmptyView as follows:
@Override
protected int getIdOfEmptyView()
{
return R.layout.emptyView_Favorites;
}
Solution 3
You can define external XML layout files, inflate and set it as an empty view. Only thing to remember is to set the parent of the inflated view.
View emptyView = inflater.inflate(R.layout.id_of_your_layoout_file, parent, false);
gridView.setEmptyView(emptyView);
or
listView.setEmptyView(emptyView);
RoflcoptrException
Updated on January 16, 2020Comments
-
RoflcoptrException over 4 years
I'm really having trouble using the setEmptyView method. I tried it to implement it in GridView and ListView, but both of them didnt work. Here a sample codeblock:
networkGames = (GridView) baseLayer.findViewById(R.id.all_game_grid_network); networkGames.setBackgroundResource(R.drawable.game_border); networkGames.setSelector(R.drawable.game_active_border); networkGames.setOnItemClickListener(new NetworkGameListener()); networkGames.setEmptyView(View.inflate(baseLayer, R.drawable.no_network_games, null)); networkGames.setAdapter(new NetworkAdapter());
The network adapter contains no items:
private class NetworkAdapter extends BaseAdapter { /* (non-Javadoc) * @see android.widget.Adapter#getCount() */ @Override public int getCount() { return 0; } /* (non-Javadoc) * @see android.widget.Adapter#getItem(int) */ @Override public Object getItem(int position) { return null; } /* (non-Javadoc) * @see android.widget.Adapter#getItemId(int) */ @Override public long getItemId(int position) { return 0; } /* (non-Javadoc) * @see android.widget.Adapter#getView(int, android.view.View, android.view.ViewGroup) */ @Override public View getView(int position, View convertView, ViewGroup parent) { return null; } }
I also tried to call networkGames.setAdapter(null), but this doesnt work either. My emtpyView looks like this:
<LinearLayout android:id="@+id/LinearLayout01" android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android"> <TextView android:text="There are currently no network games available. Start a new one." android:id="@+id/TextView01" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center"> </TextView> </LinearLayout>
I really don't know what I'm doing wrong. I also read various tutorials, but none of them metnioned any problems.
-
RoflcoptrException about 14 yearsi added the above layout at the end of the layout where i define my gridview. but nevertheless it isn't displayed
-
RoflcoptrException about 14 yearshmm is it possible that i have to define the gridview and the emptyview exclusively (with no other layout items like buttons) in a separate xml file?
-
Karan about 14 yearsI've modified the answer with the example. It works fine on Android 2.1. HTH !
-
devunwired almost 14 yearsThis helped me in a slightly unrelated situation. The fact that AdapterView just changes visibility instead of actually managing which View is presents to its parent layout is the key!
-
QuinnVT over 11 yearswhat if you don't want the whole activity to be overridden with your empty view (like headers or buttons)?
-
PacificSky over 11 yearsOne option might be to wrap both the GridView and whatever empty view you have in a parent layout (like a LinearLayout or RelativeLayout in the activity's view). That will ensure that they occupy at most as much space as the parent. The parent itself could be laid out in the activity view using a RelativeLayout, ensuring that headers, buttons etc are correctly shown independently of the GridView/empty view.
-
Andy over 11 yearsAwesome. That addContentView line was exactly what I was missing in my code. Thanks!
-
raksja over 8 yearsThis doesnt work if you are using
android.support.v4.widget.SwipeRefreshLayout
-
RED_ over 8 years@techastute is there a solution for swiperefreshlayout?
-
TheRealChx101 almost 6 yearsWhat about for a Spinner and what if you're calling that function outside
AdapterView
without aparent
object?LayoutParams
didn't work for me an my Spinner shrinks/disappears when empty.