首页 > 解决方案 > 在 searchView 中找不到新添加的股票

问题描述

所以这不是我得到的错误或任何东西。这是一个我很难做到的实现。

我制作了一个股票应用程序,您可以在其中从 API 搜索股票并将它们添加到 recyclerView。我还实现了一个 searchView 来查找我的 recyclerView 列表中的任何特定库存。

但是,这是我的问题:假设我打开了应用程序并从 API 向列表中添加了一个新股票。它将股票完美地添加到列表中。但是,当我去 searchView 查找我刚刚添加的相同股票时,我在 searchView 列表中找不到它。事实上,某些股票也从 recyclerView 列表中删除(在我进入 searchView 之前它完全存在)。当我重新启动应用程序时,库存再次出现在 recyclerView 列表中,这一次我可以从 searchView 列表中访问它。这只是正在发生的一件奇怪的事情。

仅当我尝试查找刚刚添加到列表中的股票并想立即在 searchView 中找到它时,才会出现此问题。如果我关闭应用程序并重新打开,那是 searchView 知道股票存在的时候。否则,它似乎不知道何时添加新库存。

请帮忙!

带有过滤器实现的适配器类:

public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> implements Filterable {
MainActivity mainAct;
List<Stock> stocks;
List<Stock> searchAllStocks;

Adapter(MainActivity ma, List<Stock> stocks) {
    this.mainAct = ma;
    this.stocks = stocks;
    this.searchAllStocks = new ArrayList<>(stocks);
}
@Override
public Filter getFilter() {
    return stockFilter;
}
private Filter stockFilter = new Filter() {
    //runs on background thread
    @Override
    protected FilterResults performFiltering(CharSequence constraint) { //charSequence constraint is whatever is typed into search
        List<Stock> filteredList = new ArrayList<Stock>(); //list to store only filtered items

        if(constraint == null || constraint.length() == 0) { //if nothing in input field
            filteredList.addAll(searchAllStocks); //show all stocks on filteredList
        }
        else { //else get user input and convert into string to filter
            String filterPattern = constraint.toString().toLowerCase().trim();

            for(Stock item: searchAllStocks) { //for each stock item in
                if(item.getName().toLowerCase().contains(filterPattern)) { //add items that match to filteredList
                    filteredList.add(item);
                }
                if(item.getSymbol().toLowerCase().contains(filterPattern)) { //add items that match to filteredList
                    filteredList.add(item);
                }
            }
        }

        //returns FilterResults and gets passed to publishResults
        FilterResults results = new FilterResults();
        results.values = filteredList;

        return results;
    }
    //runs on UI thread
    //clears current stock list and adds results of user's search to list
    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        stocks.clear();
        stocks.addAll((List)results.values);
        notifyDataSetChanged();
    }
};

按下搜索按钮时在 MainActivity 中执行的方法:

//if search button is pressed
    if(item.getItemId() == R.id.search) {
        //set up new toolbar for searching
        searchView = (SearchView)item.getActionView();
        searchView.onActionViewExpanded(); //expands search bar
        searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); //sets keyboard icon to done after user types
        searchView.setQueryHint("Search...");


        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            //does stuff after text submitted
            @Override
            public boolean onQueryTextSubmit(String query) {
                return false;
            }

            //does stuff in realtime
            @Override
            public boolean onQueryTextChange(String newText) {
                adapter.getFilter().filter(newText);
                return true;
            }
        });
    }

这就是我认为我的问题所在

从 AsyncTask 类检索信息后调用此方法

//update Stock list on screen w/ info passed from Async class AsyncStockDownloader
public void updateData(Stock stock) {
    boolean flag = false;

    //check for duplicate stocks on list
    for(int i = 0; i < stocks.size(); i++) {
        if(stocks.get(i).getSymbol().equals(stock.getSymbol())) {
            //create alertbox
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage(stock.getSymbol() + " is already displayed!");
            builder.setTitle("Duplicate Stock");

            AlertDialog dialog = builder.create();
            dialog.show();
            flag = true;
        }
    }

    //if no duplicate then add to list, database, and notify adapter that we changed
    if(!flag) {
        stocks.add(stock);
        db.addStock(stock);
        adapter.notifyDataSetChanged();
        //problem is here. we need to let searchAllStocks in adapter know when stock is added
        //so that searchbar can store new stock into searchAllStocks
    }
}

如果我需要发布任何其他代码,请告诉我。这些只是我认为问题所在的片段。

提前谢谢你们!

- - - - - - - - - - - - - - - - - - - - 编辑 - - - - - -----------------------------------------

这是从 Asynctask 接收信息后调用的方法

我添加了 1 行代码来尝试解决问题:adapter.searchAllStocks.add(...) 正如评论所建议的那样

这些是结果

//update Stock list on screen w/ info passed from Async class AsyncStockDownloader
public void updateData(Stock stock) {
    boolean flag = false;

    //check for duplicate stocks on list
    for(int i = 0; i < stocks.size(); i++) {
        if(stocks.get(i).getSymbol().equals(stock.getSymbol())) {
            adapter.searchAllStocks.clear();
            //create alertbox
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage(stock.getSymbol() + " is already displayed!");
            builder.setTitle("Duplicate Stock");

            AlertDialog dialog = builder.create();
            dialog.show();
            flag = true;
        }
    }

    //if no duplicate then add to list, database, and notify adapter that we changed
    if(!flag) {
        stocks.add(stock);
        adapter.searchAllStocks.add(new Stock(stock.getSymbol(), stock.getName(), stock.getLatestPrice(), stock.getChange(), stock.getChangePercent()));
        db.addStock(stock);
        adapter.notifyDataSetChanged();
        //problem is here. we need to let searchAllStocks in adapter know when stock is added
        //so that searchbar can store new stock into searchAllStocks list
    }
}

所以现在让我来看看我的应用程序是什么样的。

1. 这是我已经添加了 3 只股票的主页

在此处输入图像描述

2. 我点击工具栏中的搜索选项,找到一只名为“GOOG”的股票

在此处输入图像描述

过滤列表还显示了 2 支 GOOG 股票,这很奇怪,我希望它显示 1 支,但不知道为什么会这样。

3. 这是我清除整个搜索栏后显示的过滤列表。如您所见,每只股票都有一个重复的股票。

在此处输入图像描述

4. 现在,当我按返回返回主页时,我的过滤列表中的所有这些重复股票都留下了。显然我们不希望这样

在此处输入图像描述

5. 然而,当我刷新我的主页时,我又恢复了我美丽的单只股票。每次按下后退按钮后,我希望看到我的股票像这个页面一样显示

在此处输入图像描述

再次感谢任何人!

标签: androidandroid-studioandroid-recyclerviewsearchview

解决方案


推荐阅读