Android: функция поиска работает неправильно - PullRequest
0 голосов
/ 30 марта 2020

Я работаю над проектом, в котором пользователь должен иметь возможность искать книгу по названию книги или году в списке массивов.

Я использую RecyclerView и SearchView, и я инициализировал их во фрагменте.

Я использую SearchView, совместимый с androidx, для фильтрации списка книг.

Насколько мне известно, я реализовал правильную логику c, однако, вид поиска, похоже, не фильтруется. какие-либо предложения?

BookListFragment. java

public class BookListFragment extends Fragment implements SearchView.OnQueryTextListener, MenuItem.OnActionExpandListener {

public interface OnListFragmentInteractionListener {
    void onListFragmentRefreshRequested();
}

private static final String ON_REFRESH_NOTED = "ON_REFRESH_NOTED";
private OnListFragmentInteractionListener mListener;

private ArrayList<Book> mBooks =
        new ArrayList<>();

private BookRecyclerViewAdapter mBookAdapter =
        new BookRecyclerViewAdapter(mBooks);

private RecyclerView mRecyclerView;
private SwipeRefreshLayout mSwipeToRefreshView;
protected BookViewModel bookViewModel;

public BookListFragment() {
    // Required empty public constructor
}

@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_book_list,
            container, false);
    mRecyclerView = view.findViewById(R.id.list);
    mSwipeToRefreshView = view.findViewById(R.id.swiperefresh);
    setHasOptionsMenu(true);
    return view;
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    // Set the Recycler View adapter
    Context context = view.getContext();
    mRecyclerView.setLayoutManager(new LinearLayoutManager(context));
    mRecyclerView.setAdapter(mBookAdapter);
    setHasOptionsMenu(true);
    // Setup the swipe to refresh view
    mSwipeToRefreshView.setOnRefreshListener(
            new SwipeRefreshLayout.OnRefreshListener() {
                @Override
                public void onRefresh() {
                    Log.i(ON_REFRESH_NOTED, "Refresh noted.");
                    updateBooks();
                }
            }
    );
}

private void updateBooks() {
    if (mListener != null)
        mListener.onListFragmentRefreshRequested();

}

public void setBooks(List<Book> books) {
    mBooks.clear();
    mBookAdapter.notifyDataSetChanged();

    for (Book book : books) {
        if (!mBooks.contains(book)) {
            mBooks.add(book);
            mBookAdapter
                    .notifyItemInserted(mBooks.indexOf(book));
        }
    }

    mSwipeToRefreshView.setRefreshing(false);
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    // Retrieve the Book View Model for the parent Activity.
    bookViewModel = new ViewModelProvider(getActivity()).get(BookViewModel.class);

    // Get the data from the View Model, and observe any changes.
    bookViewModel.getBooks()
            .observe(getViewLifecycleOwner(), new Observer<List<Book>>() {
                @Override
                public void onChanged(List<Book> books) {
                    // When the View Model changes, update the List.
                    if (books != null)
                        setBooks(books);
                }
            });
}

@Override
public void onAttach(@NonNull Context context) {
    super.onAttach(context);
    mListener = (OnListFragmentInteractionListener) context;
}

@Override
public void onDetach() {
    super.onDetach();
    mListener = null;
}

@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NotNull MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    menu.clear();
    inflater.inflate(R.menu.menu, menu);
    MenuItem searchItem = menu.findItem(R.id.action_search);
    MenuItem itemSwitch = menu.findItem(R.id.action_switch);

    SwitchCompat switchCompat = (SwitchCompat) itemSwitch.getActionView();

    switchCompat.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (isChecked) {
                Toast.makeText(getContext().getApplicationContext(), "Formatting in XML..", Toast.LENGTH_SHORT).show();
                bookViewModel.loadBooksInXML();
            } else {
                Toast.makeText(getContext().getApplicationContext(), "Formatting in JSON..", Toast.LENGTH_SHORT).show();

            }
        }
    });

    SearchView searchView = (SearchView) searchItem.getActionView();
    searchView.setOnQueryTextListener(this);
}

