Refreshing a Spinner - android

I have a view with a spinner. The activity starts another acvitity with a popup where I add or delete values that the parent shows in the Spinner.
So, in onActivityResult() I refresh the content of the Spinner so that it reflects any additional or deleted values, by calling my fillSpinner() method.
The parameter to this method is the previously selected value:
private void fillSpinner(String value){
Cursor c = mDbHelper.getAllCategories();
startManagingCursor(c);
c.moveToFirst();
String[] from = new String[]{DBAdapter.KEY_CATEGORY};
SimpleCursorAdapter scCats = new SimpleCursorAdapter(
this, android.R.layout.simple_spinner_item,c,from,
new int[]{android.R.id.text1});
scCats.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
category.setAdapter(scCats);
if (value != null && value != "") {
category.setSelection((int)mDbHelper.categoryIndex(value));
}
}
When I open the Spinner, it contains the correct list (i.e. it was refreshed) and the correct value is selected. However, the Spinner control itself (in its closed state) does not show the selected value, but the first in the list.
When I step through the code in the debugger, the Spinner value is correct before and after I call setSelection() (and it is always called with the same correct id). However, since I cannot step out of the event, when I resume the execution after a short moment the value in the Spinner changes.
In other words, the spinner's displayed string is changed and is different from the selected item when I return from my popup activity.
Any ideas are appreciated.

I found a simple solution to that problem: Use the form Spinner.setSelection(int position, Boolean NavigateTo) to have the Spinner show the correct selected item.
Example: Spin.setSelection(iPos, true);
Good luck.

The problem, I think, was due to my cursor being recreated on every call. I don't have a better explanation. This post indirectly pointed me in the right direction.
By holding on to the cursor after creating it initially, I was able to just call requery() after changing the list data, as opposed to running through the method in my question. It works fine now.

Related

SpinnerButtonAdapter using ASyncTask to auto select from database

I have a spinner which is populated from the database. This in turn is pulled from a webservice so it is not possible to hard-code the values.
The spinner is part of a form that the user fills out and saves and I need them to be able to go back in and edit the values, so I am trying to auto-populate it based on what was selected.
The problem is that the spinner does not always select, which happens more often than not. I think this is due to the fact that I am loading the data asynchronously using an asynctask, and by the time it retrieves the data the spinner has yet not been loaded. I have logging showing that, for example, spinner item 4 was pulled from the database, but the spinner shows nothing selected.
What is the best way to find out when the loader has been completed so that I can populate (ie select) the relevant item in the list?
I put the call at the end of the load finished method,
#Override
public void onLoadFinished(Loader<Cursor> aLoader, Cursor aCursor) {
int id = aLoader.getId();
Loader<Cursor> cursorLoader = null;
switch (id) {
mAdapter.swapCursor(aCursor);
}
if (inEditMode) {
fillInValues();
}
}

Display item on click on ListView

