Delete duplicates items from my ArrayList of MyModel - arraylist

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();
}

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);
}

RecyclerView: incorrect binding when items are recycled

Each item in my RecyclerView consists of 4 EditTexts.
As long as no item is recycled, my app can change the text in any of these EditTexts.
However, as soon as items are recycled, only the first (I mean the leftmost) Edittext in the item can be updated correctly, whatever the selection.
Any idea of what could go wrong?
This is the top of the stack:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: be.ema.moles, PID: 8968
java.lang.NullPointerException: Attempt to invoke virtual method 'int androidx.recyclerview.widget.RecyclerView$ViewHolder.getAdapterPosition()' on a null object reference
at androidx.recyclerview.selection.StableIdKeyProvider.onDetached(StableIdKeyProvider.java:90)
at androidx.recyclerview.selection.StableIdKeyProvider$1.onChildViewDetachedFromWindow(StableIdKeyProvider.java:69)
at androidx.recyclerview.widget.RecyclerView.dispatchChildDetached(RecyclerView.java:7261)
at androidx.recyclerview.widget.RecyclerView.removeDetachedView(RecyclerView.java:4139)
at androidx.recyclerview.widget.RecyclerView$LayoutManager.removeAndRecycleScrapInt(RecyclerView.java:8978)
at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep3(RecyclerView.java:3997)
at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3652)
at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4194)
at android.view.View.layout(View.java:20672)
...
Here is the Fragment controlling the contents of the RecyclerView
public class MoleFragment extends Fragment {
RecyclerView moleRecycler = null;
TextView addBtn = null;
Cursor moleCursor = null;
static int moleAdapterPosition = 0;
static String moleId = "";
static String contactId = "";
static String rawContactId = "";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.moles_layout, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final Cursor moleCursor = readMoles();
moleRecycler = (RecyclerView) getActivity().findViewById(R.id.moles);
moleRecycler.setHasFixedSize(true);
moleRecycler.setLayoutManager(new LinearLayoutManager(getActivity()));
moleRecycler.setAdapter(new MolesCursorAdapter(getActivity(), moleCursor));
OnItemActivatedListener<Long> moleItemActivatedListener = new OnItemActivatedListener() {
#Override
public boolean onItemActivated(#NonNull ItemDetailsLookup.ItemDetails item, #NonNull MotionEvent e) {
moleAdapterPosition = item.getPosition();
moleCursor.moveToPosition(item.getPosition());
moleId = Long.toString(moleCursor.getLong(0));
return true;
}
};
SelectionTracker moleTracker = new SelectionTracker.Builder<Long>("selectedMoleId",
moleRecycler,
new StableIdKeyProvider(moleRecycler),
new MoleDetailsLookup(),
StorageStrategy.createLongStorage())
.withSelectionPredicate(SelectionPredicates.<Long>createSelectSingleAnything())
.withOnItemActivatedListener(moleItemActivatedListener)
.build();
return ;
}
public Cursor readMoles() {
String[] contactIds = getShownCustomer();
String selection = Data.RAW_CONTACT_ID + "=? AND " + Data.CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?";
String[] selectionArgs = new String[]{contactIds[0], contactIds[1], MOLE_MIME_TYPE};
return moleCursor = getActivity().getContentResolver().query(
Data.CONTENT_URI,
new String[] {
Data._ID,
Data.DATA1,
Data.DATA2,
Data.DATA3,
Data.DATA4},
selection,
selectionArgs,
null
);
}
/**
* Create a new instance of DetailsFragment, initialized to
* show the catches for customer 'contactId'.
*/
public static MoleFragment newInstance(String rawContactId, String contactId) {
MoleFragment f = new MoleFragment();
// Supply index input as an argument.
Bundle args = new Bundle();
args.putString("rawContactId", rawContactId);
args.putString("contactId", contactId);
f.setArguments(args);
return f;
}
public String[] getShownCustomer() {
rawContactId = getArguments().getString("rawContactId", "");
contactId = getArguments().getString("contactId", "");
String[] contactIds = new String[2];
contactIds[0] = getArguments().getString("rawContactId", "");
contactIds[1] = getArguments().getString("contactId", "");
return contactIds;
}
private class MoleDetailsLookup extends ItemDetailsLookup<Long> {
#Nullable
#Override
public ItemDetails<Long> getItemDetails(#NonNull MotionEvent event) {
View view = moleRecycler.findChildViewUnder(event.getX(), event.getY());
if (view != null) {
final RecyclerView.ViewHolder viewHolder = moleRecycler.getChildViewHolder(view);
if (viewHolder instanceof MolesCursorAdapter.ViewHolder) {
final MolesCursorAdapter.ViewHolder moleViewHolder = (MolesCursorAdapter.ViewHolder) viewHolder;
return new ItemDetailsLookup.ItemDetails<Long>() {
#Override
public int getPosition() {
return viewHolder.getAdapterPosition();
}
#Nullable
#Override
public Long getSelectionKey() {
return Long.valueOf(moleViewHolder.position);
}
};
}
}
return null;
}
}
}
And this is the RecyclerView.Adapater
public class MolesCursorAdapter extends RecyclerView.Adapter<MolesCursorAdapter.ViewHolder> {
private CursorAdapter mCursorAdapter;
private Context mContext;
private ViewHolder holder;
public MolesCursorAdapter(Context context, Cursor c) {
mContext = context;
mCursorAdapter = new CursorAdapter(mContext, c, 0) {
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View v = LayoutInflater.from(context).inflate(R.layout.moles, parent, false);
return v;
}
#Override
public void bindView(View view, final Context context, final Cursor cursor) {
String s = cursor.getString(1);
if (s != null) {
holder.startDate.setText(s.substring(6, 8) + "/" + s.substring(4, 6) + "/" + s.substring(0, 4));
} else {
holder.startDate.setText("");
}
s = cursor.getString(2);
if (s != null) {
s = s.substring(6,8) + "/" + s.substring(4,6) + "/" + s.substring(0,4);
holder.endDate.setText(s);
} else {
holder.endDate.setText("");
}
holder.round.setText(cursor.getString(3));
holder.moleType.setText(cursor.getString(4));
}
};
}
public class ViewHolder extends RecyclerView.ViewHolder implements TextWatcher {
public int position;
public EditText startDate;
public EditText endDate;
public EditText round;
public EditText moleType;
public TextView deleteBtn;
public ViewHolder(View itemView) {
super(itemView);
startDate = (EditText) itemView.findViewById(R.id.startDate);
endDate = (EditText) itemView.findViewById(R.id.endDate);
round = (EditText) itemView.findViewById(R.id.round);
moleType = (EditText) itemView.findViewById(R.id.moleType);
deleteBtn = (TextView) itemView.findViewById(R.id.deleteBtn);
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
String value = s.toString();
ContentValues newValues = new ContentValues();
if (TextUtils.isDigitsOnly(s)) {
newValues.put(ContactsContract.Data.DATA3, value);
} else {
newValues.put(ContactsContract.Data.DATA4, value);
}
updateRepository(newValues);
}
}
#Override
public int getItemCount() {
return mCursorAdapter.getCount();
}
#Override
public long getItemId(int position) {
return Long.valueOf(position);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
// Passing the binding operation to cursor loader
mCursorAdapter.getCursor().moveToPosition(position);
mCursorAdapter.bindView(holder.itemView, mContext, mCursorAdapter.getCursor());
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
TextWatcher tw = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
String value = s.toString();
ContentValues newValues = new ContentValues();
if (TextUtils.isDigitsOnly(s)) {
newValues.put(ContactsContract.Data.DATA3, value);
} else {
newValues.put(ContactsContract.Data.DATA4, value);
}
updateRepository(newValues);
}
};
View v = mCursorAdapter.newView(mContext, mCursorAdapter.getCursor(), parent);
holder = new ViewHolder(v);
holder.startDate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
// business logic
}
});
holder.endDate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
// business logic
}
});
holder.round.addTextChangedListener(tw);
holder.moleType.addTextChangedListener(tw);
holder.deleteBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String selectionClause = ContactsContract.Data._ID + "=?";
String[] selectionArgs = new String[] {mCursorAdapter.getCursor().getString(0)};
int rowsDeleted = mContext.getContentResolver().delete(
ContactsContract.Data.CONTENT_URI,
selectionClause,
selectionArgs
);
}
});
return holder;
}
}
Instead of adding a ClickListener on each View in the ViewHolder in the onCreateViewHolder method, I have added a unique tag on each View. This unique tag is used in a general (I mean at Class level) ClickListener to perform the business logic:
public class MolesCursorAdapter3 extends RecyclerView.Adapter<MolesCursorAdapter3.MolesViewHolder> {
private CursorAdapter mCursorAdapter;
private Context mContext;
public ConstraintLayout holder;
public EditText startDate;
public EditText endDate;
public EditText round;
public EditText moleType;
public TextView deleteBtn;
public class MolesViewHolder extends RecyclerView.ViewHolder implements TextWatcher, View.OnClickListener {
public int position;
public String vhMoledId = "";
public MolesViewHolder(ConstraintLayout itemView) {
super(itemView);
holder = itemView;
startDate = (EditText) itemView.findViewById(R.id.startDate);
startDate.setOnClickListener(this);
endDate = (EditText) itemView.findViewById(R.id.endDate);
endDate.setOnClickListener(this);
round = (EditText) itemView.findViewById(R.id.round);
round.addTextChangedListener(this);
moleType = (EditText) itemView.findViewById(R.id.moleType);
moleType.addTextChangedListener(this);
deleteBtn = (TextView) itemView.findViewById(R.id.deleteBtn);
deleteBtn.setOnClickListener(this);
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
String value = s.toString();
ContentValues newValues = new ContentValues();
if (TextUtils.isDigitsOnly(s)) {
newValues.put(ContactsContract.Data.DATA3, value);
} else {
newValues.put(ContactsContract.Data.DATA4, value);
}
updateRepository(newValues, vhMoledId);
}
#Override
public void onClick(final View v) {
String tag = (String) v.getTag();
String viewTag = tag.substring(0, 3);
final String moleId = tag.substring(3);
switch (viewTag) {
case "del":
// business logic
break;
case "sta":
ConstraintLayout vh = (ConstraintLayout) v.getParent();
endDate = vh.findViewWithTag("end" + moleId);
// business logic
break;
case "end":
vh = (ConstraintLayout) v.getParent();
startDate = vh.findViewWithTag("sta" + moleId);
// business logic
break;
}
}
}
public MolesCursorAdapter3(Context context, Cursor c) {
mContext = context;
mCursorAdapter = new CursorAdapter(mContext, c, 0) {
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View v = LayoutInflater.from(context).inflate(R.layout.moles, parent, false);
return v;
}
#Override
public void bindView(View itemView, final Context context, final Cursor cursor) {
ConstraintLayout vh = (ConstraintLayout) itemView;
String moleId = cursor.getString(0);
startDate = (EditText) vh.findViewById(R.id.startDate);
startDate.setTag("sta" + moleId);
endDate = (EditText) vh.findViewById(R.id.endDate);
endDate.setTag("end" + moleId);
round = (EditText) vh.findViewById(R.id.round);
moleType = (EditText) vh.findViewById(R.id.moleType);
deleteBtn = (TextView) vh.findViewById(R.id.deleteBtn);
deleteBtn.setTag("del" + moleId);
String s = cursor.getString(1);
if (s != null) {
startDate.setText(s.substring(6, 8) + "/" + s.substring(4, 6) + "/" + s.substring(0, 4));
} else {
startDate.setText("");
}
s = cursor.getString(2);
if (s != null) {
s = s.substring(6,8) + "/" + s.substring(4,6) + "/" + s.substring(0,4);
endDate.setText(s);
} else {
endDate.setText("");
}
round.setText(cursor.getString(3));
moleType.setText(cursor.getString(4));
}
};
}
#Override
public MolesCursorAdapter3.MolesViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ConstraintLayout molesLayout = (ConstraintLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.moles, parent, false);
MolesViewHolder vh = new MolesViewHolder(molesLayout);
return vh;
}
#Override
public void onBindViewHolder(#NonNull MolesViewHolder holder, int position) {
// Passing the binding operation to cursor loader
mCursorAdapter.getCursor().moveToPosition(position);
mCursorAdapter.bindView(holder.itemView, mContext, mCursorAdapter.getCursor());
holder.vhMoledId = mCursorAdapter.getCursor().getString(0);
holder.position = position;
}
#Override
public int getItemCount() {
return mCursorAdapter.getCount();
}
#Override
public long getItemId(int position) {
return Long.valueOf(position);
}
public void updateRepository(ContentValues newValues, String moleId) {
final String selection = ContactsContract.Data.MIMETYPE + " = ? AND " + ContactsContract.Data._ID + " = ?";
final String[] selectionArgs = new String[]{MOLE_MIME_TYPE, moleId};
int rowsUpdated = mContext.getContentResolver().update(
ContactsContract.Data.CONTENT_URI,
newValues,
selection,
selectionArgs
);
}
}

