Android Spinner的setOnItemSelectedListener不起作用

4

我在登录过程中动态创建了一个下拉框。我希望能够在单击选项时返回下拉框的值,但似乎并不起作用。

以下是创建下拉框的代码:

public Spinner page_spinner;

protected void onCreate(Bundle savedInstanceState){
...
page_spinner = (Spinner) findViewById(R.id.page_spinner);
...
//MAKE ARRAY HERE
GraphRequest requestPage = GraphRequest.newGraphPathRequest(
    currentAccessToken,
    "/me/accounts",
    new GraphRequest.Callback() {
        @Override
        public void onCompleted(GraphResponse response) {
            JSONArray jsonArray = null;
            try {
                jsonArray = response.getJSONObject().getJSONArray("data");
                for(int i=0; i < jsonArray.length(); i++){
                JSONObject page = jsonArray.getJSONObject(i);
                String pageName = page.getString("name");
                if(!pageName.equals("")) {
                    //Push names into the array
                    pages_array.add(pageName);
                } else {
                    pages_array.clear();
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
});
Bundle pageParameters = new Bundle();
pageParameters.putString("fields", "name,access_token,picture{url}");
requestPage.setParameters(pageParameters);
requestPage.executeAsync();
...
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(StartPage.this, android.R.layout.simple_spinner_item, pages_array);
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); // The drop down view
page_spinner.setAdapter(spinnerArrayAdapter);
spinnerArrayAdapter.notifyDataSetChanged();

然后我在这里尝试使用旋转器:
page_spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        Log.d("***********", "THIS ");
    }
    @Override
    public void onNothingSelected(AdapterView<?> parent) {
        Log.d("***********", "THIS ");
    }
});

我从未收到Log.d的信息,即使我在那里使用了Toast,也没有弹出。不确定为什么会停止,并且我没有收到任何错误信息。
有任何想法吗?

你能否将你的数组初始化和生成代码也添加为示例? - Rajen Raiyarela
@RajenRaiyarela,已添加,但我正在削减注释和多余的代码。 - ntgCleaner
@RajenRaiyarela,我已经整理了代码,这样它就能显示我如何创建数组了。 - ntgCleaner
你展示的代码看起来正确。你能贴出整个活动代码吗? - Chintan Soni
首先,将pages_array.clear()注释掉,因为可能会添加一些名称,然后清除pages_array。其次,在pages_array完全填充或每添加一个新元素时,需要调用spinnerArrayAdapter.notifyDataSetChanged()来重新加载带有新数据的spinner。 - Rajen Raiyarela
显示剩余5条评论
3个回答

3

声明旋转器为全局变量,且不带final关键字。

尝试以下代码:

page_spinner = (Spinner) findViewById(R.id.page_spinner);
...
//MAKE ARRAY HERE
GraphRequest requestPage = GraphRequest.newGraphPathRequest(
    currentAccessToken,
    "/me/accounts",
    new GraphRequest.Callback() {
        @Override
        public void onCompleted(GraphResponse response) {
            JSONArray jsonArray = null;
            try {
                jsonArray = response.getJSONObject().getJSONArray("data");
                for(int i=0; i < jsonArray.length(); i++){
                JSONObject page = jsonArray.getJSONObject(i);
                String pageName = page.getString("name");
                if(!pageName.equals("")) {
                    //Push names into the array
                    pages_array.add(pageName);
                } else {
                    pages_array.clear();
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(StartPage.this, android.R.layout.simple_spinner_item, pages_array);
        spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); // The drop down view
        page_spinner.setAdapter(spinnerArrayAdapter);
        spinnerArrayAdapter.notifyDataSetChanged();
    }
});

谢谢,我刚试了一下,但控制台还是没有任何输出。 - ntgCleaner
Callback之前构建您的Spinner,并在数组完成后在Callback内设置适配器。 - Alberto Crespo
1
你的评论起了作用 - 我把以 ArrayAdapter<String>spinnerArrayAdapter 开头的两行代码放在了 GraphRequest.Callback()onComplete 方法中,在 try{ 行的上方。然后我把 page_spinnerspinnerArrayAdapter 放在了最后一个 catch 语句下面。 - ntgCleaner
如果您不介意更新您的答案以反映代码,我可以接受它作为答案。 - ntgCleaner
1
需要23个小时才能颁发赏金。谢谢! - ntgCleaner

2

您的错误看起来有些正确。您没有通知适配器数据集中的更改。

首先,您的请求是异步执行的。因此,您的代码执行将继续到下一行。所以我猜想,一个空数组(大小为0)被传递给ArrayAdapter<>,然后适配器被设置为Spinner,然后您调用了notifyDataSetChanged()

我认为您应该像下面这样调用spinnerArrayAdapter.notifyDataSetChanged();

    @Override
    public void onCompleted(GraphResponse response) {
        JSONArray jsonArray = null;
        try {
            jsonArray = response.getJSONObject().getJSONArray("data");
            for(int i=0; i < jsonArray.length(); i++){
                JSONObject page = jsonArray.getJSONObject(i);
                String pageName = page.getString("name");
                if(!pageName.equals("")) {
                    //Push names into the array
                    pages_array.add(pageName);
                } else {
                    pages_array.clear();
                }
            }
            spinnerArrayAdapter.notifyDataSetChanged();
    } catch (JSONException e) {
        e.printStackTrace();
    }

谢谢,颁发赏金需要23小时。您需要更多的解释,不过其他三行代码也需要移动。就像Alberto的答案一样。 - ntgCleaner
@ntgCleaner 没问题。你清楚为什么犯错更重要。赏金并不能代表技能..:) 祝编码愉快.. - Chintan Soni

0

我已经测试了您的代码,一切看起来都正确。首先,我尝试在 spinner 中添加 10 个项。一切正常。然后我测试了添加仅包含一个项目的 String List

List<String> spinnerArray = new ArrayList<String>();
        spinnerArray.add("Item 1");

我的OnItemSelectedListener

spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(MainActivity.this, "Selected", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });

但是发生的事情是,之前一切正常的代码在之后不起作用了,因为spinnerArray中只有一个项目。当Activity加载时,会显示Toast,而在选择item时不会调用。你可能也有同样的问题。所以我的建议是优先考虑你的Array,它可能只包含一个item

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接