@Override
public boolean onMenuItemActionExpand(MenuItem item) {
    return false;
}

@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
    return false;
}

@Override
public boolean onQueryTextSubmit(String query) {
    return true;
}

@Override
public boolean onQueryTextChange(String newText) {
    mBookAdapter.getFilter().filter(newText);
    return true;
}

BookRecyclerViewAdapter. java

public class BookRecyclerViewAdapter extends
    RecyclerView.Adapter<BookRecyclerViewAdapter.ViewHolder> implements Filterable {

private List<Book> mBooks;
private List<Book> mBooksFull;

private static final SimpleDateFormat TIME_FORMAT =
        new SimpleDateFormat("y", Locale.UK);
private static final NumberFormat PRICE_FORMAT =
        new DecimalFormat("0.0");

public BookRecyclerViewAdapter(List<Book> books) {

    mBooks = books;
    mBooksFull = books;
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    ListItemBookBinding binding = ListItemBookBinding.inflate(
            LayoutInflater.from(parent.getContext()), parent, false);
    return new ViewHolder(binding);
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    Book book = mBooks.get(position);
    holder.binding.setBook(book);
    holder.binding.executePendingBindings();
}

@Override
public int getItemCount() {
    return mBooks.size();
}

@Override
public Filter getFilter() {
    return filter;
}

public class ViewHolder extends RecyclerView.ViewHolder {
    public final ListItemBookBinding binding;

    public ViewHolder(ListItemBookBinding binding) {
        super(binding.getRoot());
        this.binding = binding;
        binding.setTimeformat(TIME_FORMAT);
        binding.setPriceformat(PRICE_FORMAT);
    }
}

private Filter filter = new Filter() {
    // Running on background thread automatically
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        List<Book> filteredList = new ArrayList<>();
        if (constraint != null && constraint.length() > 0) {
            filteredList.addAll(mBooksFull);
        } else {
            String filterPattern = constraint.toString().toLowerCase().trim();

            for (Book item : mBooksFull) {
                if (item.getTitle().toLowerCase().contains(filterPattern) ||
                        item.getYear().toLowerCase().contains(filterPattern)) {
                    filteredList.add(item);
                } else {
                    filteredList = mBooksFull;
                }
            }
        }
        FilterResults results = new FilterResults();
        results.values = filteredList;
        return results;
    }

    // Runs on a UI thread.
    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        mBooks.clear();
        mBooks.addAll((List) results.values);
        notifyDataSetChanged(); // notifies the data with new filtered values
    }
};

BookMainActivity. java

public class BookMainActivity extends AppCompatActivity
    implements BookListFragment.OnListFragmentInteractionListener {

@Override
public void onListFragmentRefreshRequested() {
    updateBooks();
}

private void updateBooks() {
    bookViewModel.loadBooksInXML();
    bookViewModel.loadBooksInJson();
}

private static final String TAG_LIST_FRAGMENT = "TAG_LIST_FRAGMENT";

BookListFragment mBookListFragment;
BookViewModel bookViewModel;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_book_main);

    FragmentManager fm = getSupportFragmentManager();

    // Android will automatically re-add any Fragments that
    // have previously been added after a configuration change,
    // so only add it if this isn't an automatic restart.
    if (savedInstanceState == null) {
        FragmentTransaction ft = fm.beginTransaction();

        mBookListFragment = new BookListFragment();
        ft.add(R.id.main_activity_frame,
                mBookListFragment, TAG_LIST_FRAGMENT);
        ft.commitNow();
    } else {
        mBookListFragment =
                (BookListFragment) fm.findFragmentByTag(TAG_LIST_FRAGMENT);
    }
    // Retrieve the Book View Model for this activity.
    bookViewModel = new ViewModelProvider(this).get(BookViewModel.class);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    return true;
}

}

...