Spinner in ActionBar is not updating ListView - android

I have two elements:
Spinner INSIDE THE ACTIONBAR (HoloEverywhere (support.v7)) of my Activity set with an onItemSelectedListener().
Listview in my Activity which is filled with an ArrayAdapter
When I choose an Item from the Spinner, the ListView should be updated. But somehow there is a problem with my Spinner I guess. The ListView first updates when I clicked in a TextField of my Activity after I choose a SpinnerItem.
My code:
// Get a databaseConnection and fills the history variable with the data of
// the selected spinnerItem "history" is right filled with all Strings for
// the chosen Spinner from the database -> works correct
public void updateHistory() {
sqlLightDatabase database = new sqlLightDatabase(this);
ArrayList<String> history = database.getArrayList(
mySpinner.getSelectedItem().toString());
// set the adapter to the ListView
ArrayAdapter<String> listenAdapter = new ArrayAdapter<String>(this,
R.layout.list_item, history);
myListView.setAdapter(listenAdapter);
// the code works through, but the ListView is not shown the update
// instantly. But now, when I click a TextField in my Activity, myListView
// shows the new data
}
// Is instantly called when an Item is selected in mySpinner (in my ActionBar)
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position,
long id)
{
// the updateHistory function is called but myLitstView doesn't get
// updated with new Data
updateHistory();
//Just for testing. The following is working instantly fine.
drivenDistance_TF.setText("History changed");
}
I tried the last two days to fix this issue, but I have absolute no idea what I could else try to get the ListView instantly updated.
There is no ErrorLog, because there are no errors.

You must call notifyDataSetChanged method to update data in list view
So write this line
listenAdapter.notifyDataSetChanged();
after myListView.setAdapter(listenAdapter);
in updateHistory();

Related

Changing background colour of listview item on click - and remembering it

I am populating a listview with strings from an ArrayList.
When a listview item is clicked i would like to change the background colour to green. <- Issue number one because I cannot change the item which is clicked.
After an item is clicked, I am adding its index to the list of items the user has selected, when the listview is first loaded I need it to set the background colour of all the listview items which have been selected to green too. <- Issue number 2 - I have been trying to do this with a for loop but do not know how to refer to a specific item in the listview to set the background colour!
Essentially, i think if someone can help me in how to change the colour of a selected listview item, i should be able to do the same thing but in a loop for all the userFoodPref which are saved?
animalsNameList = new ArrayList<String>();
userFoodPref = new ArrayList<Integer>();
getUserSelection();
getAnimalNames();
// Create The Adapter with passing ArrayList as 3rd parameter
ArrayAdapter<String> arrayAdapter =
new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, animalsNameList);
// Set The Adapter
animalList.setAdapter(arrayAdapter);
// register onClickListener to handle click events on each item
animalList.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
// argument position gives the index of item which is clicked
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
if(userFoodPref.contains(i)
){
userFoodPref.remove(i);}
else {
userFoodPref.add(i);
View item = animalList.getSelectedView();
item.setBackgroundColor(0x0000FF00);
}
String selectedAnimal=animalsNameList.get(i);
Toast.makeText(getApplicationContext(), "Animal Selected : "+selectedAnimal, Toast.LENGTH_LONG).show();
}
});
}
If I understand well, the problem is that when you set the backround of the item and then by example scroll the list and comeback to the previous position, it doens't remember that the backround is green for this specifix item.
I have faced this problem and to solve it easily :
Create a list a string for your name and a boolean (true = green, false = not green) and create an adapter for it and simply add
if (list.get(position).getBoolean) {
Currentitem.setBackgroundColor(0x0000FF00)}
And when you click on a item simply set the boolean of the item position to true and call notifydatasetchanged()

ListView does not show changes until focus changes after notifyDataSetChanged

