I have a custom spinner (customized for formatting). It works fine and shows the result of the selected array item. The string array with my data is called mydata[].
I want to do something with that result - I've tried hours of changes but, it seems I don't know what the container is for the selected result - it just displays automatically. The mNumber refers to a case select in a class (it's result is based on what's passed into-it).
My question(s) - refer to the * WHAT DO I USE HERE * shown in the code's last line:
1. What is the container for the result?
2. How to access and syntax it?
Here's the code:
Thank you!
**[declared in onCreate]**
Spinner spinner = (Spinner) findViewById(R.id.Spinner01);
MySpinnerAdapter adapter = new MySpinnerAdapter(this, R.layout.mspinner, R.id.text,mydata);
spinner.setAdapter(adapter);
**[declared outside of onCreate]**
#SuppressWarnings("unchecked")
private class MySpinnerAdapter extends ArrayAdapter{
public MySpinnerAdapter(Context context, int resource, int textViewResourceId, String[] objects) {
super(context, resource, textViewResourceId, objects);
final TextView woof =(TextView)findViewById(R.id.TextView07);
woof.setText(String.valueOf(dogday.mNumber(*** WHAT DO I USE HERE ? ***)));
}
}
EDITED - FOR MY RESPONSE TO COMMONSWARE (too many characters for a comment box).
Thanks. You know the result that gets displayed in a spinner (by default) when something's selected - that's the piece of data I need. I want to use it as an argument for a call.
The user selects something in the spinner - The selected item will be used to make some choices in the class method (dogDay), which takes a data argument for mNumber(data) and returns a result (just like a function).
I want to do some math calcs with the result. First, I want to display what's coming back (for now) so, I'm using the dogDay.mNumber(data) as an argument for woof.text.
My question is this, How to get the piece of data (the thing the user selected in the Spinner)? How did the spinner know what to display for my selection - that's what I want? I tried using something like getSelectedItem (or whatever the it was - I can't remember just now) but, it crashes.
Is their an easier way to custom format a spinner? (and get the data) I searched hi and low for info and found only one applicable to android 1.5/later (I want a spinner with all black background and red text - I can do it via the way shown in my code using a the custom layout).
Thanks - I got a bit long winded!
EDITED - with full code
Here's a full code with the custom spinner and the call you suggested. As I mentioned, I already tried it - it only shows the first item in the list - never the selected one. I use the result of getSelectedItem as an argument for the string... I tried it from both within and outside the adapter...
package com.bt.junk;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
public class MyMaincode extends Activity {
private static String mydata[] = {"one", "two", "three"};
int poop;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// DECLARATIONS ------------------------------------------------
Spinner spinner = (Spinner) findViewById(R.id.Spinner01);
MySpinnerAdapter adapter = new MySpinnerAdapter(
this,R.layout.custom_spinner_row,R.id.text, mydata );
spinner.setAdapter( adapter );
poop = spinner.getSelectedItemPosition();
}//end onCreate ********************************************
// METHODS, CLASSES, etc ---------------------------------------
#SuppressWarnings("unchecked") //<-- I added that
private class MySpinnerAdapter extends ArrayAdapter{
public MySpinnerAdapter(Context context, int resource,
int textViewResourceId, String[] objects) {
super(context, resource, textViewResourceId, objects);
final TextView sayWhat = (TextView) findViewById(
R.id.TextView01);
sayWhat.setText(String.valueOf(mydata[poop]));
}//end MySpinnerAdapter
}//end class MySpinnerAdapter
}//end activity
Your question makes little sense to me. I am assuming that "I want to do something with that result" means "I want to find out the selected item's position in the array". If that assumption is correct, you can get the selected position for a Spinner by calling getSelectedItemPosition(). This will be 0 when the Spinner first appears, unless you change the position yourself.
Your code is also very strange, IMHO. The constructor of an ArrayAdapter should not be attempting to manipulate a widget.
Related
New to Android, I got a simple application with spinners and associated ArrayAdapters working: when things get selected, I seem to be able and trigger some calculations. I am then saving the current selected item.
At some point, I retrieve the saved value, and want to position the spinner at that value: basically setPosition() the spinner to that object.
I have found lots of tutorials with the same format I have: use the getPosition() on the ArrayAdapter, and pass in the object you are looking for... Trouble is, it keeps returning -1 (not found).
Debugging, I have verified that the object I pass is not null, and so is the ArrayAdapter, and also the ArrayAdapter getCount returns me the items it should have (so it's not empty).
I'm at loss. Appreciate any... pointers? :-)
/* ArrayAdapter class looks like this*/
public class MyAdapter extends ArrayAdapter<MyClass> {
// Constructor
MyAdapter(#NonNull Context context, int resource, #NonNull List<MyClass> objects) {
super(context, resource, objects);
}
}
/* Fragment looks like this*/
final MyAdapter mAdapter = new MyAdapter(
requireActivity(),
android.R.layout.simple_spinner_item,
objects);
Spinner mySpinner = fragment_view.findViewById(R.id.my_spinner);
mySpinner.setAdapter(mAdapter);
// assume I have one "object" of MyClass,
// and want to search for it in "MyAdapter"
int spinnerPosition = mAdapter.getPosition(objectToBeFound); // returns -1
mySpinner.setSelection(spinnerPosition);
Adapter internally works with List
public int getPosition(#Nullable T item) {
return mObjects.indexOf(item);
}
so getPosition internally depends upon List#indexOf(T) and which relies on equals method
(o==null ? get(i)==null : o.equals(get(i)))
so you are getting -1 because you haven't implemented equals and hashcode method properly in MyClass so implement both methods and you will be able to get the precise index.
Referene:
Use Auto Generate
difference between equals() and hashCode()
I have a ListView and I can reorder items, but every time I exit from the app and start it again the order goes back to default. I'd appreciate if someone can give me answer and maybe a little snippet of how I can do that.
Example: I have two items and two links. Google and Yahoo. I use drag and drop and ArrayList with that. Everything is fine except I don't know how to save the new order.
I don't know if there is some other way to reorder those items.
I use CWAC-TOUCHLIST to do this.
Here is how far I have got:
private static String[] items={"Google", "Yahoo"};
private static String[] links={"http://google.com", "http://yahoo.com"};
private IconicAdapter adapter=null;
private IconicAdapter1 adapter2=null;
ArrayList<String> array= new ArrayList<String>(Arrays.asList(items));
private ArrayList<String> array2=
new ArrayList<String>(Arrays.asList(links));
/** Called when the activity is first created. **/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TouchListView tlv=(TouchListView)getListView();
adapter=new IconicAdapter();
adapter2=new IconicAdapter1();
setListAdapter(adapter);
setListAdapter(adapter2);
tlv.setOnItemClickListener(itemclick);
tlv.setDropListener(onDrop);
}
private TouchListView.DropListener onDrop =
new TouchListView.DropListener() {
#Override
public void drop(int from, int to) {
String item=(String) adapter.getItem(from);
adapter.remove(item);
adapter.insert(item, to);
String link=(String) adapter2.getItem(from);
adapter2.remove(link);
adapter2.insert(link, to);
}
};
private TouchListView.OnItemClickListener itemclick =
new TouchListView.OnItemClickListener(){
public void onItemClick(AdapterView<?> parent, View view,
int from, long id) {
String item = adapter.getItem(from);
Toast.makeText(getBaseContext(), "you pick: "+item,
Toast.LENGTH_SHORT).show();
String link = adapter2.getItem(from);
Intent showContent = new Intent(getApplicationContext(),
Web.class);
showContent.setData(Uri.parse(link));
startActivity(showContent);
}
};
Is there a smarter way to do it?
You have to save the lists with their order either to a file or a DB.
When the application starts you have to initialize the ListViews from the saved lists.
When you drag & drop an item, you have to save the changes.
The method you need to change :
Your drop method should, in addition to what it already does, store the changes in a file or a DB.
Instead of the arrays that you pass in the IconicAdapter and IconicAdapter2 constructors (array & array2), you should pass the saved arrays.
You can read in many places how to store data to a file or a SQLite DB. For example, you can find a good tutorial for SQLite here - http://www.vogella.com/articles/AndroidSQLite/article.html#android_requisites (only the first four sections are relevant, since you don't have to use a ContentProvider).
If you choose to use a DB, you can create a table that contains the following columns : item, link & order. In the drop method you'll have to update the order column of all the rows whose order is between from and to (or if the lists are not too big, you can simply update all the rows and set the order to be the index in the array that holds the list).
When you load the table from the DB you should order it by the order column.
I've been playing around with ArrayAdapters and I've reached a point where I'm getting different results from two almost identical ArrayLists + ArrayAdapter combinations.
The first one:
An ArrayList of 'Restaurant' objects, an ArrayAdapter that uses this ArrayList and a ListView that binds this ArrayAdapter.
private ArrayList<Restaurant> model = new ArrayList<Restaurant>();
private ArrayAdapter<Restaurant> restaurantAdapter = null;
...
public void onCreate(Bundle savedInstanceState){
...
restaurantAdapter = ArrayAdapter<Restaurant>(this, android.R.layout.simple_list_item_1, model);
...
listView.setAdapter(restaurantAdapter);
...
}
The second one:
An ArrayList of String objects, an ArrayAdapter that uses this ArrayList and a AutoCompleteTextView that binds this ArrayAdatper.
private ArrayList<String> prevAddressList = new ArrayList<String>();
private ArrayAdapter<String> addListAdapter = null;
...
public void onCreate(Bundle savedInstanceState){
...
addListAdapter = ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, prevAdddressList);
...
autoCompleteField.setAdapter(addListAdapter);
...
}
I have a save button, on click, I'm creating a restaurant object with a name and an address and adding it to the first adapter, additionally, I want to create a list of previously used address so they are "auto completed" next time they are typing it, so I'm taking the text, and adding it to the second adapter.
...onSave = new View.OnClickListener(){
...
restaurantAdapter.add(r); //r is a Restaurant object.
addListAdapter.add(autoCompleteField.getText().toString());
...
}
Now, everything is working properly. I get the Restaurants displayed in a ListView. The AutoComplete is working as expected.... but I noticed something when I was checking the values while debugging:
The actual ArrayLists, model (Restaurant) is getting updated after adding an object to the adapter , but prevAddressList (String) is not.
Unless, I set the AutoCompleteTextField empty.... then, the prevAddressList gets updated after adding something to the second adapter.
Already tried using notifyDataSetChanged(), but it makes no difference (and it is set to true on every adapter by default anyway).
Other behavior that differs between the two adapters is that in the first one (Restaurant), values are going to the mObjects field, while in the second one (String) they are going to mOriginalValues instead.
I'm completely stomped. The only difference between those two adapters is that one is type "Restaurant" and the other is type "String".
Any ideas? Maybe I'm missing something very obvious? Let me know if you need the full code.
thanks
Instead of adding it to the adapter, try adding the object to your list and then calling notifyDataSetChanged on your adapter. The adapter should pick up your changes and your list of course will have the object you just added.
For anyone coming here from google:
Unable to modify ArrayAdapter in ListView: UnsupportedOperationException
This might explain the behavior, although I have to test it myself.
I want to populate a spinner with some values from a List
The list is populated with objects
ArrayAdapter<PersonDetails> toStopAdapter = new ArrayAdapter<PersonDetails>(MoreTicketSalesActivity.this, R.layout.generic_spinneritem,
R.id.spinner_item_name, personDetails);
Spinner.setAdapter(toStopAdapter);
My PersonDetails class looks like this
private int id;
private int index;
private String name;
At the moment when i set the adapter the personDetails is full with data
But on my spinner is displayed some strange text "com.project.person ..."
What i do wrong?
Thanks
You're using a simple display for each element of the spinner. What does 'generic_spinneritem' look like?
The simple answer is to make sure your PersonDetails class overrides toString and returns the name (or whatever you want). Right now its showing a class name.
For more complicated row display, you'll need to create a custom adapter and override getView.
please guide me with this program. Why do we need to use an array adapter to show the list? What is this "adapter", and can we display things directly in the ListView, without an adapter? Like, can we set setListAdapter(names) instead of setListAdapter(adapter);? Thanks.
Here is the code:
import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
public class Episode7 extends ListActivity {
String[] names = {
"Elliot","Geoffrey","Samuel","Harvey","Ian","Nina","Jessica",
"John","Kathleen","Keith","Laura","Lloyd"
};
/** Called when the activity is first created. */
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Create an ArrayAdapter that will contain all list items
ArrayAdapter<String> adapter;
/* Assign the name array to that adapter and
also choose a simple layout for the list items */
adapter = new ArrayAdapter<String>(
this,
android.R.layout.simple_list_item_1,
names);
// Assign the adapter to this ListActivity
setListAdapter(adapter);
}
}
From the android API reference,
An Adapter object acts as a bridge between an AdapterView and the underlying data for that view. The Adapter provides access to the data items. The Adapter is also responsible for making a View for each item in the data set.
It basically a set of interfaces that determine how the data will be handled by the list. You can use different pre-made adapter classes in your lists or create your own if you want to present custom data.
Take a look at this page in the Dev Guide: http://developer.android.com/guide/topics/ui/binding.html
Lars Vogel has a nice tutorial also: http://www.vogella.de/articles/AndroidListView/article.html
The Adapter acts as both a container for the information you want to display, and allows you to change how it is displayed by over-riding the getView() method of the adapter. Normally, by default, the adapter will call the toString() method of the Object used to create the Adapter and set the text in the TextView that is referenced in the layout provided by android.R.layout.simple_list_item_1... but by over-riding the adapter's getView(), you can have a more complicated layout display for the list.
To answer the initial question... you must use an adapter with a ListView.
This is how I do it and it works for me:
import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class ListViewDemo extends Activity {
// --------- Create your string array, adapter and ListView
String[] items = {"Cars", "Money","Vacation","Electronics",
"Shoes","Jewelry", "Buku bucks","Cash","Ham","Swag","Straight Cash","Homies","Roll Dawgs","Nate Dogg","Wiz Khalifa","Mac Miller","Chitty Bang",
"Sam Adams","Technine","Kanye West","Rims","Escalade","Spreewells","Chrome Rims","24's",
"Lebron James","Dwayne Wade","Andre Iguodala","Allen Iverson","Jodi Meeks",
"Levoy Allen","Mo Williams","Eric Snow","Alien Iverson","Laptop","Phone","Tablet"};
ArrayAdapter<String> adapter;
ListView cashList;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
cashList = new ListView(this);
// create the array adapter<String>(context, layout, array)
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, items);
// add the adapter to the list
cashList.setAdapter(adapter);
// set the list as the content view
setContentView(cashList);
}
}