【问题标题】:My spinner does not display the selected item and doesn't call onItemSelected我的微调器不显示所选项目并且不调用 onItemSelected
【发布时间】:2018-08-06 12:40:11
【问题描述】:

我有一个允许用户选择翻译的 android 微调器。我可以点击微调器,它会显示一个包含可用翻译的列表,但是当我在列表中选择一个项目时,它不会出现在微调器中,也不会调用 onItemSelected 方法。

这里是微调器的 xml 代码:

<Spinner
    android:id="@+id/trans_list"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_toRightOf="@+id/chap_list"
    android:layout_weight="1" />

这里是启动微调器的相关代码。 (编辑)这段代码是从 Fragment 类内部运行的,而不是从我的 MainActivity 类中运行的:

    trans_spinner = v.findViewById(R.id.trans_list);

    ArrayAdapter<String> adapter = new ArrayAdapter<>(v.getContext(), android.R.layout.simple_spinner_dropdown_item, translations);

    trans_spinner.setAdapter(adapter);

    trans_spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            String translation = trans_spinner.getItemAtPosition(trans_spinner.getSelectedItemPosition()).toString();
            Log.d("trans", translation);
            Toast.makeText(view.getContext(), translation, Toast.LENGTH_LONG).show();
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
            Log.d("test", "1");
        }
    });

    trans_spinner.setSelection(1);

当我选择一个项目时,不会调用 onItemSelected() 或 onNothingSelected() 方法。我发现这个页面描述了一个与我的问题非常相似的问题: Android Spinner will not launch OnItemSelected and current selected item is not displayed in Spinner 但是,用户没有针对他们的问题提出明确的解决方案,因此对我没有多大帮助。

我不确定它是否相关,但微调器中的项目取自在线网页,该网页提供 JSON 数据来填充微调器。这似乎有效,因为选项确实出现在微调器列表中。问题是,在选择其中一个时,微调器显示为空,并且侦听器不执行任何操作。

【问题讨论】:

  • 你使用的是片段还是活动??
  • 我正在使用片段

标签: android listener spinner


【解决方案1】:

所以我发现问题实际上是因为我如何获得要放入微调器的字符串列表。如原始帖子中所述,我正在从网页中以 JSON 格式加载字符串值。我正在为此使用 Retrofit2 API。

问题是由于我正在下载这些数据,然后在我的片段的 onCreateView() 方法中初始化微调器。我所做的修复它是我创建了一个初始化微调器的新方法,然后我会从 Retrofit API 使用的 onResponse() 方法调用它。这意味着它在完成下载/填充字符串列表之前不会初始化微调器。

【讨论】:

    【解决方案2】:
    <Spinner
        android:id="@+id/planets_spinner"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
    

    如果您的微调器的可用选项是预先确定的,您可以为它们提供在字符串资源文件中定义的字符串数组:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string-array name="planets_array">
            <item>Mercury</item>
            <item>Venus</item>
            <item>Earth</item>
            <item>Mars</item>
            <item>Jupiter</item>
            <item>Saturn</item>
            <item>Uranus</item>
            <item>Neptune</item>
        </string-array>
    </resources>
    

    对于这样的数组,您可以在 Activity 或 Fragment 中使用以下代码,使用 ArrayAdapter 的实例为微调器提供数组:

    Spinner spinner = (Spinner) findViewById(R.id.spinner);
    // Create an ArrayAdapter using the string array and a default spinner layout
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
            R.array.planets_array, android.R.layout.simple_spinner_item);
    // Specify the layout to use when the list of choices appears
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    // Apply the adapter to the spinner
    spinner.setAdapter(adapter);
    

    当用户从下拉列表中选择一个项目时,Spinner 对象会收到一个 on-item-selected 事件。

    要为微调器定义选择事件处理程序,请实现 AdapterView.OnItemSelectedListener 接口和相应的 onItemSelected() 回调方法。例如,下面是 Activity 中接口的实现:

    公共类 SpinnerActivity 扩展 Activity 实现 OnItemSelectedListener { ...

    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)
    }
    
    public void onNothingSelected(AdapterView<?> parent) {
        // Another interface callback
    }
    

    }

    AdapterView.OnItemSelectedListener 需要 onItemSelected() 和 onNothingSelected() 回调方法。

    然后需要通过调用setOnItemSelectedListener()来指定接口实现:

    Spinner spinner = (Spinner) findViewById(R.id.spinner);
    spinner.setOnItemSelectedListener(this);
    

    如果您使用 Activity 或 Fragment 实现 AdapterView.OnItemSelectedListener 接口(如上面的示例中),则可以将其作为接口实例传递。

    【讨论】:

    • 感谢您的建议,我认为这与我最初的做法非常相似(我没有让我的片段实现 OnItemSelectedListener 接口,而是创建了一个新的侦听器并分配了 onItemSelected 和 onNothingSelected 方法)。我认为值得一试让我的片段实现接口,但是它没有解决问题:/
    【解决方案3】:

    Java 代码

    public class MainActivity extends AppCompatActivity {
    
        Spinner spinner;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            spinner = findViewById(R.id.spinner);
    
            List<String> translations = new ArrayList<>();
            translations.add("string1");
            translations.add("string2");
            translations.add("string3");
            translations.add("string4");
            translations.add("string5");
    
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_dropdown_item, translations);
            spinner.setAdapter(adapter);
    
            spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                    Object getPosition = parent.getItemAtPosition(position);
                    String value = getPosition.toString();
                    Toast.makeText(getActivity(), value, Toast.LENGTH_LONG).show();
                }
    
                @Override
                public void onNothingSelected(AdapterView<?> parent) {
    
                }
            });
        }
    }
    

    XML 代码

    <Spinner
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/spinner">
    </Spinner>
    

    【讨论】:

    • 感谢您的建议,虽然它似乎不起作用:/ 我也用 parent 替换了 getItemAtPosition() 的 trans_spinner 参数,但它也没有任何结果。
    • 什么是翻译?字符串列表?
    • 是的,它是一个字符串列表
    • 我更新了我的答案。这是一个已经过测试的工作示例。
    • 它在我的项目中仍然不起作用。目前唯一的区别是我如何获取字符串列表,并且我的代码是从片段类而不是我的主要活动类运行的。您认为两者中的任何一个都可能是原因吗?
    【解决方案4】:

    在初始化适配器后添加这段代码

    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
    

    并在onItemSelected中获取所选项目

    translations.get(position)
    

    【讨论】:

      猜你喜欢
      • 2012-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多