Loading more data in recyclerview on scroll

I am getting Json data in list which has like 100 of items. I am passing this list to the recyclerview adapter. But i want to pass only 10 items at first. after 10 items when user scrolls the list it should load more data from the list.I have Implemented the scroll listeners and other adapter.I am not sure how to pass 10 items from the json list to adapter.
ScrollListener
public abstract class PaginationScrollListener extends RecyclerView.OnScrollListener {
LinearLayoutManager layoutManager;
/**
* Supporting only LinearLayoutManager for now.
*
* #param layoutManager
*/
public PaginationScrollListener(LinearLayoutManager layoutManager) {
this.layoutManager = layoutManager;
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visibleItemCount = layoutManager.getChildCount();
int totalItemCount = layoutManager.getItemCount();
int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition();
if (!isLoading() && !isLastPage()) {
if ((visibleItemCount + firstVisibleItemPosition) >= totalItemCount
&& firstVisibleItemPosition >= 0
&& totalItemCount >= getTotalPageCount()) {
loadMoreItems();
}
}
}
protected abstract void loadMoreItems();
public abstract int getTotalPageCount();
public abstract boolean isLastPage();
public abstract boolean isLoading();
}
Adapter
public class PaginationAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int ITEM = 0;
private static final int LOADING = 1;
private List<Movie> movies;
private Context context;
private boolean isLoadingAdded = false;
public PaginationAdapter(Context context) {
this.context = context;
movies = new ArrayList<>();
}
public List<Movie> getMovies() {
return movies;
}
public void setMovies(List<Movie> movies) {
this.movies = movies;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType) {
case ITEM:
viewHolder = getViewHolder(parent, inflater);
break;
case LOADING:
View v2 = inflater.inflate(R.layout.item_progress, parent, false);
viewHolder = new LoadingVH(v2);
break;
}
return viewHolder;
}
#NonNull
private RecyclerView.ViewHolder getViewHolder(ViewGroup parent, LayoutInflater inflater) {
RecyclerView.ViewHolder viewHolder;
View v1 = inflater.inflate(R.layout.item_list, parent, false);
viewHolder = new MovieVH(v1);
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
Movie movie = movies.get(position);
switch (getItemViewType(position)) {
case ITEM:
MovieVH movieVH = (MovieVH) holder;
movieVH.textView.setText(movie.getTitle());
break;
case LOADING:
break;
}
}
#Override
public int getItemCount() {
return movies == null ? 0 : movies.size();
}
#Override
public int getItemViewType(int position) {
return (position == movies.size() - 1 && isLoadingAdded) ? LOADING : ITEM;
}
public void add(Movie mc) {
movies.add(mc);
notifyItemInserted(movies.size() - 1);
}
public void addAll(List<Movie> mcList) {
for (Movie mc : mcList) {
add(mc);
}
}
public void remove(Movie city) {
int position = movies.indexOf(city);
if (position > -1) {
movies.remove(position);
notifyItemRemoved(position);
}
}
public void clear() {
isLoadingAdded = false;
while (getItemCount() > 0) {
remove(getItem(0));
}
}
public boolean isEmpty() {
return getItemCount() == 0;
}
public void addLoadingFooter() {
isLoadingAdded = true;
add(new Movie());
}
public void removeLoadingFooter() {
isLoadingAdded = false;
int position = movies.size() - 1;
Movie item = getItem(position);
if (item != null) {
movies.remove(position);
notifyItemRemoved(position);
}
}
public Movie getItem(int position) {
return movies.get(position);
}
public MovieVH(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.item_text);
}
}
protected class LoadingVH extends RecyclerView.ViewHolder {
public LoadingVH(View itemView) {
super(itemView);
}
}
}
**Getting Api response **
private void callApi() {
apiInterfacePages = ApiClient.getRetrofit().create(APIInterface.class);
Call<CamerasItem> camerasCall = apiInterfacePages.getCameras();
camerasCall.enqueue(new Callback<CamerasItem>() {
#Override
public void onResponse(Call<CamerasItem> call, Response<CamerasItem> response) {
CamerasItem camerasItem = response.body();
itemList = new ArrayList<>();
itemList = camerasItem.getItems();
Log.i("Item", "" + getChannel().getName());
for (int i = 0; i < itemList.size(); i++) {
if (itemList.get(i).getCategory().equals(getChannel().getName())){
if (!itemList.get(i).getUrlMjpeg().endsWith("=mediaRedirect")) {
String videoUrl = itemList.get(i).getUrlMjpeg();
String imageUrl = itemList.get(i).getThumbnail();
String name = itemList.get(i).getName();
String city = itemList.get(i).getCity();
String flag = itemList.get(i).getFlag();
String country= itemList.get(i).getCountry();
modelList.add(new MyModel(videoUrl, imageUrl, name, city, flag,country));
}
}
}
#Override
public void onFailure(Call<CamerasItem> call, Throwable t) {
Log.i("Item", "" + t.getMessage());
}
});
}
So now how to pass to 10 items to recyclerview for the first time and 10 items at each scroll.
You have to set Progressbar inside the activity's xml where Recyclerview is defined.
and loadThumbnail is a function to download thumbnail. it just gives a little delay to scroll down. Now the complete code for the adapter class is as following
public class CamerasAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<MyModel> list;
private Activity mActivity;
private static final int TYPE_VIDEO = 0, TYPE_ADD = 1;
private static final int PAGE_LIMIT = 5;
private int mCurrentLimit = PAGE_LIMIT;
private boolean mIsLoading;
RelativeLayout mLoaderProgress;
public CamerasAdapter(FragmentActivity activity, RelativeLayout loaderLayout) {
mActivity = activity;
mLoaderProgress = loaderLayout;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.li_web_cam_view, viewGroup, false);
return new CamsViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder viewHolder, int i) {
if (mCurrentLimit == (i + 1) && mCurrentLimit <= list.size() && !mIsLoading) {
mLoaderProgress.setVisibility(View.VISIBLE);
mIsLoading = true;
loadThumbnail(0, i + 1);
} else {
//do nothing
}
((CamsViewHolder) viewHolder).onBindData(mActivity, list.get(i), i);
((CamsViewHolder) viewHolder).emptyView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
itemClickListner.onClick(i, ((CamsViewHolder) viewHolder).tvCamName, list.get(i));
}
});
}
private void loadThumbnail(final int count, int position) {
try {
if (count > 2 || position >= list.size()) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
mIsLoading = false;
mCurrentLimit = mCurrentLimit + PAGE_LIMIT;
notifyItemChanged(position - count);
mLoaderProgress.setVisibility(View.GONE);
return;
}
}, 2000);
} else {
if (list.get(position) == null) {
loadThumbnail(count, position + 1);
} else {
Glide.with(mActivity).load(list.get(position).getImage_url()).downloadOnly(new SimpleTarget<File>() {
#Override
public void onResourceReady(File resource, GlideAnimation<? super File> glideAnimation) {
loadThumbnail((count + 1), (position + 1));
}
#Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
loadThumbnail((count + 1), (position + 1));
}
});
}
}
} catch (Exception e) {
e.printStackTrace();
mLoaderProgress.setVisibility(View.GONE);
mIsLoading = false;
}
}
#Override
public int getItemCount() {
return mCurrentLimit <= list.size() ? mCurrentLimit : list.size();
}
public void setData(List<MyModel> dataList) {
this.list = dataList;
notifyDataSetChanged();
}
ItemClickListner itemClickListner;
public void setListener(ItemClickListner listener) {
itemClickListner = listener;
}
ProgressLoadListener progressLoadListener;
public void setProgressLoadListener(ProgressLoadListener listener) {
progressLoadListener = listener;
}
}
code for xml file
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:visibility="gone"
android:layout_height="match_parent"
android:layout_above="#+id/loader_progress_bar_layout"
android:background="#f5f5f5"
android:layout_gravity="center" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:id="#+id/loader_progress_bar_layout"
android:visibility="gone"
android:background="#fff"
>
<ProgressBar
android:id="#+id/progress_bar_loader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_gravity="center" />
</RelativeLayout>
initialize Recyclerview with adapter
public class Main2Activity extends AppCompatActivity {
RecyclerView recyclerView;
RelativeLayout layoutProgressBar;
CamerasAdapter adapter;
List<Item> itemList;
LinearLayoutManager mLayoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
layoutProgressBar = findViewById(R.id.loader_progress_bar_layout);
recyclerView = findViewById(R.id.recycler_view);
adapter = new CamerasAdapter(getActivity(), loaderLayout);
mLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setAdapter(adapter);
adapter.setProgressLoadListener(new ProgressLoadListener() {
#Override
public void loadProgressBar() {
layoutProgressBar.setVisibility(View.VISIBLE);
}
});
adapter.setData(setAdaperData());
}
public List<MyModel> setAdaperData(){
List<MyModel> modelList = new ArrayList<>();
/*addItemsto list*/
return modelList;
}
}