I need help on a specific task :
I have a ListView in my main activity with a custom Adapter associated, and an OnItemLongClick listener that displays a Dialog with many operations configured (change quantity, cancel item...) and it works like a charm.
My goal is to have a physical copy of the clicked item in the Dialog, to display immediately the changes made.
Since my ListView item is complex and designed by the Adapter, i can't just get the reference to the original object, i need a visual copy of the selected ListView item...
I thought about creating the same structure (ListView and Adapter) with only the selected item associated but it's kind of heavy...
Is there a simpler solution that can help me in this situation ? I mean real copy of the original ListView Item with changes made in my Dialog done to the original object...
Posting your relavent code may help us to guide you more clearly.
However you can get your object in onItemLongClick((AdapterView, View, int position, long) using position params i.e
YourObject objReference = yourActivityClassObjectList.get(position);
now when showing dialog, pass this objReference to your dialog and when changes made, change the contents of this objReference and call
adapter.notifyDataSetChanged();
instead of passing the objReference to dialog, you can pass int position and while changes made, get the reference to that object, change contents and notify data set changed to Adapter.
When you click on one listview item the onListItemClick callback should be fired. As you see in the doc the third parameter is position. You can call YourAdapter.getItem(int) to retrive the element hold by the listview at position

Get Position from SimpleCursorAdapter

Is there a way to do this? My specific purpose is that I am trying to populate a label from an edittext within my list that is populated by a simplecursoradapter. When I gather the information from the cursor is only gives me the value from the most recent item in the list.
Example:
lbs = (TextView)view.findViewById(R.id.GrainLbs);
lbs.setOnTouchListener(new OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent arg1) {
if(!popState){
parentActivity.showPopup(v, mView, getId, String.valueOf(getLbs));
Log.i("Current ID", "");
}
setPopState();
return true;
}
});
I'm trying to pass the value from the database to a method in my activity from within my custom simplecursoradapter (String.valueOf(getLbs)) which since i'm gathering this information by clicking on an object in the listview I thought it would automatically use the data from the specific list item. Is there a way I can get the list item position and then use info from the database based on the position?
If you are extending ListActivity, then you can override ListActivity.onListItemClick. The second argument passed into that function is the position in the list, which is the same as the position in your SimpleCursorAdapter.
This turned out to be such a simple answer and I can't believe i've spent so much time trying to figure it out. Because I was collecting the value within an inside method (an onclicklistener) I needed to make my variable final, it was declared at the beginning of the class so it could be used throughout, and because of this I wasn't getting an exception, but I needed to make it final before it would pass the correct value for whatever reason.
So I guess if you bind your views within a customcursoradapter you can collect values for each individual listitem without knowing the position, it automatically knows this for you.

How to refresh cursorAdapter especially when deleting last item in a list?

