Reputation: 66
I am building out a Unit Conversion app. I need to have one inputs and 2 spinners. The spinners regulate what the current unit is, and what the new unit will be. Below is my code. I am confused on how to use if statements to compare the two. I have been trying to use .equals("lb"), but it just returns false for some reason. Let me know where I might be going wrong.
Main Code:
package com.stproductions.commonconverter;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Convert From Box
setContentView(R.layout.activity_main);
Spinner spinner1 = findViewById(R.id.spinner1);
ArrayAdapter<CharSequence>adapter1 = ArrayAdapter.createFromResource(this, R.array.fromchoices, android.R.layout.simple_spinner_item);
adapter1.setDropDownViewResource(android.R.layout.simple_spinner_item);
spinner1.setAdapter(adapter1);
spinner1.setOnItemSelectedListener(this);
//Convert To Box
Spinner spinner2 = findViewById(R.id.spinner2);
ArrayAdapter<CharSequence>adapter = ArrayAdapter.createFromResource(this, R.array.choices, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_item);
spinner2.setAdapter(adapter);
spinner2.setOnItemSelectedListener(this);
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String text = parent.getItemAtPosition(position).toString();
String text2 = parent.getItemAtPosition(position).toString();
// View text = parent.findViewById(R.id.spinner1);
// View text2 = parent.findViewById(R.id.spinner2);
// Spinner spinner1 = (Spinner) findViewById(R.id.spinner1);
// Spinner spinner2 = (Spinner) findViewById(R.id.spinner2);
if(text.equals("lb") && text2.equals("oz")){
Toast.makeText(this,"hello", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
}
String.XML:
<resources>
<string name="app_name">Common Converter</string>
<string-array name="choices">
<item>lb</item>
<item>oz</item>
<item>g</item>
<item>kg</item>
<item>ton</item>
<item>mg</item>
</string-array>
<string-array name="fromchoices">
<item>lb</item>
<item>oz</item>
<item>g</item>
<item>kg</item>
<item>ton</item>
<item>mg</item>
</string-array>
</resources>
Activity_Main.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
tools:context=".MainActivity">
<Spinner
android:id="@+id/spinner2"
android:layout_width="97dp"
android:layout_height="59dp"
android:background="#E6E6E6"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.831"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.595" />
<Spinner
android:id="@+id/spinner1"
android:layout_width="97dp"
android:layout_height="59dp"
android:background="#E6E6E6"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.831"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.309" />
</androidx.constraintlayout.widget.ConstraintLayout>
I now get the following in my logcat:
2021-01-06 14:48:00.985 18954-18954/com.stproductions.commonconverter E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.stproductions.commonconverter, PID: 18954
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.view.View.toString()' on a null object reference
at com.stproductions.commonconverter.MainActivity.onItemSelected(MainActivity.java:39)
at android.widget.AdapterView.fireOnSelected(AdapterView.java:957)
at android.widget.AdapterView.dispatchOnItemSelected(AdapterView.java:946)
at android.widget.AdapterView.access$300(AdapterView.java:55)
at android.widget.AdapterView$SelectionNotifier.run(AdapterView.java:910)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Upvotes: 0
Views: 81
Reputation: 1706
EDIT: Firstly, as I said in the comments below this answer, your onItemSelected
will be called once you select a value from Spinner1
and again when you select a value from Spinner2
. Each time, text
and text2
will be the same values, so comparing them there to different values won't ever be true. You need another approach.
To do this, instead of using .setOnItemSelectedListener()
you can do this without that. I added Button to your layout like this:
<Button
android:layout_width="100dp"
android:layout_height="50dp"
android:text="Click"
android:id="@+id/button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.831"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.309"/>
After that in your MainActivity.class
I deleted both spinner1.setOnItemSelectedListener(this)
and spinner2.setOnItemSelectedListener(this)
and added btn.setOnClickListener()
like this:
Button btn = findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (spinner1.getSelectedItem() != null && spinner2.getSelectedItem() != null) {
String first_option = spinner1.getSelectedItem().toString();
String second_option = spinner2.getSelectedItem().toString();
if (first_option.contentEquals(second_option)) {
Toast.makeText(MainActivity.this, "hello", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "sad face", Toast.LENGTH_SHORT).show();
}
}
}
});
So now you don't even need your listeners. There is a check if the spinner is equaled to null if it is you should handle that by informing the user that he needs to select any value. If your value is selected as first by default you don't need to do that. Now you can create switch cases inside this onClick method and show your output as you wish.
Anyway, my recommendation for using string.contentEquals()
still stands.
This is my final code:
MainActivity.class
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Convert From Box
Spinner spinner1 = findViewById(R.id.spinner1);
ArrayAdapter<CharSequence>adapter1 = ArrayAdapter.createFromResource(this, R.array.fromchoices, android.R.layout.simple_spinner_item);
adapter1.setDropDownViewResource(android.R.layout.simple_spinner_item);
spinner1.setAdapter(adapter1);
//Convert To Box
Spinner spinner2 = findViewById(R.id.spinner2);
ArrayAdapter<CharSequence>adapter = ArrayAdapter.createFromResource(this, R.array.choices, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_item);
spinner2.setAdapter(adapter);
Button btn = findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (spinner1.getSelectedItem() != null && spinner2.getSelectedItem() != null) {
String first_option = spinner1.getSelectedItem().toString();
String second_option = spinner2.getSelectedItem().toString();
if (first_option.contentEquals(second_option)) {
Toast.makeText(MainActivity.this, "hello", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "sad face", Toast.LENGTH_SHORT).show();
}
}
}
});
}
}
And activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
tools:context=".MainActivity">
<Spinner
android:id="@+id/spinner2"
android:layout_width="97dp"
android:layout_height="59dp"
android:background="#E6E6E6"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.831"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.595" />
<Spinner
android:id="@+id/spinner1"
android:layout_width="97dp"
android:layout_height="59dp"
android:background="#E6E6E6"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.831"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.309" />
<Button
android:layout_width="100dp"
android:layout_height="50dp"
android:text="Click"
android:id="@+id/button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.831"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.309"/>
</androidx.constraintlayout.widget.ConstraintLayout>
You should use string.contentEquals()
instead of string.equals()
. The reason why is that string.equals()
compares the String's contents but also it checks if the other object is also an instance of a String
. String.contentEquals()
only compares the contents of the objects. So it can be CharSequence or anything similar, String, StringBuilder, etc.
Also you have one extra setContentView()
in onCreate
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Convert From Box
setContentView(R.layout.activity_main); <--- DELETE THIS LINE
Spinner spinner1 = findViewById(R.id.spinner1);
Source:
Upvotes: 1
Reputation: 40898
Point 1: Actually you are using the same AdapterView.OnItemSelectedListener
for both Spinner
& Spinner2
.. So the same onItemSelected()
callback will be triggered when you select value of either of both spinners.
Point 2: The second point text
and text2
inside onItemSelected()
have the same value .. I guess you though that text
will point to Spinner1
selected item, and text2
will point to Spinner2
selected item; and that is wrong as of point 1.
So to solve this: you can either use a different listener/callback for the spinners, or use the same listener/callback but do some logic to differentiate which spinner triggers the onItemSelected()
callback.
Here I am using the id
attribute to know which spinner triggers onItemSelected()
.
I made both spinners as global fields to facilitate accessing them. And put a Toast
to show the spinners' values for any change of any of them.
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
private static final String TAG = "LOG_TAG";
private Spinner mSpinner2;
private Spinner mSpinner1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Convert From Box
setContentView(R.layout.activity_main);
mSpinner1 = findViewById(R.id.spinner1);
ArrayAdapter<CharSequence> adapter1 = ArrayAdapter.createFromResource(this, R.array.fromchoices, android.R.layout.simple_spinner_item);
adapter1.setDropDownViewResource(android.R.layout.simple_spinner_item);
mSpinner1.setAdapter(adapter1);
mSpinner1.setOnItemSelectedListener(this);
//Convert To Box
mSpinner2 = findViewById(R.id.spinner2);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.choices, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_item);
mSpinner2.setAdapter(adapter);
mSpinner2.setOnItemSelectedListener(this);
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String text = "", text2 = "";
if (parent.getId() == R.id.spinner1) {
Log.d(TAG, "onItemSelected: spinner 1");
text = parent.getItemAtPosition(position).toString();
text2 = mSpinner2.getSelectedItem().toString();
} else if (parent.getId() == R.id.spinner2) {
Log.d(TAG, "onItemSelected: spinner 1");
text2 = parent.getItemAtPosition(position).toString();
text = mSpinner1.getSelectedItem().toString();
}
Toast.makeText(this, "Spinner1: " + text + " Spinner2: " + text2, Toast.LENGTH_SHORT).show();
// View text = parent.findViewById(R.id.spinner1);
// View text2 = parent.findViewById(R.id.spinner2);
// Spinner spinner1 = (Spinner) findViewById(R.id.spinner1);
// Spinner spinner2 = (Spinner) findViewById(R.id.spinner2);
if (text.equals("lb") && text2.equals("oz")) {
Toast.makeText(this, "hello", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
}
Upvotes: 0