RecylcerView Filter not working in xamarin.android - android-recyclerview

I got trouble filtering data in recylerview through searchview action bar. I got an project example and trying to implement the method. But the data won't filtering.
I put this on my fragment (search view)
public override void OnCreateOptionsMenu(IMenu menu,MenuInflater menuInflater)
{
//SearchMenu
menuInflater.Inflate(Resource.Menu.nav_search, menu);
var searchItem = menu.FindItem(Resource.Id.action_search);
var provider = MenuItemCompat.GetActionView(searchItem);
mSearchView = provider.JavaCast<Android.Support.V7.Widget.SearchView>();
mSearchView.QueryTextChange += (s, e) => mLocationsAdapter.Filter.InvokeFilter(e.NewText);
mSearchView.QueryTextSubmit += (s, e) =>
{
Toast.MakeText(this.Activity, "You searched: " + e.Query, ToastLength.Short).Show();
e.Handled = true;
};
MenuItemCompat.SetOnActionExpandListener(searchItem, new SearchViewExpandListener(mLocationsAdapter));
}
And this is my adapter:
namespace ShopDiaryApp.Adapter
{
public class LocationsRecycleAdapter : RecyclerView.Adapter,IFilterable
{
private readonly Activity mActivity;
private List<LocationViewModel> mLocations;
private List<LocationViewModel> mFilteredLocations;
private int mSelectedPosition = -1;
public LocationsRecycleAdapter(List<LocationViewModel> locations, Activity activity)
{
this.mLocations = locations;
this.mActivity = activity;
Filter = new LocationFilter(this);
}
public override int ItemCount => this.mLocations.Count;
public Filter Filter { get; private set; }
public event EventHandler<int> ItemClick;
private void OnClick(int position)
{
this.ItemClick?.Invoke(this, position);
NotifyItemChanged(position);
mSelectedPosition = position;
NotifyItemChanged(position);
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
if (this.mLocations.Count > 0)
{
var vh = holder as ViewHolder;
if (vh != null)
{
var location = this.mLocations[position];
vh.LocationName.Text = location.Name;
vh.LocationAddress.Text = location.Address;
vh.LocationDescription.Text = location.Description;
vh.ItemView.Selected = (mSelectedPosition == position);
}
}
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
var v = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.AdapterLocations, parent, false);
var vh = new ViewHolder(v, this.OnClick);
return vh;
}
public class ViewHolder : RecyclerView.ViewHolder
{
public ViewHolder(IntPtr javaReference, JniHandleOwnership transfer)
: base(javaReference, transfer)
{
}
public ViewHolder(View itemView, Action<int> listener)
: base(itemView)
{
this.LocationName = itemView.FindViewById<TextView>(Resource.Id.textviewLocationsAdapterName);
this.LocationAddress = itemView.FindViewById<TextView>(Resource.Id.textviewLocationAdapterAddress);
this.LocationDescription = itemView.FindViewById<TextView>(Resource.Id.textviewLocationAdapterDescription);
itemView.Click += (sender, e) => listener(this.LayoutPosition);
}
public TextView LocationName { get; }
public TextView LocationAddress { get; }
public TextView LocationDescription { get; }
}
private class LocationFilter : Filter
{
private readonly LocationsRecycleAdapter mLocationAdapter;
public LocationFilter(LocationsRecycleAdapter adapter)
{
mLocationAdapter = adapter;
}
protected override FilterResults PerformFiltering(ICharSequence constraint)
{
var returnObj = new FilterResults();
var results = new List<LocationViewModel>();
if (mLocationAdapter.mLocations == null)
mLocationAdapter.mLocations = mLocationAdapter.mFilteredLocations;
if (constraint == null) return returnObj;
if (mLocationAdapter.mLocations != null && mLocationAdapter.mLocations.Any())
{
// Compare constraint to all names lowercased.
// It they are contained they are added to results.
results.AddRange(
mLocationAdapter.mLocations.Where(
location => location.Name.ToLower().Contains(constraint.ToString())));
}
// Nasty piece of .NET to Java wrapping, be careful with this!
returnObj.Values = FromArray(results.Select(r => r.ToJavaObject()).ToArray());
returnObj.Count = results.Count;
constraint.Dispose();
return returnObj;
}
protected override void PublishResults(ICharSequence constraint, FilterResults results)
{
using (var values = results.Values)
mLocationAdapter.mFilteredLocations = values.ToArray<Java.Lang.Object>()
.Select(r => r.ToNetObject<LocationViewModel>()).ToList();
mLocationAdapter.NotifyDataSetChanged();
// Don't do this and see GREF counts rising
//constraint.Dispose();
//results.Dispose();
}
}
}
}
In protected override void PublishResults(ICharSequence constraint, FilterResults results) I got the filtered data. But the recyler view wont update (not filtered). Am I missing something?? Thanks for help :)

