Solved , I should use Static for my Models in declerating . thanks all
I just went through this topic filter recycler view using search view and I did all the steps. Now when I search in recycler view it will filter my recycler view but when I press back space and remove a char it wont show the removed items! My recycler view is also empty after the search.
This is my RecyclerView adapter:
package com.webapp.masoud.application.myRecyclerAdapter;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import com.webapp.masoud.application.R;
import com.webapp.masoud.application.service.NewsModel;
import java.util.ArrayList;
import de.hdodenhof.circleimageview.CircleImageView;
public class myRecyclerAdapter extends RecyclerView.Adapter<myRecyclerAdapter.myRecyclerViewHolder> {
private Context context;
ArrayList<NewsModel> myModels;
public myRecyclerAdapter(Context context, ArrayList<NewsModel> myModels) {
this.context = context;
this.myModels = myModels;
}
@Override
public myRecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.channels_layout, parent, false);
return new myRecyclerViewHolder(v);
}
@Override
public void onBindViewHolder(myRecyclerViewHolder holder, int position) {
final NewsModel newsModel = myModels.get(position);
holder.edt_Title.setText(newsModel.title);
holder.edt_Dis.setText(newsModel.discription);
holder.txt_Category.setText(newsModel.category);
Picasso.with(context).load(newsModel.image).into(holder.img_Channel);
holder.btn_Join.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final String username;
if (newsModel.username.startsWith("@")){
username = "http://telegram.me/" + newsModel.username.substring(1);
}
else{
username = "http://telegram.me/" + newsModel.username;}
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(username));
context.startActivity(i);
}
});
}
@Override
public int getItemCount() {
return myModels.size();
}
public void animateTo(ArrayList<NewsModel> models) {
applyAndAnimateRemovals(models);
applyAndAnimateAdditions(models);
applyAndAnimateMovedItems(models);
}
public void setModels(ArrayList<NewsModel> models) {
myModels = new ArrayList<>(models);
}
public NewsModel removeItem(int position) {
final NewsModel model = myModels.remove(position);
notifyItemRemoved(position);
return model;
}
public void addItem(int position, NewsModel model) {
myModels.add(position, model);
notifyItemInserted(position);
}
public void moveItem(int fromPosition, int toPosition) {
final NewsModel model = myModels.remove(fromPosition);
myModels.add(toPosition, model);
notifyItemMoved(fromPosition, toPosition);
}
private void applyAndAnimateRemovals(ArrayList<NewsModel> newModels) {
for (int i = myModels.size() - 1; i >= 0; i--) {
final NewsModel model = myModels.get(i);
if (!newModels.contains(model)) {
removeItem(i);
}
}
}
private void applyAndAnimateAdditions(ArrayList<NewsModel> newModels) {
for (int i = 0, count = newModels.size(); i < count; i++) {
final NewsModel model = newModels.get(i);
if (!myModels.contains(model)) {
addItem(i, model);
}
}
}
private void applyAndAnimateMovedItems(ArrayList<NewsModel> newModels) {
for (int toPosition = newModels.size() - 1; toPosition >= 0; toPosition--) {
final NewsModel model = newModels.get(toPosition);
final int fromPosition = myModels.indexOf(model);
if (fromPosition >= 0 && fromPosition != toPosition) {
moveItem(fromPosition, toPosition);
}
}
}
class myRecyclerViewHolder extends RecyclerView.ViewHolder {
private TextView edt_Title;
private TextView edt_Dis;
public TextView txt_Category;
private Button btn_Join;
private CircleImageView img_Channel;
public myRecyclerViewHolder(View itemView) {
super(itemView);
edt_Title = (TextView) itemView.findViewById(R.id.edt_Title);
edt_Dis = (TextView) itemView.findViewById(R.id.edt_Dis);
btn_Join = (Button) itemView.findViewById(R.id.btn_Join);
img_Channel = (CircleImageView) itemView.findViewById(R.id.img_Channel);
txt_Category = (TextView) itemView.findViewById(R.id.txt_Category);
}
}
}
This is my MainActivity.java:
package com.webapp.masoud.application.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Parcelable;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.webapp.masoud.application.R;
import com.webapp.masoud.application.myRecyclerAdapter.myRecyclerAdapter;
import com.webapp.masoud.application.service.NewsModel;
import com.webapp.masoud.application.service.APIService;
import com.webapp.masoud.application.service.NewsModelResponse;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import uk.co.chrisjenx.calligraphy.CalligraphyConfig;
import uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper;
public class MainActivity extends AppCompatActivity {
private SearchView mSearchView;
private MenuItem searchMenuItem;
RecyclerView rv_Channels;
private Parcelable recyclerViewState;
SearchView.OnQueryTextListener myListener;
myRecyclerAdapter myAdapter;
ArrayList<NewsModel> newsModelArrayList;
NewsModelResponse newsModelResponse;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//CalliGraphy
CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
.setDefaultFontPath("fonts/Vazir.ttf")
.setFontAttrId(R.attr.fontPath)
.build()
);
//Context
setContentView(R.layout.activity_main);
//MY Application
Toolbar myToolbar = (Toolbar) findViewById(R.id.myToolbar);
setSupportActionBar(myToolbar);
final ProgressDialog myProgressDialog = new ProgressDialog(MainActivity.this);
myProgressDialog.setMessage("در حال دریافت لیست کانال ها ، لطفا منتظر بمانید .");
rv_Channels = (RecyclerView) findViewById(R.id.rv_Channels);
final SearchView sv_Channels = (SearchView) findViewById(R.id.sv_Channels);
//My API Service !
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://rapcity1.cf/service/")
.addConverterFactory(GsonConverterFactory.create())
.build();
APIService service = retrofit.create(APIService.class);
Call<NewsModelResponse> serviceNewsModels = service.getNewsModels();
serviceNewsModels.enqueue(new Callback<NewsModelResponse>() {
@Override
public void onResponse(Call<NewsModelResponse> call, Response<NewsModelResponse> response) {
myProgressDialog.dismiss();
newsModelResponse = response.body();
newsModelArrayList = newsModelResponse.getNewsModels();
myAdapter = new myRecyclerAdapter(MainActivity.this, newsModelArrayList);
LinearLayoutManager myLinearlayoutmanager = new LinearLayoutManager(MainActivity.this);
rv_Channels.setLayoutManager(myLinearlayoutmanager);
recyclerViewState = rv_Channels.getLayoutManager().onSaveInstanceState();//save
rv_Channels.setItemAnimator(new DefaultItemAnimator());
rv_Channels.setAdapter(myAdapter);
}
@Override
public void onFailure(Call<NewsModelResponse> call, Throwable t) {
}
});
//End of API Service
//Search
assert sv_Channels != null;
myListener = new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String query) {
final ArrayList<NewsModel> filteredModelList = filter(newsModelArrayList, query);
myAdapter.animateTo(filteredModelList);
rv_Channels.scrollToPosition(0);
return true;
}
};
}
private ArrayList<NewsModel> filter(ArrayList<NewsModel> models, String query) {
// query = query.toLowerCase();
final ArrayList<NewsModel> filteredModelList = new ArrayList<>();
for (NewsModel model : models) {
final String title = model.title;
//final String dis = model.discription;
if (title.contains(query) /*|| dis.contains(query)*/) {
filteredModelList.add(model);
}
}
return filteredModelList;
}
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
searchMenuItem = menu.findItem(R.id.action_search);
mSearchView = (SearchView) searchMenuItem.getActionView();
mSearchView.setOnQueryTextListener(myListener);
mSearchView.setOnCloseListener(new SearchView.OnCloseListener() {
@Override
public boolean onClose() {
rv_Channels.getLayoutManager().onRestoreInstanceState(recyclerViewState);
return true;
}
});
return true;
}
}
This is my newsModels:
package com.webapp.masoud.application.service;
import java.io.Serializable;
/**
* Created by Master on 4/19/2016.
*/
public class NewsModel implements Serializable {
public String id;
public String title;
public String discription;
public String image;
public String category;
public String username;
public NewsModel(String title, String description,String image,String id,String category,String username) {
this.id = id;
this.title = title;
this.discription = description;
this.image = image;
this.category = category;
this.username=username;
}
public NewsModel() {
}
}
Please help me, thanks. Sorry for my bad English!