I have an AlertDialog with a ListView set to multiple selection on it. It also has a Button on it.
The Button open another AlertDialog that if ok'ed will remove the selected items from the data set of the ListView, and then tell the adapter of the list view that the dataset has changed with the notifyDataSetChanged() method.
This all works fine except for one thing. The ListView does not update it's content until I interact with something. Then it updates to the correct data.
This is not a big problem, but I really would like the ListView to appear correct at once, and not just after the focus has changed.
Code:
Button remove = (Button) view.findViewById(R.id.btn_remove_questions_edit_rack);
final Context con = this;
remove.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
Builder warnBuild = new Builder(con);
warnBuild.setMessage(R.string.question_deletion_warning);
warnBuild.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
SparseBooleanArray checked = list.getCheckedItemPositions();
for (String s : keys)
{
int i = keys.indexOf(s);
if (checked.get(i))
{
toRemove.add(map.get(s));
map.remove(s);
}
}
keys.clear();
keys.addAll(map.keySet());
((ArrayAdapter) list.getAdapter()).notifyDataSetChanged();
list.clearChoices(); //This makes sure the selection is cleared, if it isn't, some of the other items (those that now has the index of the selected items) will be selected when the View refreshes.
dialog.dismiss();
}
});
//Negative button here, not relevant.
}
});
Where map and keys are:
final HashMap<String, QualityQuestion> map = new HashMap<>();
//I add items to the map
final ArrayList<String> keys = new ArrayList<>(map.keySet());
And toRemove is where I store the items to be removed from the actual object they are on when the ok button on the original AlertDialog is pressed.
This is how I populate my ListView in the first place:
final ListView list = (ListView) view.findViewById(R.id.list_questions_edit_rack);
list.setAdapter(
new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_activated_1,
keys));
I have tried things like list.invalidateViews(), list.invalidate and other things I found in questions similar to mine here on SO. But none of that made any difference. I suspect my problem to be different from theirs since my items clearly are updated, it just takes a change of focus on the original AlertDialog for the change to be visible.
How can I make the ListView show the changes in it's data source imidiatly insted of after a focus change?
By calling
((ArrayAdapter) list.getAdapter()).notifyDataSetChanged();
you get a fresh adapter which is almost certainly not identical to the anonymous adapter you used to populate your list in the first instance.
See also the documentation for ListView.getAdapter()
Returns the adapter currently in use in this ListView.
The returned adapter might not be the same adapter passed to setAdapter(ListAdapter) but might be a WrapperListAdapter.
From the point of view of this fresh adapter, the data set hasn't changed because the changes happened way before it was instantiated.
To solve your problem, make your list and your list adapter members of your activity class (or the scope where you want to keep them alive):
private ArrayList<String> keys;
private ArrayAdapter myAdapter;
private ListView list;
Then in your "onCreate()"
keys = ...; // initialization of ArrayList with the needed data
myAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_activated_1,
keys);
list = (ListView) view.findViewById(R.id.list_questions_edit_rack);
list.setAdapter(myAdapter);
This way, in your "OnClickListener" you can notify "myAdapter":
keys.addAll(map.keySet());
myAdapter.notifyDataSetChanged();
Hope this helps :)
You can tweak it, by granting focus to another view, and then requesting it back:
view.requestFocus();
You can also use:
view.requestFocusFromTouch();

Spinner OnItemSelectedListener() not working with one item in list.

So I am having a problem with a spinner not firing the listener when there is only one item in the list.
Here is a break down of what i am trying to do: have a spinner with a string that displays an id/title for an object, there is a button to add items to this spinner that creates a dialog and returns and object from the dialog and updates the spinner. I currently have the spinner working to add items to the spinner after the dialog closes. the code works as intended when there are multiple items in the spinner, however if there is only one item in the spinner then no onitemselectedlistener is fired. I know this because i have debugged the code and walked over the listener, when trying to select an item when there is only one item in the list does nothing. However, if i add another item to this list i am able to select it but only after first selecting the second or third so on item in the list
it is almost as if this item is if this is the item the spinner is currently selecting and therefore not generating any event for pressing it. I suppose my question would be how do i clear the spinner selection so that there is no Current selection. or would i have to do something like always have an entry in the spinner that says "Choose One" and have a check that would only do some action if the spinner's current selection wasn't equivalent to "Choose One".
my listener as it currently stands
methodSpin.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if(first == false) {
body.setText("");
currentMethod = hold.get(position);
Toast.makeText(methodActivity.this, "Text!" + position + ":" + currentMethod.body, Toast.LENGTH_SHORT).show();// for feedback/testing purposes
body.setEnabled(true);
body.setText(currentMethod.body);
}
else
Toast.makeText(methodActivity.this, "check == false", Toast.LENGTH_SHORT).show(); // for feedback/testing purposes
}
public void onNothingSelected(AdapterView<?> parent) {
Toast.makeText(methodActivity.this, "onNothingSelected", Toast.LENGTH_SHORT).show();// for feedback/testing purposes
}
});
The Spinner will always have a selected item even if you call Spinner.setSelection( -1 ). I guess what you can do it to add a prompt
as the first option.
ArrayList<String> aOptions = new ArrayList<String>();
aOptions.add("Choose One");
aOptions.add("Option 1");
ArrayAdapter<String> adapter = new ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item, aOptions);
Spinner spinner = (Spinner)findViewById(R.id.spinner);
spinner.setAdapter(adapter);