How to refresh cursorAdapter especially when deleting last item in a list?
scenario:
working:
editing list-view row, OK
adding list-view row, OK
deleting list-view row(one by one), until one is left, OK
problem:
deleting the last row/item, FAILED;
you need to close first your activity and open it again for it to refresh.
I am using a cursor adapter, and I want to refresh its list when deleting the last row/item of a list view. my method for refreshing an adapter is to assign a new instance of cursorAdapter to my Listview(as if, doing this again and again).
code:
listview.setAdapter(new ImmunizationListCursorAdapter(
this,// current activity
R.layout.imm_list_row,// layout for each row
immunizationCursor,// the data
// Pass in the cursor to bind to.
// Array of cursor columns to bind to.
new String[] { ImmunizationModel.IM_COL_VACNAME,
ImmunizationModel.IM_COL_DATE },
// Parallel array of which template objects to bind to
// those
// columns.
new int[] { R.id.text_vaccine_name,
R.id.text_date_description }));
there it is.
any one who can help me? :((
All you need to do is to call productCursor.requery() after each modification to the dataset.
requery() automatically triggers execution of your query (in order to retrieve the new data) plus notification to the ListView (by the adapter) that it has to refresh itself.
BTW, until not so long ago I was using the same wrong method of assign a new instance of CursorAdapter...

How to remove the filter on an ArrayAdapter used in an AutoCompleteTextView?

As the title, how can I remove the filtering on an ArrayAdapter used by an AutoCompleteTextView to get the original list back?
A little more background:
It all started from the sad fact that the "position" value passed in to onItemClick() is useless. The "position" refers to the position AFTER the array has been filtered, but I need to know its REAL position. So, what I'm trying to do is when I've got the text of the selected item (by using getItemAtPosition(position)), I compare it one-by-one with the original string array that backs the ArrayAdapter. However, I found that when onItemClick() is called, the adapter is already filtered, I no longer have access to the original array. So I thought if I can remove the filter, maybe I can get back the original array and look for the selected item in it.
ArrayAdapter<String> mAdapter;
public void onCreate() {
// Create an adapter and remembere it as a class member.
mAdapter = new ArrayAdapter<String>(this, layoutId);
// Add 100 strings to it and attach it to an AutoCompleteTextView
for (int i = 0; i < 100; i++)
mAdapter.add("random text");
((AutoCompleteTextView)findViewById(id)).setAdapter(mAdapter);
}
#Override
public void onItemClick(AdapterView<?> actv, View view, int position, long id) {
if (actv.getAdapter().equals(mAdapter))
Log.d("The adapter contained in actv is the same one I created earlier.");
// And, I can get the text of the item the user selected
String selected = (String)actv.getItemAtPosition(position);
// However, although the adapter passed in is still the same one, but the
// number of items in it is only 1! Because the array has been filtered.
int numItems = actv.getAdapter.getCount();
// So, I'm thinking if I can somehow remove the filtering here, then I can
// get back those 100 items, and do a search like following:
for (int i = 0; i < actv.getAdapter.getCount(); i++)
if (selected == actv.getAdapter.getItem(i))
break; // Eureka!!!
}
To tackle the problem of obtaining the REAL position of the selected item:
Is there a way to utilize the "id" value? Like, assign each item an id, then hopefully onItemClick() would pass back the correct id.
Like I said above, remove the filter (is it possible), get back the original 100 items, and perform a one-by-one search.
This is the last resort, I know it'll work, but I don't want to do it: Once I get the text of the selected text, I go back to the source of the data (from a database), query those 100 items out, and perform the search.
Another lame last resort: To avoid the overhead on accessing the database again as in #3, when in onCreate(), while creating the ArrayAdapter, I use an ArrayList of my own to remember all those 100 strings.
Am I doing it all wrong? What's the "right" way of obtaining the real position of the selected item from an AutoCompleteTextView?
Thank you very much!
(I read somewhere, some buy that seemed to be from Google Android team, said that one should use getFirstVisiblePosition() to resolve the position. But I can't figure out how.)
I don't know if you're still interested, but I found this answering a similar question: Problem with AutoCompleteTextView and Spinner using the same Adapter
Copying the method in the AutoCompleteTextView source code:
Filter filter = mAdapter.getFilter();
filter = null;
See my response in the above question for the grepcode link.
This is actually pretty simple to solve.. Instead of adding each element to the adapter as you get it (I'm assuming your random text part is just for example purposes), instead use the following:
First build your array into a variable, call it myArray..
then initialize your adapter like this:
mAdapter = new ArrayAdapter<String>(this, layoutId, myArray);
Now make sure that myArray is a class variable so you can reference it from anywhere else in the class.. Of course if you need access to this from another class you'd want to make a getter for it... Then you can easily iterate over the array to see if the value selected is in the array.. You'll have the whole set of data there instead of trying to get it from the adapter.
Here is a good example on using a validator for a similar looking use case:
Android, Autocomplettextview, force text to be from the entry list
In my case, I have address that can be set either by autocomplete or clicking on the map. If user click on the map, editText text should be set to address selected from the map, and in that case filtering should be disable temporarily.
I code like this:
public void OnAddressFound(String address) {
// Temporary disable autocomplete
editTextSearch.setAdapter(null);
editTextSearch.setText(address);
// Enable autocomplete again
setAutoCompleteAdapter();
}
where setAutoCompleteAdapter() is called during onCreate, and again in temporary disable/enable filter:
void setAutoCompleteAdapter() {
PlacesAutoCompleteAdapter adapter = new PlacesAutoCompleteAdapter(this, R.layout.item_autocomplete_map_search, autoCompleteList);
editTextSearch.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
Hope its help you also.
I found the solution, kinnda tricky but its works
after i looking inside of the source, i found that th treshold variable used as filtering validation, here we just need to set the treshold to maximum int so filtering never perform.
threshold = Integer.MAX_VALUE
or
setThreshold(Integer.MAX_VALUE)

Categories

Resources