android - 在 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. 然而,当我刷新我的主页时,我又恢复了我美丽的单只股票。每次按下后退按钮后,我希望看到我的股票像这个页面一样显示
再次感谢任何人!
解决方案
推荐阅读
- amazon-web-services - AWS S3 上传的文件未显示
- javascript - Extjs - 在 Model.save() 中重试 API 请求
- authentication - 是否可以使用 OAuth 对用户进行身份验证并生成令牌?
- mysql - 从有特定值的表中获取值列表
- c# - .NET C#:实例化与 297 个表匹配的 297 个业务类
- sql-server - 如何为具有多个组的 Tablix 按组获取 PageName
- json - 我在使用 swift4 中的 Codable 序列化复杂的嵌套 json 时遇到了困难。
- javascript - JavaScript 对象表示法 - 在同一个对象内使用方法?
- javascript - 计算直线同一斜率上的点
- twitter-bootstrap - 如何在没有填充的情况下将两个输入内联?