Android recycleView displaying an emply list

Please i need help on this one. Have been working on it for days but cant figure it out.
I have a recycleView to display a list of names but its displaying empty list, but i can print the list in console.
here,s the code fetching the list
public List<BackendlessUser> userList = new ArrayList<BackendlessUser>();
BackendlessDataQuery query = new BackendlessDataQuery();
Backendless.Data.of( BackendlessUser.class ).find( query, new AsyncCallback<BackendlessCollection<BackendlessUser>>()
{
#Override
public void handleResponse( BackendlessCollection<BackendlessUser> response )
{
userList = response.getCurrentPage();
for( BackendlessUser user : userList ){
Log.d( "USERS : ", user.getEmail() );
}
Log.d("USER LIST", String.valueOf( userList.size() ));
}
#Override
public void handleFault(BackendlessFault backendlessFault) {
}
});
and the recyclerView adapter that is supposed to adapt the list to the view ..
private void setupRecyclerView(#NonNull RecyclerView recyclerView) {
recyclerView.setAdapter(new SimpleItemRecyclerViewAdapter(userList));
}
public class SimpleItemRecyclerViewAdapter
extends RecyclerView.Adapter<SimpleItemRecyclerViewAdapter.ViewHolder> {
private final List<BackendlessUser> mValues;
public SimpleItemRecyclerViewAdapter(List<BackendlessUser> items) {
mValues = items;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_list_content, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.mItem = mValues.get(position);
holder.mIdView.setText(mValues.get(position).getProperty("idno").toString());
holder.mContentView.setText(mValues.get(position).getProperty("fname").toString());
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mTwoPane) {
Bundle arguments = new Bundle();
arguments.putString(ItemDetailFragment.ARG_ITEM_ID, holder.mItem.getProperty("idno").toString());
ItemDetailFragment fragment = new ItemDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.item_detail_container, fragment)
.commit();
} else {
Context context = v.getContext();
Intent intent = new Intent(context, ItemDetailActivity.class);
intent.putExtra(ItemDetailFragment.ARG_ITEM_ID, holder.mItem.getProperty("idno").toString());
context.startActivity(intent);
}
}
});
}
#Override
public int getItemCount() {
return mValues.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
public final TextView mIdView;
public final TextView mContentView;
public BackendlessUser mItem;
public ViewHolder(View view) {
super(view);
mView = view;
mIdView = (TextView) view.findViewById(R.id.id);
mContentView = (TextView) view.findViewById(R.id.content);
}
#Override
public String toString() {
return super.toString() + " '" + mContentView.getText() + "'";
}
}
}

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.