Showing empty view when ListView is empty - android

For some reason the empty view, a TextView in this case, always appears even when the ListView is not empty. I thought the ListView would automatically detect when to show the empty view.
<RelativeLayout android:id="#+id/LinearLayoutAR"
android:layout_height="fill_parent"
android:layout_width="fill_parent">
<ListView android:id="#+id/ARListView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"></ListView>
<ProgressBar android:id="#+id/arProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"></ProgressBar>
<!-- Here is the view to show if the list is emtpy -->
<TextView android:id="#id/android:empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="No Results" />
</RelativeLayout>
How can I hook up the empty view properly?

When you extend FragmentActivity or Activity and not ListActivity, you'll want to take a look at:
ListView.setEmptyView()

It should be like this:
<TextView android:id="#android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="No Results" />
Note the id attribute.

As appsthatmatter says, in the layout something like:
<ListView android:id="#+id/listView" ... />
<TextView android:id="#+id/emptyElement" ... />
and in the linked Activity:
this.listView = (ListView) findViewById(R.id.listView);
this.listView.setEmptyView(findViewById(R.id.emptyElement));
Does also work with a GridView...

I tried all the above solutions.I came up solving the issue.Here I am posting the full solution.
The xml file:
<RelativeLayout
android:id="#+id/header_main_page_clist1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="20dp"
android:paddingBottom="10dp"
android:background="#ffffff" >
<ListView
android:id="#+id/lv_msglist"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#color/divider_color"
android:dividerHeight="1dp" />
<TextView
android:id="#+id/emptyElement"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="NO MESSAGES AVAILABLE!"
android:textColor="#525252"
android:textSize="19.0sp"
android:visibility="gone" />
</RelativeLayout>
The textView ("#+id/emptyElement") is the placeholder for the empty listview.
Here is the code for java page:
lvmessage=(ListView)findViewById(R.id.lv_msglist);
lvmessage.setAdapter(adapter);
lvmessage.setEmptyView(findViewById(R.id.emptyElement));
Remember to place the emptyView after binding the adapter to listview.Mine was not working for first time and after I moved the setEmptyView after the setAdapter it is now working.
Output:

I highly recommend you to use ViewStubs like this
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" >
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<ViewStub
android:id="#android:id/empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout="#layout/empty" />
</FrameLayout>
See the full example from Cyril Mottier

<ListView android:id="#+id/listView" ... />
<TextView android:id="#+id/empty" ... />
and in the linked Activity:
this.listView = (ListView) findViewById(R.id.listView);
this.listView.setEmptyView(findViewById(R.id.empty));
This works clearly with FragmentActivity if you are using the support library. Tested this by building for API 17 i.e. 4.2.2 image.

Activity code, its important to extend ListActivity.
package com.example.mylistactivity;
import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import com.example.mylistactivity.R;
// It's important to extend ListActivity rather than Activity
public class MyListActivity extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mylist);
// shows list view
String[] values = new String[] { "foo", "bar" };
// shows empty view
values = new String[] { };
setListAdapter(new ArrayAdapter<String>(
this,
android.R.layout.simple_list_item_1,
android.R.id.text1,
values));
}
}
Layout xml, the id in both views are important.
<?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">
<!-- the android:id is important -->
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
<!-- the android:id is important -->
<TextView
android:id="#android:id/empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="i am empty"/>
</LinearLayout>

Just to add that you don't really need to create new IDs, something like the following will work.
In the layout:
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#android:id/list"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#android:id/empty"
android:text="Empty"/>
Then in the activity:
ListView listView = (ListView) findViewById(android.R.id.list);
listView.setEmptyView(findViewById(android.R.id.empty));

I had this problem. I had to make my class extend ListActivity rather than Activity, and rename my list in the XML to android:id="#android:id/list"

A programmatically solution will be:
TextView textView = new TextView(context);
textView.setId(android.R.id.empty);
textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
textView.setText("No result found");
listView.setEmptyView(textView);

First check the list contains some values:
if (list.isEmpty()) {
listview.setVisibility(View.GONE);
}
If it is then OK, otherwise use:
else {
listview.setVisibility(View.VISIBLE);
}

Related

