【问题标题】:Android updating a spinner based on "Parent" spinner's selection - .notifyDataSetChange() not firing?Android 根据“父”微调器的选择更新微调器 - .notifyDataSetChange() 未触发?
【发布时间】:2011-08-02 03:58:22
【问题描述】:

所以,我有两个微调器,让我们称第一个微调器 Parent (account_type_spinner) 和第二个微调器 Child (account_name_spinner)。请注意以下代码中的 ArrayAdapter 初始化 Child (account_name_spinner),我给它提供了一个我之前在以下代码行 (account_name_array) 之前查询过的帐户名称的字符串数组:

//---define spinner objects as variables, assign adapters and listeners---

    account_type_spinner = (Spinner) findViewById(R.id.account_type_spinner);       
    account_type_adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, account_type_array);
    account_type_adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    account_type_spinner.setAdapter(account_type_adapter);
    account_type_spinner.setOnItemSelectedListener(new SpinnerSelectionListener());

    account_name_spinner = (Spinner) findViewById(R.id.account_name_spinner);      
    account_name_adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, account_name_array);
    account_name_adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    account_name_spinner.setAdapter(account_name_adapter);     

父微调器中的选择会触发我的“SpinnerSelectionListener”,这只是我实现 OnItemSelectedListener 的类。每次在 Parent 微调器中进行选择时,此类显然都会触发,代码如下所示:

public class SpinnerSelectionListener implements OnItemSelectedListener {

    public void onItemSelected(AdapterView<?> parent,
        View view, int pos, long id) {          
        String spinner_selection = parent.getItemAtPosition(pos).toString();

        if(spinner_selection.contentEquals(INCOME)) {               
            //---grab Income type accounts from db and build array---               
            db.open();
            account_name_array = db.getAccounts(INCOME);    
            account_name_adapter.notifyDataSetChanged();

            dr_amount_textview.setVisibility(View.GONE);
            dr_amount.setVisibility(View.GONE);
            cr_amount_textview.setVisibility(View.VISIBLE);
            cr_amount.setVisibility(View.VISIBLE);
            db.close();
        } else {
            //---grab Expense type accounts from db and build array---
            db.open();
            account_name_array = db.getAccounts(EXPENSE);
            account_name_adapter.notifyDataSetChanged();

            cr_amount_textview.setVisibility(View.GONE);
            cr_amount.setVisibility(View.GONE);
            dr_amount_textview.setVisibility(View.VISIBLE);
            dr_amount.setVisibility(View.VISIBLE);
            db.close();
        }
    }

    public void onNothingSelected(AdapterView<?> parent) {
      // Do nothing.
    }
}

只要家长的选择从 INCOME 更改为 EXPENSE 或反之亦然(这是一个会计应用程序),上面的代码应该用 INCOME 或 EXPENSE 帐户更新 Child (account_name_spinner)。应通过“account_name_adapter.notifyDataSetChanged();”来促进 Child 的微调器列表的更新。但是什么都没有发生。

我在 StackOverflow 上进一步研究了这个问题,发现我必须在列表更新之前从我孩子的 ArrayAdapter (account_name_adapter) 中删除 () 或 .remove() 项,但是,当我尝试“account_name_adapter.clear() ;"在通知 ArrayAdapter 之前,我收到一个错误,指出该操作是非法的。任何想法我做错了什么?

【问题讨论】:

    标签: android spinner android-arrayadapter


    【解决方案1】:

    您可以在获得更新后的数组 (account_name_array) 后重新分配适配器

    account_name_adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, account_name_array);
    account_name_adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    account_name_spinner.setAdapter(account_name_adapter);
    

    编辑:您没有向适配器传递引用,因此当您更新数组时,适配器仍然具有相同的数据。调用 .notifyDataSetChanged() 不会用新数组更新适配器。

    【讨论】:

    • 您真的必须创建并重新分配一个新适配器吗?我很惊讶我无法更改数据并通知原始适配器,您知道这是为什么吗?
    • 几天前我也在寻找同样的东西,但只找到了重新分配改编的解决方案。我知道,我也很惊讶……
    • 回答已接受,谢谢你,我永远不会自己想出这个。非常非常惊讶竟然是这样。事实上,我相信我昨天在其他地方看到了这个建议,我完全认为这是错误的。因此,如果您正在查看此答案并认为它是虚假的,那么不幸的是。
    • 我编辑了答案,它可以更好地解释为什么 .notifyDataSetChanged() 不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-19
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多