Не удается найти недавно добавленные акции в searchView - PullRequest
0 голосов
/ 08 мая 2020

Значит, я не получаю ошибку или что-то в этом роде. Это реализация, над которой мне трудно работать.

Я сделал стандартное приложение, в котором вы можете искать акции из API и добавлять их в recyclerView. Я также реализовал searchView, чтобы найти какие-либо определенные акции в моем списке recyclerView.

Однако это моя проблема: скажем, я открыл приложение и добавил новую акцию в список из API. Он отлично добавляет акции в список. Однако когда я go захожу в 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
    }
}

Пожалуйста, дайте мне знать, есть ли еще какой-либо код, который мне нужно опубликовать. Это только отрывки, где, я думаю, проблема может быть ie.

Заранее спасибо, ребята!

---------------- ------------------------редактировать------------------------- -------------

Это метод, вызываемый после получения информации от 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 акции

enter image description here

2. Я нажал на опцию поиска на панели инструментов, чтобы найти акцию с именем "GOOG"

enter image description here

В фильтруемом списке также показаны 2 акции GOOG, что довольно странно. , Я бы предпочел показать 1, но не знаю, почему это происходит.

3. Это filterList, который отображается после того, как я очищаю весь свой searchBar. Как видите, для каждой бумаги есть дубликат.

enter image description here

4. Теперь, когда я нажимаю кнопку «Назад», чтобы вернуться на главную страницу, у меня остаются все эти повторяющиеся акции из моего отфильтрованного списка. Очевидно, мы не хотим, чтобы

enter image description here

5. Однако, когда я обновляю sh свою домашнюю страницу, я снова получаю свои прекрасные одиночные акции. Я бы хотел, чтобы мои акции отображались как на этой странице после того, как я каждый раз нажимаю кнопку «Назад»

enter image description here

Еще раз спасибо всем!

...