How to avoid crashing for an listview android app [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I build an android app with the help of an tutorial.
This is the MainActivity.java:-
package com.example.listdisplay;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class MainActivity extends Activity {
// Array of strings...
String[] mobileArray = {"Android","IPhone","WindowsMobile","Blackberry",
"WebOS","Ubuntu","Windows7","Max OS X", "PHP", "Java", "HTML", "CSS", "JavaScript","MySQL"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayAdapter adapter = new ArrayAdapter<String>(this,
R.layout.activity_listview, mobileArray);
ListView listView = (ListView) findViewById(R.id.mobile_list);
listView.setAdapter(adapter);
}
}
This is the activity_main.xml:-
<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="match_parent"
android:orientation="vertical">
<ListView
android:id="#+id/mobile_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
This is the activity_listview.xml:-
<?xml version="1.0" encoding="utf-8"?>
<!-- Single List Item Design -->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/label"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="20dip"
android:textSize="16dip"
android:textStyle="bold"
android:orientation="horizontal">
</TextView>
When I change the textview to any other view like cardview and more things. The app is going to crashed.
I want to do more styling with cardview and layout. Like i also tried with the linearlayout.I inserted this textview with an button in linear layout. But, it is still going to crash.
Please help me.
You can't change the TextView from activity_listview.xml because ArrayAdapterconstructor expects a Layout with an only EditText.
If you want to modify that, you have to implement a custom ArrayAdaptermaking a class that extends from it.
You can follow next Medium tutorial to achieve this.
https://medium.com/mindorks/custom-array-adapters-made-easy-b6c4930560dd
If you want to add a Button or something else, you need the custom ArrayAdapter.
If you want to do more styling with card view so you don't need change text view to card view just simply write your code like below code...
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:cardCornerRadius="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp">
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/label"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dip"
android:textSize="16dip"
android:textStyle="bold"
android:orientation="horizontal">
</TextView>
</LinearLayout>
</androidx.cardview.widget.CardView>
Create your custom xml file:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="8dp">
<TextView
android:id="#+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="This is just text" />
</LinearLayout>
</androidx.cardview.widget.CardView>
Important part is android:id="#+id/label" in TextView.
And add the R.id.label to third parameter of ArrayAdapter, like that:
ArrayAdapter adapter = new ArrayAdapter<String>(this,
R.layout.activity_listview, R.id.label, mobileArray);

Creating ListView results in odd behaviour

I am trying to create a listView in my app. Such that only part of the screen will be used for the listView, and the other part will be used as permanent information. I get strange output, the listView instead of showing the required string, shows the permanent information.
Here is my code:
activity_main.xml
<!-- Start of the permanent information -->
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.mti_student.kol_mila.MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/header_image_id"
android:layout_width="100dp"
android:layout_height="90dp"
android:layout_marginBottom="0dp"
android:src="#drawable/logo"
android:layout_centerHorizontal="true"/>
<LinearLayout
android:id="#+id/search_panel_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/header_image_id"
android:orientation="vertical"
android:layoutDirection="rtl">
<TextView
android:id="#+id/text_view_id"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textAlignment="center"
android:text="Title"
android:layout_marginBottom="5dp"/>
<SearchView
android:id="#+id/search_view_id"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:queryHint="Search"
android:iconifiedByDefault="false"
android:layout_gravity="center"
android:queryBackground="#color/colorWhite"
android:background="#color/colorPrimary" />
</LinearLayout>
<!-- End of permanent information -->
<!-- This where I want my list view to appear -->
<FrameLayout
android:id="#+id/fragment_layout_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/search_panel_id"
android:background="#color/colorBeige"
android:layout_marginTop="5dp"
android:orientation="horizontal">
<ListView android:id="#+id/list_view"
android:layout_height="fill_parent"
android:layout_width="fill_parent">
</ListView>
</FrameLayout>
</RelativeLayout>
</android.support.constraint.ConstraintLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private List<String> filePaths = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
copyFromAssets();//Stores the information to filePaths
ListView lv = findViewById(R.id.list_view);
ArrayList<HashMap<String,String>> arrayList=new ArrayList<>();
for (int i=0;i<filePaths.size() ;i++)
{
HashMap<String,String> hashMap=new HashMap<>();//create a hashmap to store the data in key value pair
hashMap.put("file_name",filePaths.get(i));
arrayList.add(hashMap);//add the hashmap into arrayList
}
String[] from={"name"};
int[] to={R.id.topic_id};
SimpleAdapter simpleAdapter=new SimpleAdapter(this,arrayList,R.layout.activity_main,from,to);
lv.setAdapter(simpleAdapter);
}
You're using your main activity layout as the layout for each of the items rendered by the SimpleAdapter - see the third parameter of the constructor. Instead, provide the layout which contains the TextView with id topic_id, as per your setup prior to instantiating the SimpleAdapter.
Maybe it could be because you are using the same resource as your main activity to display the information in your list view
activity:
SetContentView(R.layout.activity_main);
you should use your own view for the list view to inflate
SimpleAdapter simpleAdapter=new simpleAdapter(this,arrayList,*R.layout.row*,from,to)

