【问题标题】:2 Spinners and if statements2 Spinners 和 if 语句
【发布时间】:2021-01-10 16:57:39
【问题描述】:

我正在构建一个单位转换应用程序。我需要一个输入和两个微调器。微调器调节当前单位是什么,以及新单位是什么。下面是我的代码。我对如何使用 if 语句来比较两者感到困惑。我一直在尝试使用 .equals("lb"),但由于某种原因它只是返回 false。让我知道我可能哪里出错了。

主代码:

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) {

    }
}

字符串.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>

我现在在我的 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)

【问题讨论】:

    标签: java android if-statement spinner equals


    【解决方案1】:

    编辑:首先,正如我在此答案下方的 cmets 中所说,一旦您从 Spinner1 中选择一个值,您的 onItemSelected 将被调用,并且当您从 @987654325 中选择一个值时再次调用@。每次,texttext2 将是相同的值,因此将它们与不同的值进行比较永远不会成立。你需要另一种方法。

    要做到这一点,你可以不用.setOnItemSelectedListener() 来做到这一点。我将 Button 添加到您的布局中,如下所示:

    <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"/>
    

    在那之后,我在你的MainActivity.class 中删除了spinner1.setOnItemSelectedListener(this)spinner2.setOnItemSelectedListener(this) 并添加了btn.setOnClickListener(),如下所示:

    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();
                        }
                    }
                }
            });
    

    所以现在你甚至不需要你的听众了。检查微调器是否等于 null 如果是,您应该通过通知用户他需要选择任何值来处理它。如果默认情况下将您的值选为第一个,则不需要这样做。现在您可以在此 onClick 方法中创建 switch case 并根据需要显示您的输出。

    无论如何,我对使用 string.contentEquals() 的建议仍然有效。

    这是我的最终代码:

    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();
                        }
                    }
                }
            });
        }
    }
    

    还有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>
    

    您应该使用string.contentEquals() 而不是string.equals()。原因是string.equals() 比较字符串的内容,但它也检查另一个对象是否也是String 的实例。 String.contentEquals() 只比较对象的内容。所以它可以是 CharSequence 或任何类似的东西,String、StringBuilder 等。

    另外,您在onCreate 中还有一个额外的setContentView()

     @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);
    

    来源:

    String#equals()

    String#contentEquals()

    【讨论】:

    • 那还是不行。我已经更新了底部的问题以显示我的 logcat 读数。感谢您在这里提供帮助!
    • 还有一个问题。当您单击 spinner1 中的项目时,将调用 onItemSelected。在那里,您尝试获取 text1 和 text2,它们都是相同的,因为您从同一个父级(在本例中为 spinner1)获取它们。因此,当您检查文本 1 是否等于“lb”且文本 2 是否等于“oz”时,这永远不会是真的,因为它们都是相同的。
    • 对于最后一个错误,你得到了,它是一个空指针。您正在尝试对空值调用 .toString 。所以你的微调器没有选择的选项,所以它可能是空的。我将尝试编辑我的答案并修复此问题,完成后我会在此处标记您。
    • @SethT 那里,我编辑了我的答案,现在你甚至不需要听众。你可以用 spinner.getSelectedItem().toString() 在没有它们的情况下做到这一点。刚刚创建您的 switch case 并显示您的结果。
    • 完美回答。我真的很感激你所做的。我知道我哪里出错了,我想在尝试关注 Youtube 视频后我应得的。我不知道太多代码,所以这非常有用。谢谢!
    【解决方案2】:

    第 1 点: 实际上,您对 SpinnerSpinner2. 都使用相同的 AdapterView.OnItemSelectedListener。因此,当您选择其中任何一个的值时,将触发相同的 onItemSelected() 回调两个微调器。

    第 2 点: onItemSelected() 内的第二个点 texttext2 具有相同的值.. 我猜你虽然 text 将指向 Spinner1 选定的项目,而text2 将指向Spinner2 所选项目;从第 1 点开始,这是错误的。

    所以要解决这个问题:您可以为微调器使用不同的侦听器/回调,或者使用相同的侦听器/回调,但执行一些逻辑来区分哪个微调器触发 onItemSelected() 回调。

    这里我使用id 属性来了解哪个微调器触发onItemSelected()

    我将两个微调器都设为全局字段,以便于访问它们。并添加Toast 以显示微调器的任何更改值。

    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) {
    
        }
    }
    

    【讨论】:

    • spinner2.getSelectedItem().toString()里面的if语句会产生NullPointerException吗?我错了吗?在这种情况下可能不是,但通常与其他适配器一起使用,或者当没有选择默认值时,它只是一个空的 null 值。
    • @SlothCoding 谢谢..如果里面没有数据你是对的..但我们实际上知道有一些数据..as long as the spinner has some data .. there must be selected value
    • 哦,好吧,其实 Spinner 并不知道这一点。谢谢!
    猜你喜欢
    • 2016-03-02
    • 2016-02-29
    • 1970-01-01
    • 1970-01-01
    • 2014-02-15
    • 2013-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多