简体   繁体   English

Android-使用“ instanceof”是唯一确定“ onItemSelected”中从微调器返回的项目类型的方法吗?

[英]Android - Is using 'instanceof' the only way to determine the type of an item returned from a Spinner in “onItemSelected”?

As in the title - 如标题中所示-

Is there any way to determine the type of the item (typically either a String , if adapted from a resource, or a generic Object , if adapted programmatically) obtained from a Spinner in onItemSelected ? 是否有任何方法可以确定从onItemSelected的Spinner获得的项的类型(如果从资源改编,通常是String ,或者如果是通过编程改编,则是通用Object )? In this case, I'm referring to one filled programmatically in Java, but as far as I know, it would be the same for one created from a String resource array. 在这种情况下,我指的是用Java以编程方式填充的代码,但据我所知,对于从String资源数组创建的代码来说,它是相同的。

Obviously, however, we create our Spinner, we know what type everything in it is. 但是,显然,我们创建了Spinner, 我们知道其中的所有内容都是什么类型。 If it's from resources, probably Strings. 如果来自资源,则可能是字符串。 If done programmatically, some kind of Object or possibly View . 如果以编程方式完成,则使用某种Object或可能的View However, the signature for onItemSelected looks like this: 但是, onItemSelected的签名如下所示:

@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
    // actions

    // to get the item, you would usually do something like:
    parent.getItemAtPosition(pos);
}

And obviously, the type we get from this is ? 显然,我们从中得到的类型是? , in other words, a generic Object . ,换句话说就是通用Object

So, if we know exactly what type it is, we can, of course, do this (example shown with an Integer ): 因此,如果我们确切知道它是什么类型,我们当然可以这样做(示例显示为Integer ):

Object itemSelected = parent.getItemAtPosition(pos);

if (itemSelected instanceof Integer) doSomeMath((Integer) itemSelected);

But this doesn't exactly strike me as elegant. 但这并不完全使我感到优雅。 It works, certainly, at least in the simple cases I've given it (like Integer ). 当然,它至少在我给出的简单情况下才有效(例如Integer )。 It might even be useful for handling multiple different types of Spinner all running off the same listener - I haven't actually tried that. 它甚至对于处理全部都在同一个listener Spinner运行的多种不同类型的Spinner可能很有用-我实际上没有尝试过。

But it seems like there should be a way to have the signature simply be something like: 但是似乎应该有一种方法可以使签名简单地像这样:

public void onItemSelected(AdapterView<Integer> parent, View view, int pos, long id)

Is using 'instanceof' the only way to determine the type of an item returned from a Spinner in “onItemSelected”? 使用“ instanceof”是确定“ onItemSelected”中从微调器返回的项目类型的唯一方法吗?

It is not the only way. 这不是唯一的方法。 But it it probably the best way. 但这可能是最好的方法。

Here are some alternatives: 以下是一些替代方案:

if (itemSelected.getClass().getName().equals("java.lang.Integer")) {
     doSomeMath((Integer) itemSelected);
}

if (itemSelected.getClass() == Integer.class) {
     doSomeMath((Integer) itemSelected);
}

try {
    doSomeMath((Integer) itemSelected);
} catch (ClassCastException ex) {
    // squash
}

Notes: 笔记:

  1. None of these alternatives is recommended. 不建议使用这些替代方法。 Seriously. 认真。
  2. The instanceof operator tests for subclasses as well, unlike the first two alternatives. 与前两个替代方案不同, instanceof运算符也对子类进行测试。
  3. The third version will also squash ClassCastException if it is thrown in the doSomeMath method. 如果在doSomeMath方法中抛出第三个版本,它将也挤压ClassCastException
  4. Problems arise with null . null出现问题。 The instanceof operator returns false for null , but all of these alternatives will throw an NPE. instanceof运算符为null返回false,但是所有这些替代方案将抛出NPE。

Unfortunately, your alternative won't work. 不幸的是,您的替代方法无效。 The AdapterView.OnItemSelectedListener interface declares that method's first parameter with that type. AdapterView.OnItemSelectedListener接口使用该类型声明该方法的第一个参数。 The interface is not generic. 该接口不是通用的。

But it seems like there should be a way to have the signature [...] 但似乎应该有一种方法来获得签名[...]

It seems but it can't be done because AdapterView.getItemAtPosition(int) returns Object anyway. 似乎但不能完成,因为AdapterView.getItemAtPosition(int)无论如何都会返回Object ListView or Spinner don't know or care what type of items the adapter contains. ListViewSpinner不知道或不在乎适配器包含什么类型的项目。

Obviously, however, we create our Spinner, we know what type everything in it is. 但是,显然,我们创建了Spinner,我们知道其中的所有内容都是什么类型。

Exactly, since you're the ultimate master of what data you put in the adapter you should be able to cast it safely 确实,由于您是放入适配器的数据的最终掌握者,因此您应该能够安全地对其进行转换

@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
     final int item = (int) parent.getItemAtPosition(pos);
     doSomeMath(item);
}

Instead of checking for an always true condition it would just crash when it encounters unexpected data. 它不会检查始终为真的条件,而只会在遇到意外数据时崩溃。

Get into this mindset: If something happens if it's not supposed to happen the code should throw an exception. 进入这种思维方式:如果某些事情如果不发生,那么代码应该抛出异常。 This gives you a chance to fix any errors instead of never knowing if there's anything wrong. 这使您有机会修复任何错误,而不用不知道是否有任何错误。

Another option would be having the adapter stored in a member variable and accessing it from the listener 另一个选择是将适配器存储在成员变量中,并从侦听器访问它

private MyAdapter adapter;

@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
     final int item = adapter.getItem(pos);
     doSomeMath(item);
}

This assumes your adapter overrides getItem(int) and returns the appropriate type. 假定您的适配器重写getItem(int)并返回适当的类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Android Spinner将不会启动OnItemSelected,并且当前选定的项目不会显示在Spinner中 - Android Spinner will not launch OnItemSelected and current selected item is not displayed in Spinner Java Android Spinner onItemSelected - Java Android Spinner onItemSelected android中微调器的onItemSelected属性 - onItemSelected property of spinner in android Android onItemSelected微调框未激活 - Android onItemSelected Spinner not activating Android Spinner:永远不会调用 onItemSelected - Android Spinner : onItemSelected is never called 什么是访问Android微调器中显示的子项的方法,而不仅仅是等待onItemSelected()事件? - What's the method to access whatever child item is displayed in an Android spinner, instead of just waiting for an onItemSelected() event? 微调框未在API 23中使用onItemSelected方法 - Spinner not using onItemSelected method in API 23 仅更改一项微调器 android 的样式 - Change style of only one item spinner android Android 编程:如何在微调器的 onItemSelected 适配器中永久更改语言 - Android programming: How to make language change permanent in onItemSelected adapter in a spinner 在其他几个方法完成执行后,会触发Spinner的Android OnItemSelected - Android OnItemSelected of a Spinner is triggered after several other methods finish executing
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM