How to handle empty ListView in android? - android

Having a bit of trouble dealing with empty ListView in android. Here's what I've got:
public class MainActivity extends ListActivity {
...
refreshList();
...}
public void refreshAlbumList(){
albumList=control.listAlbums();
if (albumList.length!=0){
ArrayAdapter<String> ap = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,albumList);
setListAdapter(ap);
}else{
//deal with empty list somehow, currently results in error
}
}
What I've tried is:
this.getListView().setEmptyView(findViewById(android.R.id.empty));
And then inserting a TextView with id empty into main_activity.xml
But the result was that took over the screen and I couldn't see the list.
Current xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android1="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context=".MainActivity" >
<ListView
android1:id="#id/android:list"
android1:layout_width="match_parent"
android1:layout_height="wrap_content"
android1:layout_weight="1" >
</ListView>
</LinearLayout>

The ListView calls ListAdapter#isEmpty method to determine if it should show/hide itself and the empty view. You will therefore always need to set an ListAdapter.
So the answer is to always create your ArrayAdapter and always set it to the ListView. In your activities onCreate call ListView#setEmptyView method. Alternatively, you can simply have a TextView with the android:id="#android:id/empty" attribute and the ListActivity will detect it and assign it using the above method.
Example: https://gist.github.com/slightfoot/5519281

Related

How to make it easy to select a database?

I am new to stack, but I figured I need help. I hope someone can help me :).
What I want to do is the following:
the user of the App is saving some database (db3) files via PC in a folder he has to create. In my case he needs to call it "My Custom Foler".
implement a Spinner which lets the user choose from all db3 files of this directory and then be able to do db_selected.getReadableDatabase
Just to put it in context: I am gonna implement a ContenProvider and the populate a ListView with Items from specific table using SQliteOpenHelper and LoaderManager.LoaderCallbacks<Cursor>. BUT THAT IS NOT MY QUESTION.
I want to setup this spinner. Maybe someone can help?
Here is my code so far with still a lot missing but the basic structure should be clear.
Greetings :)
I added:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
In activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".MainActivity">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/list">
</ListView>
<LinearLayout
android:id="#+id/login_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="8dp">
<Spinner
android:id="#+id/select_database"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
</RelativeLayout>
MainActivity.class
public class MainActivity extends AppCompatActivity {
private final String DATABASE_PATH = "My Custom Folder";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//either we show login page or the populated ListView
ListView populatedListView = (ListView) findViewById(R.id.list);
View logInView = findViewById(R.id.login_view);
populatedListView.setEmptyView(logInView);
//How to setup a Spinner which lets select a ".db3" from a custom created Folder
Spinner spinner = findViewById(R.id.select_database);
//When Spinner item is clicked/touched I am gonna load it into my ListView
}
}
}

TwoWayView setAdaptor is not allowing to set the adaptor(HorizontalListView)

I tried using TwoWayView. My xml contains
<org.lucasr.twowayview.TwoWayView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/rewardListView"
style="#style/TwoWayView"
android:layout_marginTop="20dp"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:drawSelectorOnTop="false"
tools:context=".RewardActivity" />
I have created the Adapter which extends RecyclerView.Adapter and properly implemented every methods. Now in the activity, on the instance of TwoWayView, I try to set the adapter, but its not allowing me to set it up.
mRewardListView = (TwoWayView) findViewById(R.id.rewardListView);
adaptor = new RewardListViewAdaptor(mRewardList, this);
mRewardListView.setAdapter(adaptor);
I am getting this error "setAdapter(android.widget.ListAdapter) in TwoWayView cannot be cast to RewardListViewAdaptor".
Any help will be highly appreciated.

Android app crashes with weird error

I have button that launches a ListActivity, but every time I click on it, the app crashes with the following LogCat error:
01-10 13:12:51.327: E/AndroidRuntime(2970): FATAL EXCEPTION: main
01-10 13:12:51.327: E/AndroidRuntime(2970): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.app/com.app.Settings}: java.lang.RuntimeException: Your content must have a ListView whose id attribute is 'android.R.id.list'
This is the xml code:
<?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"
android:background="#color/background"
android:orientation="vertical"
android:padding="15dip" >
<ListView
android:id="#+id/listViewSettings"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
And this is the Java code:
import java.util.ArrayList;
import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
public class Settings extends ListActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings);
ArrayList<String> listItems=new ArrayList<String>();
listItems.add("foo");
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
listItems);
setListAdapter(adapter);
}
}
I have already tried changing the list id to list but if I do this I get the following error:
If I do this I get the following error: `Error: No resource found that matches the given name (at 'id' with value '#id/list').`
ListActivity does not require that you assign a layout to it via the setContentView() method, if you only want to show a ListView ListActivity contains by default a ListView.
In case you need to include more Views than a ListView in your ListActivity you can still assign a layout to your Activity. In this case your layout must contain a ListView with the android:id attribute set to #android:id/list.
So change your list id to:
android:id="#android:id/list"
This row in your XML:
android:id="#+id/listViewSettings"
...has to be like this:
android:id="#android:id/list"
Why? Well, the ListActivity requires you to use the id "android.R.id.list" if you want it to maintain your ListView (same thing applies when using a ListFragment).
Simply change your xml ListView-id
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
In this case your layout must contain a ListView with the android:id attribute set to #android:id/list

