Android spinners: How to write java code for them? - java

I am trying to make a GPA calculator. I have a bunch of spinners in two columns. 7 in each. I have put in an array of strings to be displayed in the drop down list. Now, I want to write code in java for saying if the user selects "four" from the drop down list, then the input should be considered as number 4 later to multiply it with for example if the user chose grade A, then to multiply with 4. How do I do this? I created an array adapter but it's not working. i am getting "Nan" as the answer. I have looked it up and it says Nan is displayed when the number is undefined. Any help would be appreciated. Thank you!
Should I be using some kind of onClickListener like I used for my button? How does the computer know that it has to equate gradepoint to 4 if the user picks grade A?
This is what I did (which obviously is wrong):
if(spinner1.getSelectedItem().equals("A+")) gradepoint1=4.00;
if(spinner1.getSelectedItem().equals("A")) gradepoint1=4.00;
if(spinner1.getSelectedItem().equals("A-")) gradepoint1=3.67;
if(spinner1.getSelectedItem().equals("B+")) gradepoint1=3.33;
if(spinner1.getSelectedItem().equals("B")) gradepoint1=3.00;
if(spinner1.getSelectedItem().equals("B-")) gradepoint1=2.67;
if(spinner1.getSelectedItem().equals("C+")) gradepoint1=2.33;
if(spinner1.getSelectedItem().equals("C")) gradepoint1=2.00;
if(spinner1.getSelectedItem().equals("C-")) gradepoint1=1.67;
if(spinner1.getSelectedItem().equals("D+")) gradepoint1=1.33;
if(spinner1.getSelectedItem().equals("D")) gradepoint1=1.00;
if(spinner1.getSelectedItem().equals("D-")) gradepoint1=0.67;
if(spinner1.getSelectedItem().equals("F")) gradepoint1=0.00;
if(spinner1.getSelectedItem().equals("ABS")) gradepoint1=0.00;

I suggest you do something like this:
Before you're oncreate:
float[] gradeValues = { 4f, 3.67f, 3.33f, 3.00f, 2.67f, 2.33f, 2.00f,1.33f,1.00f,0.67f,0.00f,0.00f};
String [] gradeAlpabetic = {"A+","A","A-","B+","B","B-","C+","C","C-","D+","D","D-","F","ABS"};
Here the first value, 4f, has the position 0, and the next has 1 and so on.
The value "A+" will be at position 0 on the spinner, so this way we know which grade goes with which grade value.
In onViewCreated or OnCreate:
ArrayAdapter<String> gradesArrayAdap = new ArrayAdapter<String>(
getActivity(), R.layout.spinnerlayout, gradeAlphabetic);
gradesSpinner.setAdapter(GradesArrayAdapter);
gradeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
getGrades();
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
}
});
Then you put this outside the onViewCreated/onCreate.
public void getGrades(){
String grade = gradeSpinner.getSelectedItemPosition();
float theGrade = Float.parseFloat(gradeValue(grade);
System.out.println("Your grade in float is: " + theGrade);
}
Hope it helps.

You can have a hashmap of the values and then select the value based on the selected item
HashMap<String, Double> mGrades;
public void test(){
Spinner spinner1 = new Spinner(this);
mGrades = new HashMap<String, Double>();
mGrades.put("A+", 4.00);
mGrades.put("A", 4.00);
//Etc.....
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, mGrades.keySet().toArray(new String[0]));
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner1.setAdapter(adapter);
spinner1.setOnItemSelectedListener(this);
}
public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
// An item was selected. You can retrieve the selected item using
// parent.getItemAtPosition(pos)
Log.d("TAG", String.valueOf(mGrades.get(mGrades.keySet().toArray()[pos])));
}
public void onNothingSelected(AdapterView<?> parent) {
// Another interface callback
}
It may be a bit slower then using some other method, but hey. Its something simple.

Related

How to set selected item for Spinner in Android

