I've been working on a SearchView
and I have failed miserably. When I type something on it, nothing happens and it does not filter the list. I have provided my fragment and my adapter below. Please help! Thanks!
Additional Question: After I type something in the searchview, and if I tap the back button, I want the keyboard to hide and to return the title of my fragment. How should i do this?
Fragment
public class RecentNewsFragment extends Fragment implements ConnectivityReceiver.ConnectivityReceiverListener, SearchView.OnQueryTextListener {
public RecentNewsFragment() {
}
final String TAG = "MainPageActivity";
ArrayList<News> newsList;
public RecyclerView rvNewsArticle;
public NewsArticleAdapter adapter;
public SwipeRefreshLayout swipeRefreshLayout;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_recent_news, container, false);
checkConnection();
rvNewsArticle = (RecyclerView) view.findViewById(R.id.rvNewsArticle);
rvNewsArticle.setHasFixedSize(true);
final LinearLayoutManager manager = new LinearLayoutManager(getActivity());
rvNewsArticle.setLayoutManager(manager);
swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeRefresh);
swipeRefreshLayout.setColorSchemeResources(R.color.primaryColor, R.color.primaryTextColor, R.color.secondaryColor);
swipeRefreshLayout.setSize(SwipeRefreshLayout.LARGE);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
loadNews();
}
}, 1000);
}
});
return view;
}
private void loadNews() {
String ip = IPAddress.ipaddress;
String url = "http://" + ip + "/theflare/app/news.php";
StringRequest stringRequest = new StringRequest(Request.Method.GET,
url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.d(TAG, response);
newsList = new JsonConverter<News>()
.toArrayList(response, News.class);
adapter = new NewsArticleAdapter(getActivity(), newsList);
rvNewsArticle.setAdapter(adapter);
swipeRefreshLayout.setRefreshing(false);
FileCacher<ArrayList<News>> newsCacher = new FileCacher<>(getActivity(), "theflarenewscache.txt");
try {
newsCacher.appendOrWriteCache(newsList);
} catch (IOException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
if (error != null) {
Snackbar snackbar = Snackbar
.make(getActivity().findViewById(android.R.id.content), "Something went wrong.", Snackbar.LENGTH_INDEFINITE)
.setAction("Retry", new View.OnClickListener() {
@Override
public void onClick(View view) {
loadNews();
}
});
View sbView = snackbar.getView();
sbView.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.maroon));
snackbar.show();
}
}
}
);
MySingleton.getInstance(getActivity()).addToRequestQueue(stringRequest);
}
private void loadCachedNews() {
FileCacher<ArrayList<News>> newsCacher = new FileCacher<>(getActivity(), "theflarenewscache.txt");
if(newsCacher.hasCache()){
try {
ArrayList<News> cachedNewsList = newsCacher.readCache();
final NewsArticleAdapter adapter = new NewsArticleAdapter(getActivity(), cachedNewsList);
//rvNewsArticle.setAdapter(adapter);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassCastException e){
e.printStackTrace();
}
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Inflate the menu; this adds items to the action bar if it is present.
inflater.inflate(R.menu.main_page, menu);
// Associate searchable configuration with the SearchView
final MenuItem searchItem = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
searchView.setOnQueryTextListener(this);
MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() {
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
// Do something when collapsed
adapter.setFilter(newsList);
return true; // Return true to collapse action view
}
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
// Do something when expanded
return true; // Return true to expand action view
}
});
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onQueryTextSubmit(String query) {
if (adapter != null) {
query = String.valueOf(query.equals(""));
}
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
newText = newText.toLowerCase();
final ArrayList<News> filteredNewsList = new ArrayList<>();
for (News model : newsList) {
final String title = model.getTitle().toLowerCase();
final String author = model.getAuthor().toLowerCase();
final String category = model.getCategory().toLowerCase();
final String content = model.getContent().toLowerCase();
if ((title.contains(newText)) || (author.contains(newText)) || (category.contains(newText)) || (content.contains(newText))) {
filteredNewsList.add(model);
}
}
adapter.setFilter(filteredNewsList);
return true;
}
// Method to manually check connection status
private void checkConnection() {
boolean isConnected = isConnected();
snackInternet(isConnected);
}
private void snackInternet(boolean isConnected) {
if (isConnected) {
Snackbar snackbar = Snackbar.make(getActivity().findViewById(android.R.id.content), "Connected to the Internet!", Snackbar.LENGTH_SHORT);
View sbView = snackbar.getView();
sbView.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.primaryDarkColor));
snackbar.show();
loadNews();
}
else {
Snackbar snackbar = Snackbar
.make(getActivity().findViewById(android.R.id.content), "You seem to be offline.", Snackbar.LENGTH_INDEFINITE)
.setAction("Retry", new View.OnClickListener() {
@Override
public void onClick(View view) {
loadNews();
}
});
View sbView = snackbar.getView();
sbView.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.maroon));
snackbar.show();
loadCachedNews();
}
}
@Override
public void onResume() {
super.onResume();
// register connection status listener
TheFlare.getInstance().setConnectivityListener(this);
}
/**
* Callback will be triggered when there is change in
* network connection
*/
@Override
public void onNetworkConnectionChanged(boolean isConnected) {
snackInternet(isConnected);
}
}
Adapter
public class NewsArticleAdapter extends RecyclerView.Adapter<NewsArticleAdapter.NewsViewHolder> {
private Context context;
private ArrayList<News> newsList;
public NewsArticleAdapter(Context context, ArrayList<News> newsList){
this.context = context;
this.newsList = newsList;
}
@Override
public NewsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.from(parent.getContext())
.inflate(R.layout.news_cardview_layout, parent, false);
NewsViewHolder newsViewHolder = new NewsViewHolder(view);
return newsViewHolder;
}
@Override
public void onBindViewHolder(NewsViewHolder holder, int position) {
final News selectedNews = newsList.get(position);
holder.tvId.setText(String.valueOf(selectedNews.id));
holder.tvTitle.setText(selectedNews.title);
holder.tvPubDate.setText("" + selectedNews.publicationDate);
String ip = IPAddress.ipaddress;
String fullUrl = "http://" + ip + "/theflare/admin/img/newsbanner/" + selectedNews.imgBanner;
Picasso.with(context)
.load(fullUrl)
.placeholder(R.drawable.bannerplaceholder)
.error(android.R.drawable.stat_notify_error)
.into(holder.ivImage);
holder.ivImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick (View view) {
Intent intent = new Intent(context, NewsDetailActivity.class);
intent.putExtra("newsList", selectedNews);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
}
@Override
public int getItemCount() {
if(newsList != null){
return newsList.size();
}
return 0;
}
public void setFilter(ArrayList<News> newsArrayList) {
newsList.clear();
newsList.addAll(newsArrayList);
notifyDataSetChanged();
}
//ViewHolder class
public static class NewsViewHolder extends RecyclerView.ViewHolder{
public CardView cvNews;
public TextView tvId;
public ImageView ivImage;
public TextView tvTitle;
public TextView tvPubDate;
public NewsViewHolder(View itemView) {
super(itemView);
cvNews = (CardView)itemView.findViewById(R.id.cvNews);
tvId = (TextView) itemView.findViewById(R.id.tvId);
ivImage = (ImageView)itemView.findViewById(R.id.ivImageUrl);
tvTitle = (TextView)itemView.findViewById(R.id.tvTitle);
tvPubDate = (TextView)itemView.findViewById(R.id.tvPubDate);
}
}
}
Solved it! Had to insert some codes and it finally worked! Here is what I have done:
In my MainActivity
, I had to change my onCreateOptions
method to this:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
Then in my fragment's onCreateView
method:
setHasOptionsMenu(true);
I also had to implement the listeners for searchview and menuitem:
public class RecentNewsFragment extends Fragment implements SearchView.OnQueryTextListener, MenuItem.OnActionExpandListener
Afterwards, I implement these methods:
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Inflate the menu; this adds items to the action bar if it is present.
inflater.inflate(R.menu.search_menu, menu);
// Associate searchable configuration with the SearchView
final MenuItem searchItem = menu.findItem(R.id.action_search);
MenuItemCompat.setShowAsAction(searchItem, MenuItemCompat.SHOW_AS_ACTION_ALWAYS | MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
searchView.setOnQueryTextListener(this);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onQueryTextSubmit(String query) {
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
if (newText == null || newText.trim().isEmpty()) {
adapter.setFilter(newsList);
return false;
}
newText = newText.toLowerCase();
final ArrayList<News> filteredNewsList = new ArrayList<>();
for (News model : newsList) {
final String title = model.getTitle().toLowerCase();
final String author = model.getAuthor().toLowerCase();
final String category = model.getCategory().toLowerCase();
final String content = model.getContent().toLowerCase();
if ((title.contains(newText)) || (author.contains(newText)) || (category.contains(newText)) || (content.contains(newText))) {
filteredNewsList.add(model);
}
}
adapter.setFilter(filteredNewsList);
return true;
}
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
return true;
}
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
adapter.setFilter(newsList);
return true;
}
Finally, in my adapter:
public void setFilter(ArrayList<News> newsArrayList) {
news.clear();
news.addAll(newsArrayList);
notifyDataSetChanged();
}