Android ArrayAdapter/ListView does not update in Fragment

I am facing a problem while updating a ListView via an ArrayAdapter in a Android Fragment.
I have a method handling a .csv that is retrieved from a server. It parses the .csv and does the following:
for(int i =0; i< lines.length; i++){
String[] words = lines[i].split(",");
for(int j = 0;j<words.length; j++)
if ( j%6 == 1 || j%6 == 2)
getArrayAdapter().add(words[j]);
Using breakpoints, I can see that "words[j]" is a valid String. The method getArrayAdapter is the following:
private ArrayAdapter<String> getArrayAdapter(){
if (aa == null){
ListView lv = (ListView) getCurrentActivity().findViewById(R.id.list);
aa = new ArrayAdapter<String>(
getCurrentActivity(),
android.R.layout.simple_list_item_1);
aa.setNotifyOnChange(true);
lv.setAdapter(aa);
}
return aa;
}
If the "getArrayAdapter().add(words[j]);" is called, method "notifyDataSetChanged()" in ArrayAdapter is called, as it should:
#Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
mNotifyOnChange = true;
}
Via its parent it reaches DataBaseObservable that does this:
public void notifyChanged() {
synchronized(mObservers) {
// since onChanged() is implemented by the app, it could do anything, including
// removing itself from {#link mObservers} - and that could cause problems if
// an iterator is used on the ArrayList {#link mObservers}.
// to avoid such problems, just march thru the list in the reverse order.
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onChanged();
}
}
}
The array of observers had an "AdapterDataSetObserver" that contains all kind of references to my adapter and ListView. I looked what happens in the onChanged() of AdapterDataSetObserver, but I do not really know what to look at.
My table_fragment.xml looks like:
<?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"
android:orientation="vertical"
android:id="#+id/top">
<ListView android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="2"
android:numColumns="2"
android:columnWidth="30dp"
android:id="#+id/list">
</ListView>
</LinearLayout>
The xml of the activity containing the Fragment looks like:
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".MainActivity" >
<fragment android:name="com.example.TableFragment"
android:id="#+id/table_fragment"
android:layout_weight="0"
android:layout_width="match_parent"
android:layout_height="0dip" />
</LinearLayout>
When looking in the log, nothing strange is there. All seems to go fine, but the screen does not show any of the strings.
What am I missing here? Probably missing something trivial, since I am a newbie to Android.
android:layout_height="0dip"
this is wrong. You should let get the ListView all the available space. Change it in fill_parent
then:
aa = new ArrayAdapter<String>(
getCurrentActivity(),
android.R.layout.simple_list_item_1);
you need to submit to the Apdater the dataset you want to show. For this purpose you should use this constructor
It turns out that layout_height of the ListView can be 0 (it auto expands). However, in the xml of the activity that contains the fragment, the layout_height could could not be set to 0 (it does not auto expand). I had put that on 0dip as well (after suggestion of Eclipse). Changing to "match_parent" did the job (despite the Eclipse warnings).
#Jos, the answer you selected is not the correct answer. The ListView height can, and should be, 0dp. In order for the ListView to function in its default manner you need to change the Id of the ListView to exactly android:id="#id/android:list" and you can also add a TextView or ProgressBar to show when the list is empty, also the default function of ListView, something like the following:
<TextView
android:id="#id/android:empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal|center_vertical"
android:text="#+string/empty_list_message" />
Again the id must match exactly, everything else can change to suit your needs.
Here is what the complete xml 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/android:list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:drawSelectorOnTop="false"
android:listSelector="#drawable/list_selector"/>
<TextView
android:id="#id/android:empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal|center_vertical"
android:text="#string/empty_list_message" />
</LinearLayout>
The layout_weight and listSelector are particular to my program, you may or may not need these.

Android: Listview NullPointerException

I've written a simple android list view, but it is throwing a java.lang.NullPointerException during run time. Checked it in debug mode and it seems the findViewbyId is returning null.
So when I get to the setAdapter it throws the exception. But the list does exist in the R.java file and the main.xml. How can I fix this?
setContentView(my.namespace.R.layout.main);
String[] a={"asd","asdsad"};
ListView lt;
lt = (ListView) findViewById(R.id.list);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,my.namespace.R.layout.rowitem, a);
lt.setAdapter(adapter);
Main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
Is your activity extends ListActivity? You dont need a separate layout if you extend ListActivity. See this tutorial for further reference.
Wirte this:
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,my.namespace.R.layout.simple_list_item_1, a);
Refer THIS

Categories

Resources