Android Separate Empty VIews for ListVIews - android

I want to make multiple empty views for a list view and set them programmatically.
So I 've got a listview in an ListActivity. The way my client wants the app, I have a header bar in the app, so the layout looks like this
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/providerListLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<include
android:id="#+id/headerBar_ref"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
layout="#layout/header_with_dashboard_button" />
<include
android:id="#+id/loadingView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
layout="#layout/loading_view" />
<RelativeLayout
android:id="#+id/listViewWrapper"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_below="#id/headerBar_ref" >
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/headerBar_ref" >
</ListView>
</RelativeLayout>
So I have the 2 empty views in separate xml files. In the list Activity I try to set the empty view like so:
RelativeLayout rootLayout = (RelativeLayout) findViewById(R.id.listViewWrapper);
RelativeLayout noFavsLayout = (RelativeLayout) this
.getLayoutInflater().inflate(emptyViewLayoutId,
rootLayout);
getListView().setEmptyView(noFavsLayout);
But when I do this, the empty view is there ALL the time. I've also tried to to add the view using addContentView(), but that takes over the whole screen. I've not been able to find a solution on S/O yet

Based on reading http://wiresareobsolete.com/2010/08/adapting-to-empty-views/, the actual mechanism for showing the empty view is that the adapter checks to see if the list is empty, and then sets the visibility of either the ListView or empty view to View.GONE, then sets the other one to View.VISIBLE. For this to work properly, both views have to be in the same parent view. In your example, this would mean something like
<RelativeLayout
android:id="#+id/listViewWrapper"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_below="#id/headerBar_ref" >
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="#android:id/empty"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="This list is empty."
/>
</RelativeLayout>
(Note that I removed "layout_below" from your ListView, it was the only item in the relative layout, so it didn't need that reference. Also, the view has been added in the XML, you should not have to inflate it in the java.)
Now if you want to programmatically set a different empty view (for instance after performing a search), you could add another view to your relative layout, with another id (such as noResults)... and discover that it's always displayed.
<TextView
android:id="#+id/noResults"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="No results were returned."
/>
So in your onCreate() you'll need to find that view and set its visibility to gone as well.
ListView listView = (ListView)findViewById(android.R.id.list);
View empty = findViewById(android.R.id.empty);
listView.setEmptyView(empty);
View noResults = findViewById(R.id.no_results);
noResults.setVisibility(View.GONE);
Then whenever you change the empty view for your list, you'll want to set the visibility of the other view to GONE to make sure only one is getting displayed.
listView.setEmptyView(noResults);
empty.setVisibility(View.GONE);
I hope this helps!

Related

ListView adds empty view to root/parent instead of self?

I'm trying to add a custom empty view to a ListView as shown in this Q&A. But the ListView seems to add the empty view to its parent, or maybe to the root ViewGroup, rather than to itself. Am I doing something wrong here?
I created a small layout file that demonstrates the problem. Notice how the empty view is placed in the top left corner of the activity, completely outside the ListView:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/top_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Some text above the ListView" />
<ListView
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_alignParentLeft="true"
android:layout_below="#id/top_text" />
<TextView
android:id="#android:id/empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ListView empty text" />
</RelativeLayout>
Aren't the list items children of the ListView?
Yes, when the ListView creates them via the associated ListAdapter.
The empty view is not a list item. It is not a child of the ListView. It is simply another view. AdapterView toggles the visibility of itself and the empty view, depending upon whether or not the AdapterView is empty. If the AdapterView is empty, its own visibility is set to GONE and the empty view is set to VISIBLE. If the AdapterView is not empty, its own visibility is set to VISIBLE and that of the empty view is set to GONE. See updateEmptyStatus() in the source code for AdapterView.
Given the visibility toggle effect, the typical approach is to have the empty view roughly occupy the same space as does the ListView. However, that's not a requirement.

Edit Text and Text View not visible when ListView is set in Android

here my xml layout of my Android app (where I show all of my contacts)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="#+id/android:empty"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:layout_marginTop="5dip"
android:text="Scegli il contatto:"
/>
<EditText
android:id="#+id/editTextSend"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<ListView
android:id="#+id/android:list"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
I fill ListView using a custom Adapter.
But textView and Edit Text are not visibile. I want to show in particular edit text where users can write initial letters of his contacts name)
Suggestions to get them visible?
I fill ListView ... But textView and Edit Text are not visibile.
If you can only see a ListView then it appears you're using a ListActivity and forgot to call setContentView(). So you aren't actually using your layout... you only see ListActivity's default ListView.
That said, your XML code will work, but here are some quick notes:
As I stated in my comment, the TextView might be hidden depending on what type of Activity or Fragment you are using:
A ListActivity will automatically bind the #+id/android:empty and #+id/android:list Views, so the "empty" TextView is only shown when the ListView is empty.
An Activity won't recognize #+id/android:empty on its own. All the Views should be visible.
fill_parent is deprecated, simply use match_parent
Setting a ListView's height to wrap_content forces the Adapter to draw the ListView multiple times... with your layout I recommend using match_parent.
I'd say it is visible pretty fine with your layout. But anyway, I'd make listview declared that way:
<ListView
android:id="#+id/android:list"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" >
so it will take all the remaining free space

