Seth T
Seth T

Reputation: 66

2 Spinners and if statements

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

Answers (2)

SlothCoding
SlothCoding

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:

String#equals()

String#contentEquals()

Upvotes: 1

Zain
Zain

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

Related Questions