I think that you should be using mFilteredLocations in OnBindViewHolder:
if (this.mFilteredLocations.Count > 0)
...
var location = this.mFilteredLocations[position];
So that your mLocations stays as your original list of locations and what you show on your RecyclerView is always your filtered list.
Obviously at the beginning both mFilteredLocations and mLocations have to have the same items.
public LocationsRecycleAdapter(List<LocationViewModel> locations, Activity activity)
{
this.mLocations = locations;
this.mFilteredLocations = locations;
this.mActivity = activity;
Filter = new LocationFilter(this);
}
And on your filter you are changing mFilteredLocations and notify the data set changed so that all data is refreshed. But this will only take effect if you do the aforementioned changes.
Here you have another related question/answer but on Android if it can serve you as a further guidance.
HIH

Related

Get data from list of EditTexts in a recycler view to a list?

I am having an EditText in a TTextInputLayout as a Row_item for my recycler view, On the click of a button I am incrementing the count value in that recycler view and adding the edit text views in the app. After having as many views as I want, I am putting some data in those EditTexts and After all this I press save button and all the data from EditTexts should save in a list. I tried the textwatcher Property in xamarin.android but not able to perform that.
In my activity I also tried
var view = addChildRecyclerView.FindViewHolderForAdapterPosition(i);
var holder = view as fragmentRecyclerViewAdapterViewHolder;
if (holder != null)
{
holder.childname.FindViewById<TextInputLayout>(Resource.Id.enterChildNameTextView);
childlisttosend.Add(holder.childname.EditText.Text);
But sometimes I get holder as a null and some valus are missed to be put in the list.
I tried textchange property but it puts every single alphabet in the list, like
for index 1 it is "m"
for index 2 it is "ma"
for index 3 it is "man"
for index 4 it is "mani"
for index 5 it is "manis"
for index 6 it is "manish"
It is of no use. Please sugggest a solution.
adapter is
namespace assessment1_part2_v2.Fragment
{
public class addFamilyFragment : DialogFragment
{
public TextInputLayout fathername, mothername, address;
public MaterialButton addchild, savebutton;
public ArrayAdapter adapter;
public ListView listview;
public familyData familydata = new familyData();
public List<childData> childrenList = new List<childData>();
public editTextAdapter EditTextAdapter;
public event EventHandler<DataSenderClass> famaDataSender;
public RecyclerView enterChildRecyclerView;
public List<string> addChildDummyData = new List<string>();
public TextInputLayout enterChildEditTExt;
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.Inflate(Resource.Layout.addfam_layout, container, false);
connectingViews(view);
buttonClicks();
return view;
}
public class DataSenderClass : EventArgs
{
public familyData data { get; set; }
}
private void buttonClicks()
{
addchild.Click += Addchild_Click;
savebutton.Click += Savebutton_Click;
}
private void Savebutton_Click(object sender, EventArgs e)
{
//father, mother and address
familydata.fathername = fathername.EditText.Text;
familydata.mothername = mothername.EditText.Text;
familydata.location = address.EditText.Text;
familydata.children = new List<childData>();
List<childData> list = new List<childData>();
List<string> dummyCheck = new List<string>();
for (int i = 0; i <= addChildDummyData.Count; i++)
{
var viewholder = enterChildRecyclerView.FindViewHolderForAdapterPosition(i);
var holder = viewholder as editTextAdapterViewHolder;
// holder.addChildEditTExt;
if(holder != null)
{
holder.addChildEditTExt.FindViewById<TextInputLayout>(Resource.Id.enterChildEditTExt);
dummyCheck.Add(holder.addChildEditTExt.EditText.Text);
}
}
var x = dummyCheck;
addChildDummyData.Clear();
famaDataSender?.Invoke(this, new DataSenderClass { data = familydata });
this.Dismiss();
}
private void Addchild_Click(object sender, EventArgs e)
{
if (addChildDummyData.Count == 0)
{
addChildDummyData.Add("");
EditTextAdapter = new editTextAdapter(addChildDummyData);
enterChildRecyclerView.SetLayoutManager(new LinearLayoutManager(Activity));
enterChildRecyclerView.SetAdapter(EditTextAdapter);
int x = enterChildRecyclerView.ChildCount;
}
else
{
addChildDummyData.Add("");
EditTextAdapter.NotifyItemInserted(addChildDummyData.Count - 1);
int x = enterChildRecyclerView.ChildCount;
}
}
private void connectingViews(View view)
{
fathername = view.FindViewById<TextInputLayout>(Resource.Id.enterFatherNameEditText);
mothername = view.FindViewById<TextInputLayout>(Resource.Id.enterMotherNameEditText);
address = view.FindViewById<TextInputLayout>(Resource.Id.enterAddressEditText);
addchild = view.FindViewById<MaterialButton>(Resource.Id.addChildButton);
savebutton = view.FindViewById<MaterialButton>(Resource.Id.saveButton);
enterChildRecyclerView = view.FindViewById<RecyclerView>(Resource.Id.enterChildRecyclerView);
//listview = (ListView)view.FindViewById(Resource.Id.enterChildRecyclerView);
}
}
} `
We couldn't see the code of editTextAdapter.
But you can refer to my code ,my RecyclerView has an Edittext in each item and we can get data from the input list.
I put TextWatcher in my RecyclerView.ViewHolder(PhotoViewHolder.cs).
PhotoViewHolder.cs
public class PhotoViewHolder: RecyclerView.ViewHolder
{
public ImageView Image { get; private set; }
public TextView Caption { get; private set; }
public CheckBox MyCheckBox { get; set; }
public bool IsChecked { get; set; }
public EditText MyEditText { get; set; }
public MyTextWatcher myTextWatcher;
public Button imAddBefore { get; private set; }
public Button imAddAfter { get; private set; }
public PhotoViewHolder(View itemView, Action<int> listener, MyTextWatcher myWatcher ) : base(itemView)
{
//Image = itemView.FindViewById<ImageView> (Resource.Id.imageView);
Caption = itemView.FindViewById<TextView>(Resource.Id.textView);
MyCheckBox = itemView.FindViewById<CheckBox>(Resource.Id.myCheckBox);
DeleteButton = itemView.FindViewById<Button>(Resource.Id.deleteBtn);
MyEditText = itemView.FindViewById<EditText>(Resource.Id.mEditText);
this.myTextWatcher = myWatcher;
// add TextWatcher here
MyEditText.AddTextChangedListener(myTextWatcher);
// other code
}
public class MyTextWatcher : Java.Lang.Object, ITextWatcher
{
int position;
public void AfterTextChanged(IEditable s)
{
}
public void BeforeTextChanged(ICharSequence s, int start, int count, int after)
{
}
public void OnTextChanged(ICharSequence s, int start, int before, int count)
{ //mInput is a field in my item model
PhotoAlbumAdapter.mPhotoAlbum[position].mInput = s.ToString();
}
public void updatePosition(int position)
{
this.position = position;
}
}
}
My RecyclerView.Adapter is PhotoAlbumAdapter.cs
PhotoAlbumAdapter.cs
public class PhotoAlbumAdapter: RecyclerView.Adapter
{
public event EventHandler<int> ItemClick;
public static List<Photo> mPhotoAlbum = new List<Photo>();
public static RecyclerView.Adapter adapter;
public PhotoAlbumAdapter(List<Photo> branchesList)
{
adapter = this;
mPhotoAlbum = branchesList;
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.PhotoCardView, parent, false);
PhotoViewHolder vh = new PhotoViewHolder(itemView, OnClick, new PhotoViewHolder.MyTextWatcher());
return vh;
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
PhotoViewHolder vh = holder as PhotoViewHolder;
Photo item= mPhotoAlbum[position];
vh.Caption.Text = item.Caption;
// here we call function `updatePosition` in our TextWatcher class
vh.myTextWatcher.updatePosition(vh.AdapterPosition);
vh.MyEditText.Text = item.mInput;
// other code
}
public override int ItemCount
{
get { return mPhotoAlbum.Count; }
}
// Raise an event when the item-click takes place:
void OnClick(int position)
{
if (ItemClick != null)
ItemClick(this, position);
}
}
In my activity, we can get the data from the recycleview like this:
List<Photo> items= new List<Photo>();
mAdapter = new PhotoAlbumAdapter(items);
mRecyclerView.SetAdapter(mAdapter);
The result is:
for (int i=0;i< items.Count;i++) {
Photo temp = items[i];
System.Diagnostics.Debug.WriteLine( "The "+i +" result is: "+" Caption= " + temp.Caption + "<---> input = " + temp.mInput);
}

Delete duplicates items from my ArrayList of MyModel

I tried everything to remove the elements from my array without losing the json data of my SharedPreferences, if I don't add in my HashSet the data that I merged, I get an array without duplicate elements. This is what I want, add my model element without duplications in my array by loading the elements from the Json.
**Here my MyModel :**
public class MyModel {
Integer imageRes;
String textRes;
public MyModel(Integer imageRes, String textRes) {
this.imageRes = imageRes;
this.textRes = textRes;
}
public Integer getImageRes() {
return imageRes;
}
public void setImageRes(Integer imageRes) {
this.imageRes = imageRes;
}
public String getTextRes() {
return textRes;
}
public void setTextRes(String textRes) {
this.textRes = textRes;
}
}
And here my Holder
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.myViewHolder> {
public MyAdapter(ArrayList<MyModel> models) {
this.models = models;
}
private final ArrayList<MyModel> models;
#NonNull
#Override
public myViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.items, parent,false);
return new myViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull myViewHolder holder, int position) {
holder.setIsRecyclable(false);
holder.imageItem.setImageResource(models.get(position).getImageRes());
holder.textItem.setText(models.get(position).getTextRes());
}
public ArrayList<MyModel> getModels() {
return models;
}
#Override
public long getItemId(int position) {
return super.getItemId(position);
}
#Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
#Override
public int getItemCount() {
return (models == null) ? 0 : models.size();
}
#Override
public void setHasStableIds(boolean hasStableIds) {
super.setHasStableIds(hasStableIds);
}
static class myViewHolder extends RecyclerView.ViewHolder{
ImageView imageItem;
TextView textItem;
public myViewHolder(#NonNull View itemView){
super(itemView);
imageItem = itemView.findViewById(R.id.ItemMarker);
textItem = itemView.findViewById(R.id.itemTxt);
}
}
}
**And here my problem :**
if(models != null){
try {
try{
SharedPreferences ListDatas = getSharedPreferences("SavedList", MODE_PRIVATE);
Gson gson = new Gson();
String json = ListDatas.getString("ListKey", null);
Type type = new TypeToken<ArrayList<MyModel>>(){}.getType();
models = gson.fromJson(json, type);
list.setHasFixedSize(true);
if(adapter != null){
adapter.setHasStableIds(true);
}
list.setAdapter(adapter);
list.setBackgroundColor(R.color.items);
list.setDuplicateParentStateEnabled(false);
models.ensureCapacity(100);
adapter = new MyAdapter(models);
NewModel = models;
Set<MyModel> DelItems = new HashSet<>();
DelItems.add(new MyModel(R.drawable.marker, "Commande en cours..." + "\n" + "Date : " + dateFormat + "\n" + "Nettoyage enregistré à : " + heure + "H" + minutes));
Set<MyModel> DelItems2 = new HashSet<>(NewModel);
NewModel.clear();
Set<MyModel> DelItemsFinal = new HashSet<>(DelItems2);
DelItemsFinal.addAll(DelItems2);
DelItemsFinal.addAll(DelItems);
Set<MyModel> DelItemsFinal2 = new LinkedHashSet<>(DelItemsFinal);
NewModel.clear();
NewModel.addAll(DelItemsFinal2);
DelItems.clear();
DelItems2.clear();
adapter.notifyDataSetChanged();
lastPosition = NewModel.size() -1;
layoutManager.scrollToPosition(lastPosition);
InfosHisto.setText("Votre historique de commande");
} catch (JsonSyntaxException e) {
e.printStackTrace();
}

Android Studio : E/RecyclerView: No adapter attached; skipping layout

I've found only a few articles related to this issue on StackOverflow tried all of their solutions in various combinations but can't get the RecyclerView to display my RecyclerView.Adapter that is populated with data which a I can verify and see the list in debug mode but it simply won't show the information.
My code (I struggled to paste the XML Layout files):
public class RecipeDetailActivity extends AppCompatActivity {
private RecipeModel mRecipe;
private ArrayList<IngredientModel> mIngredientList = new ArrayList<>();
private IngredientListAdapter ingredientListAdapter;
private RecyclerView rvIngredientList;
private boolean mTwoPane;
private ListView listView;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recipe_detail);
rvIngredientList = (RecyclerView)findViewById(R.id.rv_ingredient_list);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
rvIngredientList.setLayoutManager(layoutManager);
SampleRecycler sampleRecycler = new SampleRecycler(); // empty RecyclerView.Adapter
rvIngredientList.setAdapter(sampleRecycler);
mRecipe = getIntent().getParcelableExtra("com.wernerraubenheimer.bakingapp.data.RecipeModel");
mIngredientList = mRecipe.getIngredients();
ingredientListAdapter = new IngredientListAdapter(mIngredientList);
ingredientListAdapter.notifyDataSetChanged();
// Up until this point the RecyclerVie.Adapter is populated with data - debug mode I can see the list
rvIngredientList.swapAdapter(ingredientListAdapter, false);
}
}
public class IngredientListAdapter extends RecyclerView.Adapter<IngredientListAdapter.IngredientViewHolder> {
private ArrayList<IngredientModel> mIngredientList;
private Context mContext;
private boolean mTwoPane;
public IngredientListAdapter(ArrayList<IngredientModel> ingredientList) {
mIngredientList = ingredientList;
}
#Override
public IngredientViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
mContext = parent.getContext();
int layoutIdForListItem = R.layout.ingredient_list_item;
LayoutInflater inflater = LayoutInflater.from(mContext);
boolean attachImmediatelyToParent = false;
View view = inflater.inflate(layoutIdForListItem, parent, attachImmediatelyToParent);
IngredientViewHolder viewHolder = new IngredientViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(IngredientViewHolder holder, int position) {
IngredientModel ingredient = mIngredientList.get(position);
holder.bind(mContext, ingredient);
}
#Override
public int getItemCount() {
if (mIngredientList != null) {
return 0;
} else {
return mIngredientList.size();
}
}
static class IngredientViewHolder extends RecyclerView.ViewHolder {
private CardView cardviewContainer;
private TextView tvIngredientName;
private TextView tvIngredientQuantity;
private TextView tvIngredientMeasure;
private Context mContext;
private IngredientModel mIngredient;
IngredientViewHolder(View itemView) {
super(itemView);
//cardviewContainer = (CardView)itemView.findViewById(R.id.card_view_ingredient);
tvIngredientName = (TextView)itemView.findViewById(R.id.text_view_ingredient_name);
tvIngredientQuantity =(TextView)itemView.findViewById(R.id.text_view_quantity);
tvIngredientMeasure = (TextView)itemView.findViewById(R.id.text_view_measure);
}
void bind(Context context, IngredientModel ingredientModel) {
mContext = context;
mIngredient = ingredientModel;
tvIngredientName.setText(mIngredient.getIngredient());
tvIngredientQuantity.setText(mIngredient.getQuantity());
tvIngredientMeasure.setText(mIngredient.getMeasure());
}
}
}
Although, it is difficult to decipher from the code you have pasted,
it looks like the problem is with the following function:
#Override
public int getItemCount() {
if (mIngredientList != null) {
return 0;
} else {
return mIngredientList.size();
}
}
Changing condition to if (mIngredientList == null) { should solve the problem.
Also, in the RecipeDetailActivity.onCreate() method, only following code should be enough to display the list:
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recipe_detail);
rvIngredientList = (RecyclerView) findViewById(R.id.rv_ingredient_list);
rvIngredientList.setLayoutManager(new LinearLayoutManager(this));
mRecipe = getIntent().getParcelableExtra("com.wernerraubenheimer.bakingapp.data.RecipeModel");
mIngredientList = mRecipe.getIngredients();
ingredientListAdapter = new IngredientListAdapter(mIngredientList);
rvIngredientList.setAdapter(ingredientListAdapter);
}

Recyclerview initially not scrolling smoothly while loading data from web service

I'm using recycler view as a single child inside the swipe refresh layout. Initially, its not scrolling smoothly while loading data from webservice both upwards and downwards. But after first scroll, it scrolls smoothly. How to make it scroll smoothly at very first scroll itself.
private RecyclerView newsFeedList;
newsFeedList = (RecyclerView) view.findViewById(R.id.rv_feed_list);
newsFeedList.setHasFixedSize(true);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
llm.setOrientation(LinearLayoutManager.VERTICAL);
newsFeedList.setLayoutManager(llm);
newsFeedAdapter = new NewsFeedAdapter(getActivity(), new ArrayList<NewsFeedParser.NewsFeed>(), newsFeedList);
newsFeedList.setAdapter(newsFeedAdapter);
and updated recyclerview after getting response from web service by calling below method:
private void parseDataToNewsFeed(String response, boolean isLoadMore) {
Gson gson = new Gson();
NewsFeedParser newsFeedParser = gson.fromJson(response, NewsFeedParser.class);
if (newsFeedParser.data != null && newsFeedParser.data.size() > 0) {
if (isLoadMore) {
newsFeedAdapter.removeProgress(newsFeedAdapter.getItemCount());
newsFeedAdapter.addList(newsFeedParser.data);
} else {
currentPageCount = 1;
newsFeedAdapter.updateList(newsFeedParser.data);
}
} else {
newsFeedAdapter.updateList(newsFeedParser.data);
txtNoResult.setText(getString(R.string.no_clubs_socities_subscribed));
txtNoResult.setVisibility(View.VISIBLE);
}
}
Adaper class:
public class NewsFeedAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final DisplayImageOptions options;
private Context context;
private ArrayList<NewsFeedParser.NewsFeed> itemList;
private int lastVisibleItem, totalItemCount, visibleThreshold = 2;
private boolean loading;
public OnLoadMoreListener onLoadMoreListener;
private OnItemClickListener itemClickListener;
// private ImageLoader mImageLoader;
private final int VIEW_ITEM = 1;
private final int VIEW_PROG = 0;
private long mLastClickTimeListViewItem = 0;
public NewsFeedAdapter(Context context, ArrayList<NewsFeedParser.NewsFeed> itemList, RecyclerView recyclerView) {
this.context = context;
this.itemList = itemList;
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_default_news)
.showImageForEmptyUri(R.drawable.ic_default_news)
.showImageOnFail(R.drawable.ic_default_news)
.cacheInMemory(true)
.cacheOnDisk(true)
.considerExifParams(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.build();
if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) {
final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
totalItemCount = linearLayoutManager.getItemCount();
lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
if (!loading && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
if (onLoadMoreListener != null) {
onLoadMoreListener.onLoadMore();
}
loading = true;
}
}
});
}
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder vh;
if (viewType == VIEW_ITEM) {
View itemView = LayoutInflater.from(context).inflate(R.layout.fragment_news_feed_trending_list_item, parent, false);
vh = new NewsFeedViewHolder(itemView);
} else {
View progView = LayoutInflater.from(context).inflate(R.layout.view_refresh_footer, parent, false);
vh = new ProgressViewHolder(progView);
}
return vh;
}
#Override
public int getItemViewType(int position) {
return itemList.get(position) != null ? VIEW_ITEM : VIEW_PROG;
}
#Override
public int getItemCount() {
return itemList.size();
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
if (holder instanceof NewsFeedViewHolder) {
final NewsFeedParser.NewsFeed singleItem = itemList.get(position);
((NewsFeedViewHolder) holder).txtNews.setText(Html.fromHtml(singleItem.title));
((NewsFeedViewHolder) holder).txtDays.setText(DateConversion.getStatusTiming(context, singleItem.modified));
((NewsFeedViewHolder) holder).imgNewsPhoto.setImageResource(R.drawable.ic_default_news);
if (singleItem.featured_image != null) {
if (singleItem.featured_image.attachment_meta != null) {
if (singleItem.featured_image.attachment_meta.sizes != null) {
if (singleItem.featured_image.attachment_meta.sizes.thumbnail != null) {
if (!TextUtils.isNullOrEmpty(singleItem.featured_image.attachment_meta.sizes.thumbnail.url)) {
ImageLoader.getInstance().displayImage(singleItem.featured_image.attachment_meta.sizes.thumbnail.url, ((NewsFeedViewHolder) holder).imgNewsPhoto, options);
} else {
if (!TextUtils.isNullOrEmpty(singleItem.featured_image.source)) {
ImageLoader.getInstance().displayImage(singleItem.featured_image.source, ((NewsFeedViewHolder) holder).imgNewsPhoto, options);
}
}
}
}
}
}
if (singleItem.read_status == 0) {
((NewsFeedViewHolder) holder).rlFeedItem.setBackgroundColor(ContextCompat.getColor(context, R.color.clr_news_feed_item_bg));
} else {
((NewsFeedViewHolder) holder).rlFeedItem.setBackgroundColor(ContextCompat.getColor(context, R.color.transparent));
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (SystemClock.elapsedRealtime() - mLastClickTimeListViewItem < 1000) {
return;
}
mLastClickTimeListViewItem = SystemClock.elapsedRealtime();
if (itemClickListener != null) {
itemClickListener.onItemClick(singleItem);
singleItem.read_status = 1;
notifyItemChanged(position);
}
}
});
} else {
((ProgressViewHolder) holder).progressBar.setLinearProgress(true);
}
}
public void addList(ArrayList<NewsFeedParser.NewsFeed> items) {
if (items == null) {
this.itemList.add(null);
} else {
for (NewsFeedParser.NewsFeed item : items) {
this.itemList.add(item);
}
}
notifyDataSetChanged();
}
public void updateList(ArrayList<NewsFeedParser.NewsFeed> items) {
if (items != null) {
this.itemList = items;
}
notifyDataSetChanged();
}
public void removeProgress(int itemCount) {
this.itemList.remove(itemCount - 1);
notifyItemRemoved(itemCount);
}
public static class NewsFeedViewHolder extends RecyclerView.ViewHolder {
USUTextView txtNews, txtDays;
ImageView imgNewsPhoto;
RelativeLayout rlFeedItem;
public NewsFeedViewHolder(View itemView) {
super(itemView);
txtNews = (USUTextView) itemView.findViewById(R.id.txt_news);
txtDays = (USUTextView) itemView.findViewById(R.id.txt_days);
imgNewsPhoto = (ImageView) itemView.findViewById(R.id.img_news_photo);
rlFeedItem = (RelativeLayout) itemView.findViewById(R.id.rl_feed_list_item);
}
}
public static class ProgressViewHolder extends RecyclerView.ViewHolder {
public ProgressWheel progressBar;
public ProgressViewHolder(View progView) {
super(progView);
progressBar = (ProgressWheel) progView.findViewById(R.id.progress_bar);
}
}
public void setLoaded() {
loading = false;
}
public void setOnLoadMoreListener(OnLoadMoreListener onLoadMoreListener) {
this.onLoadMoreListener = onLoadMoreListener;
}
public interface OnLoadMoreListener {
void onLoadMore();
}
public void setOnItemClickListener(OnItemClickListener recyclerClickListener) {
this.itemClickListener = recyclerClickListener;
}
public interface OnItemClickListener {
void onItemClick(NewsFeedParser.NewsFeed item);
}
}
Please suggest me any idea.....

getFilter()' on a null object reference

i'm trying to implement search on my list view
this is my custom adapter:
public class AllContactsAdapter extends BaseAdapter implements Filterable {
Context context;
ArrayList<Contact> contactList;
ArrayList<Contact> mStringFilterList;
ValueFilter valueFilter;
public AllContactsAdapter(Context context, ArrayList<Contact> list) {
this.context = context;
contactList = list;
mStringFilterList = list;
}
#Override
public int getCount() {
return contactList.size();
}
#Override
public Object getItem(int position) {
return contactList.get(position);
}
#Override
public long getItemId(int position) {
return contactList.get(position).getID();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Contact item = contactList.get(position);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.row_name_phone_view, null);
}
TextView name = (TextView) convertView.findViewById(R.id.txtAllFullName);
name.setText(item.getName());
TextView phone = (TextView) convertView.findViewById(R.id.txtAllPhoneNumber);
phone.setText(item.getPhoneNumber());
return convertView;
}
#Override
public Filter getFilter() {
if (valueFilter == null) {
valueFilter = new ValueFilter();
}
return valueFilter;
}
private class ValueFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null && constraint.length() > 0) {
ArrayList<Contact> filterList = new ArrayList<Contact>();
for (int i = 0; i < mStringFilterList.size(); i++) {
if ((mStringFilterList.get(i).getName().toUpperCase())
.contains(constraint.toString().toUpperCase())) {
Contact contact = new Contact(mStringFilterList.get(i)
.getName(), mStringFilterList.get(i)
.getPhoneNumber());
filterList.add(contact);
}
}
results.count = filterList.size();
results.values = filterList;
} else {
results.count = mStringFilterList.size();
results.values = mStringFilterList;
}
return results;
}
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
contactList = (ArrayList<Contact>) results.values;
notifyDataSetChanged();
}
}
}
this is my call in main activity:
#Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}
i'm getting this error:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.widget.Filter com.example.shaka.contactsmanager.AllContactsAdapter.getFilter()' on a null object reference
can you please help me?
The variable adapter is null and you're trying to call the method getFilter() on it.
You need to initialize the adapter variable before using it. I can't be sure of how to do it because I can't see the MainActivity code, but it's definetely this problem.