所以这不是我得到的错误或任何东西。这是一个我很难做到的实现。
我做了一个股票应用,你可以从API中搜索股票,并将它们添加到回收者View中。我还实现了一个searchView来查找我的recyclerView列表中的任何某只股票。
然而,这是我的问题:比方说,我打开应用程序,并从API中添加一个新的股票到列表中。它将该股票完美地添加到列表中。然而,当我去搜索View寻找我刚刚添加的那只股票时,我无法在搜索View列表中找到它。事实上,某只股票也从回收器列表中被删除了(在我进入searchView之前,它还完美地存在着)。当我重新启动应用程序时,这时股票又出现在回收商列表中,这次我可以从搜索视图列表中访问它。这只是一个奇怪的事情发生。
这个问题只发生在我试图找到一个我刚刚添加到我的列表中的股票,并且想要在搜索View中找到它之后。如果我关闭应用程序并重新打开,这时搜索视图就会知道该股票存在。否则,只要有新股票被添加,它似乎就不知道。
请大家帮忙
适配器类w过滤器的实现。
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
}
}
那么现在让我来给u介绍一下我的app是什么样的。
1. 这是主页,在这里我已经添加了3只股票
2. 我从工具栏上点击搜索选项,发现一只股票名为 "GOOG"
filteredList还显示2只GOOG股票,这很奇怪,我更希望它显示1只,但不知道为什么会这样。
3. 这是我清除整个搜索栏后显示的filteredList,你可以看到,每个股票都有重复的股票。正如你所看到的,每个股票都有一个重复的股票。
4. 4.现在当我按回车键返回主页时,我从filteredList中留下了所有这些重复的股票。很明显,我们不希望这样
5. 但是,当我刷新主页的时候,我的漂亮的单只股票又回来了。我很想看到我的股票在我每次按下返回键后,都能像这个页面一样显示出来。
再次感谢任何人!