I want to be able to show an alternative to an empty list, currently the following method call sets up the list, however taskArrayList could be empty if the call to the database has returned an empty list
/**
* Setup list adapter.
*/
private void setupListAdapter() {
setListAdapter(new TaskAdapter(this, R.id.tasks_list_view,
taskArrayList));
taskListView = getListView();
taskListView.setOnItemClickListener(new TaskClickListener());
}
I'm thinking that before I call this method, or at the beginning of the method adding the following check
if(taskArrayList.isEmpty()) {
/*load an alternative view*/
}
however because my Activity is a ListActivity so it requires a ListView to be set against it, so I'm unsure of the best approach to handling the case when the list is empty.
I don't want to create a "dummy item" which says there are no items and add it to the ArrayList but I'm not sure of the alternatives.
If you add something with the idea #android:id/empty
it will be shown instead of the list when it is empty automagically!
<TextView android:id="#android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF0000"
android:text="No data"/>
In the documentation they say it like this:
Optionally, your custom view can contain another view object of any type to display when the list view is empty. This "empty list" notifier must have an id "android:id/empty". Note that when an empty view is present, the list view will be hidden when there is no data to display.
http://developer.android.com/reference/android/app/ListActivity.html
Related
I need to change just first row in my ListView. I used such way:
private void updateAdapter(int number) {
String value = Integer.toString(number);
list_.clear();
list_.add(value);
adapter_.notifyDataSetChanged();
}
But, does anybody know another way, like myAdapter.update(newValue)? I use simple adapter
private ArrayAdapter<String> adapter_;
and ListView
<ListView
android:id="#+id/list_view"
android:paddingBottom="150dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
Basically, if your add or remove elements from your data source (which I assume is list_ here) and you call notifyDataSetChanged(), the ListView will get recalculated in the designated way based on your (changed) data source.
Therefore it wouldn't make sense to directly update your adapter (with the proposed function adapter.update()).
If you're worried about performance (which I think is your motivation here when only changing the first row) check Using an ArrayAdapter with ListView to see how the population of a ListView works.
Get the element by using getItem (int position) from the SimpleAdapter class. No you can change the object inside the adapter.
After change value call...
listAdapter.notifyDataSetChanged();
... to refresh your UI.
See doc: SimpleAdapter - getItem(int pos)
I am using merge adapter to merge two custom cursor adapters in android.I could not find clicked section to get data from my custom cursor adapter.How can I get adapter object when listview clicked?.
I tried following way in my onitemclick of listview. But it does not print "clicked on mention question section" text.But it returns android.content.ContentResolver$CursorWrapperInner#41b9a638.How can I find which section is clicked in listview?
if (parent.getAdapter().getItem(position) instanceof FeedMentionQuestionAdapter) {
LivLog.info(getClass(), "clicked on mention question section ");
}
How can I get adapter object when listview clicked?
You need to hold onto your own adapter, or call getAdapter() on your ListView.
But it returns android.content.ContentResolver$CursorWrapperInner#41b9a638
Presumably, you put a CursorAdapter in the MergeAdapter.
Also, getItem() will never return an adapter. It returns items. If you are trying to determine the adapter that handles a particular position, call getAdapter().
How can I find which section is clicked in listview?
If you are referring to SectionIndexer, then sections are not clicked.
When the app starts, I load some objects from the Device's SD Card and add them to a ListView.
Objects = new ArrayList<DataObject>();
Items = new ArrayList<MenuItem>();
Adapter = new MenuItemAdapter(this, Items);
listView.setAdapter(Adapter);
LoadObjects();
When I load objects I deserialize the object, check it's unique ID and if it's already in the list of Objects it should not be added. My method LoadObjects loads tries to load all files in a directory with a given extension. Then if successful, tries to load it into the Items list by using this method:
private boolean LoadObject(DataObject obj)
{
for (DataObject do : Objects)
{
if (do.GetID().equals(obj.GetId())
return false;
}
boolean added = Objects.add(do);
if (added)
{
Items.add(new MenuItem(do.GetID(), do.GetName());
Adapter.notifyDataSetChanged();
}
return added;
}
When this method is run "onCreate" it works fine, it loads in all the objects that can be loaded and is stored on the SD Card. When I try to add one after this method, the first item appears in the list where the new item should be added. I input a new name with a Dialog to create a new DataObject, which will later call LoadObject(new DataObject(name));
I've tried:
Resetting the Items adapter
Adding a "Add" method on the custom Adapter so that instead of adding to Items, I add through the Adapter by Adapter.Add(new DataObject(name)) which adds to it's own list; I also have a SetList adapter, to recreate the list without success.
Skip the notifyDataSetChanged
Cleared the Object list, Items list, Create a new Adapter each time - reloading all Objects, all MenuItem's, recreating the adapter and setting a new List - all with the same result.
Skip LoadObjects() and just let all newly added items appear, first one is correct - but whatever I add later shows up as the same as #1 from the ListView.
And I have to use FragmentActivity and not ListActivity because I have some Dialogs I need to show.
Simply put, I use the ListView to show specific Files from the SD Card to be able to load them onto another Activity later - but this hinders me from adding any new items without having to restart the Activity just to show new items, which means I need to be able to start out with an empty list and then
Probably becouse you use Adapter that have multiple references. Try to rename and don't name variables with uppercase.(see also import list to see what Adapter did you have there)
Your attempt #4 has to work. Give next loadObject() a shot:
private boolean LoadObject(DataObject obj)
{
for (DataObject do : Objects)
{
if (do.GetID().equals(obj.GetID())
return false;
}
Objects.add(obj);
Items.add(new MenuItem(obj.GetID(), obj.GetName());
Adapter = new MenuItemAdapter(this, Items);
listView.setAdapter(Adapter);
return true;
}
Seems that the problem occured due to a ListView being inside a RelativeLayout, altough I can't figure out why.
This is how my Layout was first:
<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" >
<ListView
android:id="#+id/main_menulist"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</ListView>
</RelativeLayout>
When I instead created a new Layout with a ListView only, the problem no longer occured:
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main_menulist"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
I've only read about how you should not put a ListView in a ScrollView, but I've used this type of solution (perhaps not by dynamically adding items) before and it's worked.
I have list view. I need to set delete button to each row. Is there any standard way to
do this in android?
Thank you very much.
Android way is to not have a delete button but an action based on long press. So when you long press on the list it will show a list of stuff you can do and include delete in it. For example, you can check your Gmail, sms and long press on the thread to get this option.
You need to write your own list view item layout, which includes a delete button, see here for some details on that. In the button XMl you need to have the android:onclick attribute set, then in your code have an appropiate matching method. for example
<button android:onclick="deleteItem" android:text="Delete" ...>
public void deleteItem(View view) {
... code to delete...
}
You have to do xml file with single row (with button) then make class which extends some Adapter for example:
arrayAdapter = new MyArrayAdapter(this, R.layout.news_row, newsList)
where MyArrayAdapter extends ArrayAdapter, news_row is xml with view of single row, newsList is ArrayList with data
I have an ArrayList of an object which has properties Object.name and Object.url.
I want to loop through the ArrayList and apply the Object's "name" to an android ListView. I also want to keep the Object's other properties in tact, so that i can call the "url" property in the onClick method.
What i have now is this:
main_list.setAdapter(new ArrayAdapter<RomDataSet>(this, android.R.layout.simple_list_item_1, android.R.id.text1, mRoms));
But clearly that is not what I need...
Any help would be appreciated :)
1.) You have your ArrayList:
main_list
2.) Create a ListView in your XML file (say, main.xml) and grab its id. That is, given:
<?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"
>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/liveFeed"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
Do something like this:
ListView livefeed = (ListView)this.findViewById(R.id.liveFeed);
within your activity (if you're in somewhere else such as an OnClickListener, replace the "this" with the View variable that was passed as a variable into the OnClickListener).
3.) Define your ArrayAdapter. Note that one of its parameters (the third one in your case) will be a TextView id. This is because the ArrayAdapter class, by default, returns a TextView in the ListView. If you override the ArrayAdapter class, you can use custom layouts to have items with custom Views within your ListView, but this is not necessary for what you've outlined in your question, and it seems like you've got it already.
4.) Set the adapter to the ListView (given an ArrayAdapter named 'aa'):
livefeed.setAdapter(aa);
Now the way the ArrayAdapter works is it invokes each Object's toString() method and sets each TextView in the ListView to this String. So make a toString() method in your Object's class that returns its name property:
public String toString(){return name;} //assuming name is a String
Also note that, if you add Objects to the ArrayList, notify the ArrayAdapter that you have so it can accordingly update your ListView with the modifications (given an ArrayAdapter named 'aa'):
aa.notifyDataSetChanged();
Let me know if you need any more help. As always, check the answer check mark if this answered your question.
Also note that, at one point you may wish to cross reference your ArrayAdapter and ArrayList between your activity and Object class. It's very helpful to make these fields static in order to do so.
EDIT:
You wanted to also know how to access a specific Object when you click on an item in the ListView. Here it is (given your ListView is named livefeed):
livefeed.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
//in here you may access your Object by using livefeed.getItemAtPosition(position)
//for example:
Object current = livefeed.getItemAtPosition(position);
//do whatever with the Object's data
}
});