In an Android app, I have a SpinnerAdapter that I am using to display expiration years of credit cards. My variable expirationYears contains an array of Strings with years from "2020" to "2029". It was declared as String[] expirationYears = new String[10]; and then with a function I set the ten years as Strings, from current year and then the nine subsequent years after that for a total of ten elements in the array. When I run it, this is what I see:
Everything is perfect so far. The only problem is that when as you see in the image above, 2020 is the year selected by default. That is the first element in the expirationYears array. But I want to set 2021 as default (the second element of the array). This is what my code has:
Spinner spinnerYearCreditCardPayment;
SpinnerAdapter creditCardYearAdapter = new SpinnerAdapter(Payment.this, expirationYears);
creditCardYearAdapter
.setDropDownViewResource(android.R.layout.spinner_dropdown_item);
spinnerYearCreditCardPayment.setAdapter(creditCardYearAdapter);
spinnerYearCreditCardPayment
.setOnItemSelectedListener(new OnItemSelectedListener() {
..........
});
I was expecting to have some property available to define which element I want to show by default. Something like creditCardYearAdapter.setSelectedItem(INDEX_NUMBER). But that property does not exist. Do you know how I could set the default selected item so that it is not the first element of the array (2020) but the second (2021)? Thank you.
UPDATE 1:
Following The_Martian's answer, this was what I did:
spinnerYearCreditCardPayment
.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
arg0.setSelection(1);
cardYear = (String) spinnerYearCreditCardPayment
.getSelectedItem();
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
Now I correctly see the second element of the array ("2021") as the default selection.
The problem is that when I use arg0.setSelection(1);, I choose another year and it does not respond. The selected year remains "2021" even thought I am trying to change the year.
You can do similar to the following. I am just giving you an idea here.
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
parent.setSelection(position + 1);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
Try this snippet
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id)
{
int seleccion=parent.getSelectedItemPosition();
spinner.setSelection(position)
});
}
You can select the spinner item based on value instead of position. Can refer the example below-
String value = "to be selected value";
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.select_state, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mSpinner.setAdapter(adapter);
if (value != null) {
int spinnerPosition = adapter.getPosition(value);
mSpinner.setSelection(spinnerPosition);
}

using spinner in android development

I'm new to android development, I have some experiences on C# windows programming, but also very little. I'm working on an android application which uses spinners. So far, I found a tutorial which make spinner items, and displays spinner text in text view, as you select spinner item. The code lookes like this:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
spinner =(Spinner)findViewById(R.id.sp);
text=(TextView)findViewById(R.id.tv);
ArrayAdapter<CharSequence> adapter =ArrayAdapter.createFromResource(this, R.array.spinnerarray, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new function());
}
public class function implements OnItemSelectedListener {
#Override
public void onItemSelected(AdapterView<?> parent, View arg1, int pos,
long id) {
// TODO Auto-generated method stub
String str=parent.getItemAtPosition(pos).toString();
text.setText(str);
}
I want to make an application, which will calculate some points, with the grade user would choose. Example: spinner will contain grades, such as Negative(1), Positive(2),Good(3), Very Good(4), Excellent(5). I want to achieve, that when an user chooses one grade, lets say very good, that the application will use the grade for very good which is 4, and it would transform it to some points, determined by me ( 1=20, 2=40,3=60,4=80,5=100). The points will be later used in calculation, but I have no idea how to assign points to certain grade. I hope you understand my question and thank you for your help.
I had the same app for windows, there I just used something like: if(veryGood.IsSelected==true){points = 20}, and i want to achieve same effect here.
You need a simple modifications on your function class:
public class function implements OnItemSelectedListener {
private final static int[] grades = new int[]{20,40,60,80,100}; //change in whatever you want. The length of the array must be the same of the adapter, or an ArrayIndexOutOfBoundException may be throwed.
#Override
public void onItemSelected(AdapterView<?> parent, View arg1, int pos, long id) {
text.setText(grades[pos] + " points!");
}
}
PS: in Java is a good practice to use upper case initial on class names e.g. Function instead of function.

Android - Defining value displayed within spinner (different from selected value)

I have a spinner which contains dynamic data which is displayed over 2 lines. What I require help with is dislaying only part of the spinners value (ItemArrayName[i]) within the spinner text box.
To calrify in the popup when the spinner is clicked, I require the full text, however when the item has been select I only require the item name.
e.g.
Within the App:
Item Name
Within the spinner selection pop out:
Item Name
Atk = 10, Def = 10
Java Code:
ArrayList<String> ItemArrayList = new ArrayList<String>();
for(int i = 0; i < ItemArrayName.length; i++)
{
ItemArrayList.add(ItemArrayName[i] + "\nAtk = " + String.valueOf(ItemArrayAtk[i]) + ", Def = " + String.valueOf(ItemArrayDef[i]));
}
Spinner spnItem = (Spinner) view.findViewById(R.id.UseItem);
ArrayAdapter<String> adpItem = new ArrayAdapter<String> (context, R.layout.spinnerrow, ItemArrayList);
spnItem.setAdapter(adpItem);
spnItem.setOnItemSelectedListener(new OnItemSelectedListener()
{
public void onItemSelected(AdapterView<?> parent, View view, int position, long arg3)
{
//String city = "The item is " + parent.getItemAtPosition(position).toString();
//Toast.makeText(parent.getContext(), city, Toast.LENGTH_LONG).show();
}
public void onNothingSelected(AdapterView<?> arg0)
{
// TODO Auto-generated method stub
}
});
Thanks in advance
How about using a Hashtable to map what you display in the spinner to your more detailed popup string?
EDIT:
Here's a primitive and possibly non compiling modification to your code using a hashtable as described:
// EDIT #1: Create a hashtable to lookup stuff:
final Hashtable<String, String> vals = new Hashtable<String, String>();
for(int i = 0; i < ItemArrayName.length; i++)
{
vals.put(ItemArrayName[i], ItemArrayName[i] + "\nAtk = " + String.valueOf(ItemArrayAtk[i]) + ", Def = " + String.valueOf(ItemArrayDef[i]));
}
Spinner spnItem = (Spinner) view.findViewById(R.id.UseItem);
// EDIT #2: Extract the array of hash keys to show in your list:
ArrayAdapter<String> adpItem = new ArrayAdapter<String> context, R.layout.spinnerrow, vals.keySet().toArray(new String[vals.size()]));
spnItem.setAdapter(adpItem);
spnItem.setOnItemSelectedListener(new OnItemSelectedListener()
{
public void onItemSelected(AdapterView<?> parent, View view, int position, long arg3)
{
// EDIT #3: retrieve the full string from the hashtable using "get":
String city = "The item is " + vals.get(parent.getItemAtPosition(position).toString());
//Toast.makeText(parent.getContext(), city, Toast.LENGTH_LONG).show();
}
public void onNothingSelected(AdapterView<?> arg0)
{
// TODO Auto-generated method stub
}
});
Try mapping your short text to your long text.
HashMap<String,String> itemValues = new HashMap<String,String>();
itemValues.add("short text","the full long text that pops up when item is selected");
String longTextToDisplay = itemValues.get(currentSelectedShortText);
Of course this is a simplified example and this could be made more flexible, but this is the basic idea. You're just saying "this short text goes with this long text."
Everyone makes this much harder than it has to be. If the data is displayed in the spinner already, you can grab it from there without having to refer to the backing data.
Assuming you have a LinearLayout containing the two textviews (call them tv1 and tv2) as your row layout for the spinner, and you want the value of tv2, you could do this:
public void onItemSelected(AdapterView<?> parent, View view, int position, long arg3)
{
TextView tvResult = (TextView) view.findViewById(r.id.tv2);
String city = tvResult.getText().toString();
}
EDIT
I misunderstood your question... that I know of there is no way to make the closed spinner box display text different from the actual selection within the spinner using an ArrayAdapter. If there is, I'd be interested in seeing/reading about it.
I can think of a way to do it with a CursorAdapter, but as I said above, I can't think of any way to manage it for an ArrayAdapter.
The one option I can think of would be to find the spinner class in the android source, copy it out and modify it to make your own spinner class that is capable of such a function.