ListView Selected Position always resets

I am working with a ListView trying to add/delete items. The addition bit was fairly easy, the removing though is proving to be trickier.
I was thinking to use a multiple choice list, but to start with something simpler I chose a single choice mode just to test it out.
I have an array of strings containing the items, an array adapter to notify when Data has changed.
expenseAdapter=new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_single_choice,
android.R.id.text1,
expenseList);
myListView.setAdapter(expenseAdapter);
myListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View item, int position,
long index) {
((ListView)parent).setItemChecked(position, true);
item.setSelected(true);
}
});
I have also added a listener for the item onClick Event. Visually the item gets selected/deselected the issue is when I click the button which triggers the deletion of the item the selected index in the list is always -1 although the item appears to be selected.
Delete button with onClick event
public boolean doDelete(View view)
{
ListView myListView= (ListView)findViewById(R.id.list);
String s=(String)myListView.getSelectedItem();
expenseList.remove(s);
expenseAdapter.notifyDataSetChanged();
return true;
}
Any ideas what is happening or what I'm doing wrong?
use this
xmlfile : https://www.dropbox.com/s/eky9zb275mgt4py/activity_list__addand_delete.xml
javaFile : https://www.dropbox.com/s/idqyyosbutgqqbs/List_AddandDelete.java
your selection ( focus ) is removed when ever you will shift your focus to button .
I have seen your code and understand that problem, you are getting -1 index when you are removing item from List because that item is not existing in that list so change your code please try this.
I changed getSelectedItem() to getSelectedItemId() here it will return selected item id instead of Item so you can remove that item from List based on item id which will be the Index of item in List.
public boolean doDelete(View view)
{
ListView myListView= (ListView)findViewById(R.id.list);
long id = myListView.getSelectedItemId();
expenseList.remove(id);
expenseAdapter.notifyDataSetChanged();
return true;
}
Hope it will help you.

Stuck... need help.. Listview w/ Array Adapter

Ok, so I have this application that takes a adress strings (from values/xml) and parses it your current position) retuning a name, address and distance away. This is then picked up by an arrayadapter and put up on a listview. I cannot for the life of me get the list view to accept an onitemclick to start another activity, where I can launch a different view. I did have it where I was getting the row, name and address to show through to an alert dialog, but in my efforts to get it to launch an activity, I lost that.
So does anyone have any thoughts? I am using the following call to make my list and and arrays. This is stripped down, so assume I have all the imports and proper formatting. I know I am just missing something simple here...
public class Wf extends ListActivity {
private ArrayList<String> DistanceList;
private ArrayAdapter<String> aa;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
// Bind the ListView to an ArrayList of strings.
DistanceList = new ArrayList<String>();
ListView lv = (ListView)findViewById(R.id.ListView01);
aa = new ArrayAdapter<String>(getApplicationContext(),
R.layout.listbox_layout,
DistanceList);
lv.setAdapter(aa);
//Call to get distance... here
}
public void onListItemClick(ListView parent, View v,int position, long id) {
ListView lv = (ListView)findViewById(R.id.ListView01);
Toast.makeText(this, "You clicked", Toast.LENGTH_LONG).show();
}
From the ListActivity docs:
ListActivity has a default layout that
consists of a single, full-screen list
in the center of the screen. However,
if you desire, you can customize the
screen layout by setting your own view
layout with setContentView() in
onCreate(). To do this, your own view
MUST contain a ListView object with
the id "#android:id/list" (or list if
it's in code)
Your ListView does not have the correct ID. Your code is incomplete but I suspect the listener is not being registered with the ListView.

Categories

Resources