Java onItemSelectedListener 和 Spinner 不返回任何内容

Posted

技术标签:

【中文标题】Java onItemSelectedListener 和 Spinner 不返回任何内容【英文标题】:Java onItemSelectedListener and Spinner not returning Anything 【发布时间】:2017-11-25 15:03:54 【问题描述】:

我正在构建一个货币转换器(从 API 获取,动态填充列表以创建可用货币,选择两种货币并返回汇率。这似乎是一种通行权)。

我一直试图让 Spinner 工作,但尽管我尽了最大努力,但当我从列表中选择一个值时,我似乎无法让听众做任何事情。当我点击一个值时,日志确实会返回一些内容(见下文),但我不知道这意味着什么,以及为什么它没有返回我想要的 System.out.println("yay") 调用。

D/OpenGLRenderer:endAllActiveAnimators 位于 0xa7040980 (DropDownListView),句柄为 0x95c21270"。

数组适配器正在从我从 API 获得的 ArrayList<string>JSON 对象正确填充微调器列表。根据我在 S.O. 上找到的示例,侦听器代码看起来是正确的。到目前为止。

我想知道这是否是我的代码中的排序问题?或者别的什么。

package com.timlee.currencymate;

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;

    public class MainActivity extends AppCompatActivity 

// public variables
    String uRLResultString = "";
    ArrayList <String> currencies = new ArrayList<String>();
    Spinner currencyOneSpinner;
    Spinner currencyTwoSpinner;

// get data from api
public class DownloadTask extends AsyncTask <String, Void, String> 

    @Override
    protected String doInBackground(String... urls) 
        URL url;
        HttpURLConnection urlConnection = null;

        try 
            url = new URL(urls[0]);
            urlConnection = (HttpURLConnection)url.openConnection();
            InputStream in = urlConnection.getInputStream();
            InputStreamReader reader = new InputStreamReader(in);

            int data = reader.read();

            while (data != -1) 
                char current = (char) data;
                uRLResultString += current;
                data = reader.read();
            

            return uRLResultString;

         catch (MalformedURLException e) 
            e.printStackTrace();
         catch (IOException e) 
            e.printStackTrace();
        
        return null;
    

    @Override
    protected void onPostExecute(String result) 
        super.onPostExecute(result);

        //System.out.println(result);
        //if get current list then run this, else run something else
        getCurrencyList();

    


//gets the list of currecies
public void getCurrencyList () 

    try 

        JSONObject jsonObject = new JSONObject(uRLResultString);
        String base = jsonObject.getString("base");
        String rates = jsonObject.getString("rates");
        currencies.add(base);
        System.out.println(rates);

        JSONObject jSonObj = new JSONObject(rates);

        Iterator<String> keys = jSonObj.keys();

        while (keys.hasNext()) 
            String key = (String)keys.next();
            currencies.add(key);
            if (jSonObj.get(key) instanceof JSONObject) 
            
        

        Collections.sort(currencies, String.CASE_INSENSITIVE_ORDER);

     catch (JSONException e) 
        e.printStackTrace();
    



@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    currencies = new ArrayList<String>();

    String currencyURL = "http://api.fixer.io/latest?base=AUD";
    DownloadTask task = new DownloadTask();
    task.execute(currencyURL);

    // apply Array Adapter and listener
    currencyOneSpinner = (Spinner)findViewById(R.id.spinnerCurrencyOne);
    ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(this,android.R.layout.simple_spinner_item,currencies);
    currencyOneSpinner.setAdapter(arrayAdapter);
    currencyOneSpinner.setOnItemSelectedListener (new OnItemSelectedListener() 

        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) 
            System.out.println("yay");
            return;
        

        @Override
        public void onNothingSelected(AdapterView<?> parent) 
            System.out.println("neyh");
            return;
        
    );


【问题讨论】:

【参考方案1】:

您没有为适配器设置下拉视图。在setOnItemCLickListener上方添加这一行

currencyOneSpinner.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

而且由于您使用的是AsyncTask,因此每次更新列表时不要忘记调用以下行。

arrayAdapter.notifyDataSetChanged();

注意:您必须全局初始化适配器。

【讨论】:

谢谢 Dustblue。解决方案是我需要通知 AsyncTask 中更改的数据集。如果我只应用 arrayadapter 视图更改,问题仍然存在。我还不明白为什么通知调用会影响听众,但我很感激你的额外建议是解决方案。 不客气。它是在更新列表时更新微调器。根据文档,Notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself. 这就是它影响您的听众的原因。并且不要忘记接受我的回答!谢谢。

以上是关于Java onItemSelectedListener 和 Spinner 不返回任何内容的主要内容,如果未能解决你的问题,请参考以下文章

onItemSelectedListener 没有被触发

是否调用了 OnItemSelectedListener.onNothingSelected?

从 OnItemSelectedListener 调用值

试图在android中创建一个spinner.OnItemSelectedListener事件[重复]

如何基于onItemSelectedListener在textview中显示纺织品?

基于多个 onItemSelectedListeners 做一个任务