Pass String variables by reference to setOnItemSelectedListener of multiple Spinners

OK, I've read around and see that Java only passes by value, not by reference so I don't know how to accomplish this.
I've 6 Spinners in an Android Activity that are populated with different SQLite queries.
The code to populate each Spinner and set the OnItemSelectedListener is very similiar so I was hoping to refactor to one method and call it 6 times with each Spinner ID and Sqlite query.
How do I get the Spinner onItemSelectedListener to change the right instance member on each different Spinner?
public void fillSpinner(String spinner_name, final String field_name) {
// This finds the Spinner ID passed into the method with spinner_name
// from the Resources file. e.g. spinner1
int resID = getResources().getIdentifier(spinner_name, "id",
getPackageName());
Spinner s = (Spinner) findViewById(resID);
final Cursor cMonth;
// This gets the data to populate the spinner, e.g. if field_name was
// strength = SELECT _id, strength FROM cigars GROUP BY strength
cMonth = dbHelper.fetchSpinnerFilters(field_name);
startManagingCursor(cMonth);
String[] from = new String[] { field_name };
int[] to = new int[] { android.R.id.text1 };
SimpleCursorAdapter months = new SimpleCursorAdapter(this,
android.R.layout.simple_spinner_item, cMonth, from, to);
months.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
s.setAdapter(months);
// This is setting the Spinner Item Selected Listener Callback, where
// all the problems happen
s.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
Cursor theCursor = (Cursor) parent.getSelectedItem();
// This is the problem area.
object_reference_to_clas_member_of_field_name = theCursor
.getString(theCursor.getColumnIndex(field_name));
}
public void onNothingSelected(AdapterView<?> parent) {
// showToast("Spinner1: unselected");
}
});
}
You call this method like this fillSpinner("spinner1","strength");.
It finds the spinner with id spinner1 and queries the database for the strength field. field_name, which is strength in this example had to be declared a final variable to be used in the onItemSelectedListener or I'd get the error Cannot refer to a non-final variable field_name inside an inner class defined in a different method.
But how do I get the onItemSelectedListener to change the value of a different instance member when each different Spinner is used? This is the all important line of code:
object_reference_to_clas_member_of_field_name = theCursor .getString(theCursor.getColumnIndex(field_name));
I can't use a final String as the variable will obviously change when the user selects a different value. I've read around a good bit and am stumped to a solution. I can just copy and paste this code 6 times and forget about refactoring but I'd really like to know the elegant solution. Post a comment if you don't understand my question, I'm not sure if I explaned myself well.
You can do it, by passing additional class as parameter of fillSpinner method:
A. Create interface
public interface OnSpinnerValueSelected {
void onValueSelected(String selectedValue);
}
B. Change your method a bit:
public void fillSpinner(String spinner_name, final String field_name,
final OnSpinnerValueSelected valueChangeListener) {
// Prepare spinner
s.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
Cursor theCursor = (Cursor) parent.getSelectedItem();
valueChangeListener.onValueSelected(theCursor
.getString(theCursor.getColumnIndex(field_name)));
}
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
C. provide listener:
fillSpinner("spinner1","strength", new OnSpinnerValueSelected() {
public void onValueSelected(String selectedValue) {
yourObject.setField(selectedValue);
}
});
Refactor your listener to a new "class". Initialize with the right arguments/instances as required so that the repeated "code" is reusuable.
Right, this is how I managed it but I'm still open to new suggestions for an accepted answer and I also created a bounty.
I didn't create a new class like panzerschreck suggested so I'm posting this as a new answer to my own question. Bit of a hack but I just created an if..then..else statement in the listener to check what spinner was selected and then set a different instance member.
s.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
Cursor theCursor = (Cursor) parent.getSelectedItem();
if (field_name.equalsIgnoreCase("strength")) {
strength=theCursor.getString(theCursor.getColumnIndex(field_name));
} else if (field_name.equalsIgnoreCase("ring")) {
ring_gauge=theCursor.getString(theCursor.getColumnIndex(field_name));
} else if (field_name.equalsIgnoreCase("country")) {
country=theCursor.getString(theCursor.getColumnIndex(field_name));
} else if (field_name.equalsIgnoreCase("wrapper")) {
wrapper=theCursor.getString(theCursor.getColumnIndex(field_name));
} else if (field_name.equalsIgnoreCase("length")) {
length=theCursor.getString(theCursor.getColumnIndex(field_name));
} else if (field_name.equalsIgnoreCase("price")) {
price=theCursor.getString(theCursor.getColumnIndex(field_name));
}
// showToast(category);
}
public void onNothingSelected(AdapterView<?> parent) {
// showToast("Spinner2: unselected");
}
});
Here are the class members
private String strength,ring_gauge,country,wrapper,length,price;
Bit of hack but without Java allowing objects to be really passed by reference, it's all I could do.