Android: I have a fixed header for a listview but the "glow effect" is only for the listview

I'm trying to make a layout similar to the people app, so I have a list with a fixed header at the top. I define the header on top of the listview inside a relative layout but the "glow effect" at the top of the list is only for the listview and not the whole layout.
This is what I have:
and this is what I want:
This is my layout file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="#+id/header_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:minHeight="20dp"
android:orientation="vertical" >
<TextView
android:id="#+id/status_header"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/last_updated"
android:textSize="12sp"
android:textStyle="bold"
android:textAllCaps="true"
android:gravity="center|left"
android:layout_marginLeft="20dp"
android:layout_marginTop="7dp"
android:layout_marginBottom="7dp"
android:textColor="#color/nice_blue"
/>
<View style="#style/HeaderDivider"/>
</LinearLayout>
<ListView
android:id="#+id/status_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:headerDividersEnabled="false"
android:footerDividersEnabled="false"
android:layout_below="#+id/header_layout" >
</ListView>
The glow effect in both examples are functioning the same.
What is happening within the People application is that it is also a ListView just like yours. The effect happens in the same place. The Me, #, A, etc headers are actually inside the ListView.
Option 1
To do what you are looking to do, put a header in the ListView, you'll also need to create a custom ListView. This means extending ListView.
It sounds more challenging than it is, but you should be able to find a number of examples online. Look for examples that extend a ListView rather than creating a custom ListView.
The general idea is that you'll add in a TextView into the the View of the ListView that will act as your header. This will put the header text Last updated at inside of the ListView view that you've created and since it is inside, it will be included underneath the glow.
Option 2
You may be able to use the addHeaderView(View v, Object data, boolean isSelectable) or addHeaderView(View v) methods on the ListView itself.
I believe this will add a header row inside the ListView, but I've never used this so I can't say for sure how it works. This may be easier, but will be less flexible.

Multiple ListViews and the Empty View

i have an Fragment which contains 2 ListViews. I try to set the EmptyView for each of them.
I tried to add them via XML using #id/android:empty and via Code, both times their get ignorend.
Anyone got it working with two ListViews and diffent Empty View ?
It is working, you have to make sure that the View (for the empty state) is added to your layout, where the ListView is in.
Also, the Adapter for your ListView have to be null or isEmpty() must be true to display the empty view.
If you have still problems, post some code.
I think #Leandros is on the right track, you need to make sure that each list is set up correctly. It sounds like there might be a mismatch when you are defining #id/android:empty twice in the same xml. You may need to give them unique ids, then hook them up them in the java.
Your xml might look something like this:
...
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<ListView
android:id="#+id/list1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="#+id/empty1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="List 1 is empty"
/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<ListView
android:id="#+id/list2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="#+id/empty2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="List 2 is empty"
/>
</LinearLayout>
...
Then in the fragment, you'll need to grab the views and attach them.
...
ListView list1 = (ListView)findViewById(R.id.list1);
View empty1 = findViewById(R.id.empty1);
list1.setEmptyView(empty1);
ListView list2 = (ListView)findViewById(R.id.list2);
View empty2 = findViewById(R.id.empty2);
list2.setEmptyView(empty2);
...
And if you really want a more complicated empty view, you could include another layout in your xml instead of the TextView.
...
<include layout="#layout/empty"
android:id="#+id/list1"
/>
...
<include layout="#layout/empty"
android:id="#+id/list2"
/>
...
I hope this helps!

Overlay TextView at bottom of ListView

I have a ListView that is being populated with a custom adapter. I have a pretty basic layout for each row of the the ListView (not even sure if this is applicable to my question):
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/BaseStyle"
android:orientation="vertical"
android:paddingLeft="5dip"
android:paddingRight="5dip"
android:paddingTop="8dip"
android:paddingBottom="8dip"
>
<TextView
android:id="#+id/text"
style="#style/BaseStyle.Title"
/>
</RelativeLayout>
I'd like to overlay a single TextView at the bottom of the ListView, but not entirely sure how as working with Android layouts can be an exercise in futility. :)
Wrap your main layout with a FrameLayout and put the view that you want to be in overlay as last child.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/home_container"
android:layout_height="match_parent"
android:layout_width="match_parent">
...
your ListView
...
your text view (it is gonna be on top of your layout)
</FrameLayout>
From your description I am not sure that this is what you are looking for, you should give some more info in your question, let me know.
If instead you are just talking about the TextView inside each list item then you just need to specifiy the alignment in your text view:
android:layout_alignParentBottom="true"

Categories

Resources