Reputation: 63
I'm developing a currency exchange app and I'm having some problems with updating my ListView after extracting the rates from an API.
Ignore the flags, I just put whatever files I had to test the solution
On the start of my activity, I am defining:
final ArrayList<ItemData> list = new ArrayList<ItemData>();
final String[] web = {
"EUR", "JPY", "USD", "GBP"
};
final Integer[] imageId = {R.drawable.austria, R.drawable.bangladesh, R.drawable.benin, R.drawable.uk};
private static String _spinnerData;
public static String test;
public static synchronized String getCurrentSpinner(){
if (_spinnerData == null) {
String _spinnerData;
}
return _spinnerData;
}
And onCreate() is defined as:
... not important ...
Spinner spin = (Spinner) findViewById(R.id.spinner_complist);
final SpinnerAdapter adapter1 = new SpinnerAdapter(this,
R.layout.spinner_layout, R.id.txt, list);
spin.setAdapter(adapter1);
spin.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
ItemData item = (ItemData) (parentView.getItemAtPosition(position));
Log.i("item_1", item.getText());
String spinnerData = getCurrentSpinner();
spinnerData = item.getText();
}
I then have a custom Adapter to put the flags+name, where the name is a textview.
Afterwards, I get my conversion rate from an API, through a function getRate() that is working. On the custom adapter, I have overriden the getView method:
@Override
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView = inflater.inflate(R.layout.mylist, null, true);
TextView txtTitle = (TextView) rowView.findViewById(R.id.itemName);
ImageView imageView = (ImageView) rowView.findViewById(R.id.icon);
imageView.setImageResource(imageId[position]);
String currency;
txtTitle.setText(web[position]);
String spinnerData= getCurrentSpinner();
if (spinnerData!=null) {
currency=spinnerData;
getRate(currency, web[position], txtTitle);
}
return rowView;
}
So, in getRate I obtain a String from each row of the ListView and replace it by the value in another coin.
My problem is: If I write getRate("EUR",web[position],txtTitle), everything works as intended.
However, if I put the code as it is, it just doesn't update my ListView. I put a breakpoint and currency is "EUR", so it should be equivalent to what I had by hardcoding the string.
I think that probably the ListView isn't getting properly updated, or the function is making some callback that is replacing my TextViews with the original values.
Any ideas?
Thanks in advance,
Upvotes: 0
Views: 65
Reputation: 196
I think you have some problems with the flow of the data in your Activity.
The getView in the listview should return a view with the populated data from a data source that has the data. I would advice changing to have something like:
Snippet position selected -> call web API to get any data that you need -> when is returned add it to a list of data that is being displayed on the listview -> then call in the adapter of the listview notifyDataSetChanged()
I would recommend this article for more information about using listviews: http://www.vogella.com/tutorials/AndroidListView/article.html
Upvotes: 2
Reputation: 10155
Two things stand out to me.
First, this block:
public static synchronized String getCurrentSpinner(){
if (_spinnerData == null) {
String _spinnerData;
}
return _spinnerData;
}
This doesn't really make sense. It reads "if the static scoped _spinnerData
is null, create another locally scoped String also called _spinnerData
and do nothing with it, then return the statically scoped instance."
And second, this logic:
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
ItemData item = (ItemData) (parentView.getItemAtPosition(position));
Log.i("item_1", item.getText());
String spinnerData = getCurrentSpinner();
spinnerData = item.getText();
}
This reads "create a temporary string called spinnerData
that is initialized with the return value of getCurrentSpinner()
then immediately replace it with the value of item.getText()
then throw the whole thing away (because it's never used thereafter)".
It appears to me you have a misunderstanding in how references work. I think what you are trying to do is save the current spinner selection and use that in your getView()
.
If that's the case, you would do something like this:
private String _spinnerData; // Does not need to be static
// In onItemSelected
ItemData item = (ItemData) (parentView.getItemAtPosition(position));
Log.i("item_1", item.getText());
_spinnerData = item.getText(); // Save the last item selected
// In getView()
// Call this method with the last known spinner selection
getRate(_spinnerData, web[position], txtTitle);
I would have to assume you are new to Java and don't fully understand how references and scope work. Is that a fair assumption? If so, I strongly suggest you take a step back from Android and work on getting more familiar and comfortable with Java before proceeding. Android is complicated enough without having to figure out the language as you go as well.
Hope that helps!
Upvotes: 3