Android 2.2 SDK - Create Spinner from Map?

Basically, I want to associate a "selected" option with an id, so instead of doing this (my current way):
Vector spinnerList = new Vector();
spinnerList.addElement("No");
spinnerList.addElement("Yes");
I'd be doing something like this (the Hashtable/Vector is just for Blackberry compatability):
String id = "3";
Hashtable spinnerMap = new Hashtable();
spinnerMap.put(id, "No");
spinnerMap.put(id, "Yes");
Currently, a selected "option" from the spinner prints out 0 or 1 (based on the "No", "Yes"). So, my question is, if I'm setting the spinners programatically from a map whose values I don't know (I just know ids), how do I do this?
Spinner spinner = new Spinner(this);
ArrayAdapter spinnerArrayAdapter = new ArrayAdapter(this,
android.R.layout.simple_spinner_dropdown_item, spinnerList);
spinner.setAdapter(spinnerArrayAdapter);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
System.out.println("Selected: " + arg2);
}
public void onNothingSelected(AdapterView<?> arg0) {
System.out.println("Nothing selected: " + arg0);
}
});
Your question is not very clear. What exactly do you want to accomplish?
If you just want to display different data than a simple list of strings I think you should consider creating a custom adapter.
Reverse your map, and you can do an easy lookup of the integer id based on the string returned.
int id = spinnerMap.get(spinner.getSelectedItem());

Categories

Resources