自定义 ListView 未更新

Custom ListView not getting updated

我正在开发一个货币兑换应用程序,但在从 API 中提取汇率后更新我的 ListView 时遇到了一些问题。

忽略标志,我只是把我必须的任何文件都用来测试解决方案

在我的 activity 开始时,我定义:

    final ArrayList<ItemData> list = new ArrayList<ItemData>();
    final String[] web = {
            "EUR", "JPY", "USD", "GBP"
    };
    final Integer[] imageId = {R.drawable.austria, R.drawable.bangladesh, R.drawable.benin, R.drawable.uk};
    private static String _spinnerData;
    public static String test;

    public static synchronized String getCurrentSpinner(){
        if (_spinnerData == null) {
String _spinnerData;
        }
        return _spinnerData;
    }

并且 onCreate() 定义为:

... not important ... 

  Spinner spin = (Spinner) findViewById(R.id.spinner_complist);
        final SpinnerAdapter adapter1 = new SpinnerAdapter(this,
                R.layout.spinner_layout, R.id.txt, list);
        spin.setAdapter(adapter1);


        spin.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
                ItemData item = (ItemData) (parentView.getItemAtPosition(position));
                Log.i("item_1", item.getText());
                String spinnerData = getCurrentSpinner();
                spinnerData = item.getText();
            }

然后我有一个自定义适配器来放置标志+名称,其中名称是一个文本视图。

之后,我通过正在运行的函数 getRate() 从 API 获得我的转化率。 在自定义适配器上,我重写了 getView 方法:

 @Override
        public View getView(int position, View view, ViewGroup parent) {
            LayoutInflater inflater = context.getLayoutInflater();
            View rowView = inflater.inflate(R.layout.mylist, null, true);
            TextView txtTitle = (TextView) rowView.findViewById(R.id.itemName);

            ImageView imageView = (ImageView) rowView.findViewById(R.id.icon);
            imageView.setImageResource(imageId[position]);

            String currency;
            txtTitle.setText(web[position]);
            String spinnerData= getCurrentSpinner();
            if (spinnerData!=null) {


                currency=spinnerData;
                getRate(currency, web[position], txtTitle);

            }

            return rowView;
        }

因此,在 getRate 中,我从 ListView 的每一行获取一个字符串,并将其替换为另一个硬币中的值。

我的问题是:如果我写 getRate("EUR",web[position],txtTitle),一切都会按预期进行。

但是,如果我按原样放置代码,它不会更新我的 ListView。我放了一个断点,货币是 "EUR",所以它应该等同于我通过硬编码字符串得到的结果。

我认为可能是 ListView 没有得到正确更新,或者函数正在执行一些回调,用原始值替换我的 TextView。

有什么想法吗?

提前致谢,

我认为您的 Activity 中的数据流存在一些问题。

列表视图中的 getView 应该 return 一个视图,其中包含来自具有数据的数据源的填充数据。 我建议更改为:

已选择代码段位置 -> 调用网络 API 以获取您需要的任何数据 -> returned 何时将其添加到列表视图上显示的数据列表中 ->然后在列表视图的适配器中调用 notifyDataSetChanged()

我推荐这篇文章以获取有关使用列表视图的更多信息:http://www.vogella.com/tutorials/AndroidListView/article.html

有两件事让我印象深刻。

首先,这个区块:

public static synchronized String getCurrentSpinner(){
    if (_spinnerData == null) {
        String _spinnerData;
    }
    return _spinnerData;
}

这真的没有意义。它显示为 "if the static scoped _spinnerData is null, create another locally scoped String also called _spinnerData and do nothing with it, then return the statically scoped instance."

其次,这个逻辑:

public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
    ItemData item = (ItemData) (parentView.getItemAtPosition(position));
    Log.i("item_1", item.getText());
    String spinnerData = getCurrentSpinner();
    spinnerData = item.getText();
}

这表示 "create a temporary string called spinnerData that is initialized with the return value of getCurrentSpinner() then immediately replace it with the value of item.getText() then throw the whole thing away (because it's never used thereafter)"。

在我看来,您对引用的工作方式有误解。我 认为 你想要做的是保存当前的微调器选择并在你的 getView().

中使用它

如果是这样的话,你会这样做:

private String _spinnerData; // Does not need to be static

// In onItemSelected
ItemData item = (ItemData) (parentView.getItemAtPosition(position));
Log.i("item_1", item.getText());
_spinnerData = item.getText(); // Save the last item selected

// In getView()
// Call this method with the last known spinner selection
getRate(_spinnerData, web[position], txtTitle);

我不得不假设您是 Java 的新手,并不完全理解引用和作用域的工作原理。这是一个公平的假设吗?如果是这样,我强烈建议您从 Android 退后一步,在继续之前努力更加熟悉和熟悉 Java。 Android 已经够复杂了,你也不必弄清楚语言。

希望对您有所帮助!