Set default ListView

Is there any way to change the ListView in a SherlockListFragment from defaulting to R.id.list? e.g. I have a custom list that overrides the default ListView in xml (list) that is defined as being below a linear layout. How do I make it so that setListAdapter will use this ListView instead of the default android ListView?
XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main_view_panel"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/toggleLL"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true" >
<ToggleButton
android:id="#+id/toggle_button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<ToggleButton
android:id="#+id/toggle_button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<ToggleButton
android:id="#+id/toggle_button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
<ListView
android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/toggleLL" />
</RelativeLayout>
Fragment:
public class ProblemFragment extends SherlockListFragment
{
private SeparatedListAdapter list;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.getSherlockActivity().setContentView(R.layout.apps_layout);
list = new SeparatedListAdapter(this.getSherlockActivity(), new Layout(R.layout.separated_list_adapter_two_text, R.id.two_text_title, R.id.two_text_desc));
setListAdapter(list); //Sets the list to the default list, not the overwritten list specified in the xml
}
}
Just change your layout XML to use android:id="#android:id/list".
ListActivity and ListFragment rely on the ListView having the id android.R.id.list, which is publicly exposed in the SDK (and accessible in XML via #android:id/list). If you look at the docs for either of those classes, both mention that using your own layout requires that you give your ListView this id for it to work properly.

Is it possible to have components other than List in ListActivity

By using the following code.
BuyActivity.java
public class BuyActivity extends ListActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.transaction_list_view);
OrderAdapter orderAdapter = new OrderAdapter(this,
R.layout.custom_row_view, new ArrayList<Object>());
setListAdapter(orderAdapter);
orderAdapter.add(new Object());
orderAdapter.add(new Object());
}
}
transaction_list_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView android:id="#id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="2"
android:drawSelectorOnTop="false">
</ListView>
<TextView android:id="#id/android:empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="No data"
/>
</LinearLayout>
custom_row_view.xml
Please refer to custom_row_view.xml
I was able to get the following outcome.
Besides list, I would also like to have a static label at the bottom of ListActivity.
I try
transaction_list_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView android:id="#id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="2"
android:drawSelectorOnTop="false">
</ListView>
<TextView android:id="#id/android:empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="No data"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="THIS IS TOTAL STATIC LABEL"
/>
</LinearLayout>
But I am getting
What my expectation is
Is there anything I had missed out?
You have indicated that your ListView is supposed to fill_parent in the vertical orientation, leaving no room for your other widgets. Your weight is being ignored. You probably want to have your android:layout_height be 0dip instead.
Try setting the height of the static textview to wrap_content.
Well you could try Relative Layout to just set the static label anchored to the bottom of the screen. If that's not what you meant, I would try to help you further on. Good luck

Customizing ListView via XML Problem

I have a simple ListActivity that uses a ListAdapter that I'd like to customize the ListView for. Here is my onCreate, where I specify to use a View rather than using the default ListView generated by setListAdapter():
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set the listview, empty listview
setContentView(R.layout.main);
getListView().setEmptyView(findViewById(android.R.id.empty));
// set the list properties
getListView().setOnCreateContextMenuListener(this);
.
.
.
<code snipped>
.
.
.
setListAdapter(adapter);
}
You can see that I am setting the emptyView as well. Here is the XML file main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="#id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fadingEdge="vertical"
android:dividerHeight="5dp" />
<TextView
android:id="#android:id/empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:singleLine="false"
android:text="#string/message_empty_list" />
</LinearLayout>
My problem is that the ListView, while applying the dividerHeight correctly, is ignoring the :fadingEdge directive when it is in the XML; however, if I set the fadingEdge programatically, it works, i.e.:
getListView().setVerticalFadingEdgeEnabled(true);
Any ideas why the listview would be ignoring the fadingEdge specifically? Am I doing something incorrectly that could be leading to this behavior?
Thanks!
android:id="#id/android:list"
should be
android:id="#iandroid:id/list"
I'm not even sure why that compiles.
This is how you should be using custom xml for listactivities.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<TextView
android:id="#android:id/empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="No data found"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceMedium" />
</FrameLayout>

Categories

Resources