I have a custom ArrayAdapter<Summary> which holds a list of events. There are duplicate values in the List<Summary>, so I'm trying to put the values of List<Summary> to LinkedHashSet<Summary> but this displays a blank page.
How do I convert custom ArrayList to LinkedHashSet to get unique data?
Main.java:
LinkedHashSet<Summary> listToSet = new LinkedHashSet<Summary>();
final List<Summary> summaries = new ArrayList<Summary>();
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.events_summary, container, false);
.......
setListView(month, year, date_value);
summaryAdapter = new SummaryAdapter(this.getActivity().getApplicationContext(), R.layout.listview_item_row, listToSet);
calendarSummary = (ListView) v.findViewById(R.id.calendarSummary);
calendarSummary.setAdapter(summaryAdapter);
return v;
}
public void setListView(int month, int year, int dv) {
events = new HolidayEvents();
_calendar = Calendar.getInstance(Locale.getDefault());
int totalDays = _calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
for(int i = 1; i <= totalDays; i++){
if(isHoliday(i, month, year, dv))
{
date = i + " " + getMonthForInt(month-1) + " " + year;
for (Event event : events.eventDetails(this, month, i))
{
summaries.add(new Summary(date, event.eventdetails));
listToSet.addAll(summaries);
}
}
}
}
ArrayAdapter.java:
public class SummaryAdapter extends ArrayAdapter<Summary>{
Context context;
int layoutResourceId;
LayoutInflater mInflater;
LinkedHashSet<Summary> list = null;
List<Summary> data = null;
public SummaryAdapter(Context context, int layoutResourceId, LinkedHashSet<Summary> summaries) {
super(context, layoutResourceId);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.list = summaries;
data = new ArrayList<Summary>(list); //converting LinkedHashSet to List
mInflater = LayoutInflater.from(context);
}
....rest of the code retrieving data by using data.get(position) ...
You need to ensure that the class you are putting into Set properly overrides Equals and hashCode functions.
Lets have a look at case where hashCode is not overriden:
import java.util.*;
public class Example {
public static class Abc {
protected String s;
public Abc(String s) {
this.s = s;
}
#Override
public boolean equals(Object other) {
if (other instanceof Abc) {
return ((Abc) other).s.equals(this.s);
}
return false;
}
#Override
public int hashCode() {
return (int) (Math.random() * Integer.MAX_VALUE);
}
public String toString() {
return "Abc: " + this.s;
}
}
public static void main(String[] args) {
ArrayList<Abc> ar = new ArrayList<>();
ar.add(new Abc("a"));
ar.add(new Abc("a"));
ar.add(new Abc("a"));
LinkedHashSet<Abc> lhs = new LinkedHashSet<>(ar);
System.out.println("ar: " + ar);
System.out.println("LinkedHashSet: " + lhs);
}
}
This will produce:
ar: [Abc: a, Abc: a, Abc: a]
LinkedHashSet: [Abc: a, Abc: a, Abc: a]
even though equals are properly implemented.
I believe you may want to double-check proper implementation of both HashCodes and Equals.
Related
I'm using a hashmap to get data from another class. I check the logcat and the data for hashmap has been set and it contains the key. But when I try to get the hashmap from the other class I'm getting NullPointerException and when I try to check if the map contains the key it doesn't
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.continueItem:
CustomAdapter a = new CustomAdapter();
CustomAdapter.InputTextListener i = a.new InputTextListener();
HashMap<String, Integer> hashMap = i.getHashMap();
inputTime = hashMap.get("EDITTEXT VALUE");
Log.d(TAG, "onOptionsItemSelected: " + hashMap.get("EDITTEXT VALUE"));
Log.d(TAG, "onOptionsItemSelected: " + hashMap.containsKey("EDITTEXT VALUE"));
retrieveInputTime(inputTime);
break;
}
return super.onOptionsItemSelected(item);
}
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
private static final String TAG = "CustomAdapter";
private ArrayList<Integer> mWorkTW = new ArrayList<>();
private ArrayList<Integer> mWorkET = new ArrayList<>();
private ArrayList<Integer> mRestTW = new ArrayList<>();
private ArrayList<Integer> mRestET = new ArrayList<>();
private Context mContext;
private int numberOfIntervals;
public CustomAdapter() {
}
public CustomAdapter(Context context, ArrayList<Integer> mWorkTW, ArrayList<Integer> mWorkET, ArrayList<Integer> mRestTW, ArrayList<Integer> mRestET, int numberOfIntervals) {
this.mWorkTW = mWorkTW;
this.mWorkET = mWorkET;
this.mRestTW = mRestTW;
this.mRestET = mRestET;
this.mContext = context;
this.numberOfIntervals = numberOfIntervals;
//this.inputTimeIntegerWET = inputTimeIntegerWET;
Log.d(TAG, "CustomAdapter: " + numberOfIntervals);
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View customView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.time_row, viewGroup, false);
ViewHolder holder = new ViewHolder(customView, new InputTextListener());
return holder;
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder viewHolder, final int i) {
Log.d(TAG, "onBindViewHolder: called");
viewHolder.workTextView.setText(R.string.work_text_view);
viewHolder.restTextView.setText(R.string.rest_text_view);
viewHolder.workEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus)
viewHolder.workEditText.setHint("");
else
viewHolder.workEditText.setHint(mWorkET.get(viewHolder.getAdapterPosition()));
}
});
viewHolder.restEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus)
viewHolder.restEditText.setHint("");
else
viewHolder.restEditText.setHint(mRestET.get(viewHolder.getAdapterPosition()));
}
});
}
#Override
public int getItemCount() {
Log.d(TAG, "" + numberOfIntervals);
return numberOfIntervals;
}
public class ViewHolder extends RecyclerView.ViewHolder {
public InputTextListener inputTextListener;
TextView workTextView;
EditText workEditText;
TextView restTextView;
EditText restEditText;
ConstraintLayout parentLayout;
public ViewHolder(#NonNull View itemView, InputTextListener inputTextListener) {
super(itemView);
workTextView = itemView.findViewById(R.id.workTextView);
workEditText = itemView.findViewById(R.id.workEditText);
restTextView = itemView.findViewById(R.id.restTextView);
restEditText = itemView.findViewById(R.id.restEditText);
parentLayout = itemView.findViewById(R.id.parentLayout);
this.inputTextListener = inputTextListener;
workEditText.addTextChangedListener(inputTextListener);
}
}
class InputTextListener implements TextWatcher {
String inputTimeString;
int inputTime;
HashMap<String, Integer> hashMap = new HashMap<String, Integer>();
public HashMap<String, Integer> getHashMap() {
return hashMap;
}
public InputTextListener() {
}
public void setHashMap(HashMap<String, Integer> hashMap) {
this.hashMap = hashMap;
}
/*public int getInputTime() {
return inputTime;
}*/
public void setInputTime(int inputTime) {
this.inputTime= inputTime;
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
try {
Log.d(TAG, "onTextChanged: I've made it to here!");
inputTimeString = s.toString().trim();
inputTime = Integer.parseInt(inputTimeString);
setInputTime(inputTime);
hashMap.put("EDITTEXT VALUE", inputTime);
Log.d(TAG, "onTextChanged: " + inputTime);
int bla = inputTime + 2;
Log.d(TAG, "onTextChanged: " + bla);
Log.d(TAG, "onTextChanged: " + hashMap.containsKey("EDITTEXT VALUE"));
Log.d(TAG, "onTextChanged: " + hashMap.get("EDITTEXT VALUE"));
setHashMap(hashMap);
} catch (NumberFormatException NFE) {
mWorkET = null;
}
}
#Override
public void afterTextChanged(Editable s) {
}
}
}
I'm expecting for the hashmap being able to access the data from the other class.
Here is some of the code you posted:
CustomAdapter a = new CustomAdapter();
CustomAdapter.InputTextListener i = a.new InputTextListener();
HashMap<String, Integer> hashMap = i.getHashMap();
What this is going to do is create a new instance of your CustomAdapter class, then create a new instance of your InputTextListener class, and finally retrieve the HashMap stored inside the text listener.
Again, this is all happening with new instances of these classes. Therefore, the HashMap is empty (since nothing has populated it).
You are probably assuming that i would be the "same" listener instance as you're using elsewhere in your app. This is not the case. You will need to access that listener somehow rather than creating a new instance.
Looking at your code, this doesn't really seem feasible. Each ViewHolder has its own instance of InputTextListener... how will your options menu know which ViewHolder you're trying to interact with?
Chances are good that you're going to need to go back to the drawing board and come up with a different way to solve whatever problem you're attempting.
public class Item {
//declare private data instead of public to ensure the privacy of data field of each class
private String It;
private String Title;
public Item(String item, String hometown) {
this.It = item;
this.Title = hometown;
}
//retrieve user's name
public String getIt(){
return It;
}
//retrieve users' hometown
public String getTitle(){
return Title;
}
public static ArrayList<Item > getItem() {
ArrayList<Item> item = new ArrayList<Item>();
item.add(new Item("Harry", "San Diego"));
item.add(new Item("Marla", "San Francisco"));
item.add(new Item("Sarah", "San Marco"));
return item;
}
}
public class UsersAdapter extends ArrayAdapter<Item> {
public UsersAdapter(Context context, ArrayList<Item> it) {
super(context, 0, it);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Item item = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_user, parent, false);
}
// Lookup view for data population
TextView tv1 = (TextView) convertView.findViewById(R.id.tv1);
TextView tv2 = (TextView) convertView.findViewById(R.id.tv2);
// Populate the data into the template view using the data object
String tv = String.valueOf(Item.**getItem**()); //.toString();
tv1.setText(tv);
String title = Title.getText().toString();
tv2.setText(title);
// Return the completed view to render on screen
return convertView;
}
I'm currently looking up how custom arrays and whatnot work.I thought I out something decent together until my getItem started getting treated like an integer. Android tells me to change the return to int but that would be counter productive. When I try using toString or String.valueOf, I just get a long string of text in my listview item. Can anyone tell what I might be doing wrong here?
public String toString() is never implemented for Item, so instead of returning the data like in a language such as javascript, it returns the location in memory of the Item.
Example:
public static void main(String[] args) {
ArrayList<Item> list = new ArrayList<Item>();
list.add(new Item("foo", "bar"));
list.add(new Item("Stuff", "Bla"));
System.out.println(list);
}
public class Item {
String a, b;
public Item(String a, String b) {
this.a = a;
this.b = b;
}
}
Output:
[Item#4554617c, Item#74a14482]
Explanation:
When java is unsure how to convert something to a String it gives type#address. For example if you had a node
class Node {
Node next;
}
and then did
Node A = new Node();
Node B = new Node();
A.next = B;
B.next = A;
String.valueOf(A);
You would get an infinite loop which would end in your program erroring. Java handles this by just not going to the effort of showing the contents.
Fix:
The solution is to implement toString() so that java doesn't use the default version or as for the value of variables directly.
public Item {
private String It;
private String Title;
public String toString() {
return "[it: " + IT + ", title: " + Title + "]";
}
}
I have this structure of json api:
{
seasons: [
{
seasonstitle: "Season 1",
titles: "S1E1; S1E2; S1E3",
},
{
seasonstitle: "Season 2",
titles: "S2E1; S2E2; S2E3",
},
]
}
and I'm trying to display the values of these two keys: seasonstitle and titles but as you see the titles key has multiple values so I parsing the json like this:
ParsingClass:
public final class JsonDetailSeries {
public static ArrayList<SeriesItem> getSimpleMovieStringsFromJson(Context context, String moviesJsonString)
throws JSONException {
final String SEASONS = "seasons";
final String SEASONTITLE = "seasonstitle";
final String TITLES = "titles";
ArrayList<SeriesItem> parsedMovieData = new ArrayList<>();
JSONObject moviesObject = new JSONObject(moviesJsonString);
JSONArray moviesArray = moviesObject.getJSONArray(SEASONS);
for (int i = 0; i < moviesArray.length(); i++) {
String seasontitle;
String titles;
moviesObject = moviesArray.getJSONObject(i);
seasontitle = moviesObject.getString(SEASONTITLE);
titles = moviesObject.getString(TITLES);
String[] titlesArrray = titles.split(Pattern.quote(";"));
for (int j=0; j<titlesArrray.length; j++) {
Log.i("titles ", "=" + titlesArrray[j]);
}
parsedMovieData.add(new SeriesItem(seasontitle, titlesArrray));
}
return parsedMovieData;
}
}
when I saw it in log cat it splits correctly like this:
titles = S1E1
titles = S1E2
titles = S1E3
and so on, in my custom arraylist class which I return the data for it:
public class SeriesItem implements Parcelable {
private String seasontitle;
private String[] titlesArrray;
public SeriesItem(String seasontitle, String[] titlesArrray) {
this.seasontitle = seasontitle;
this.titlesArrray = titlesArrray;
}
#Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(seasontitle);
out.writeStringArray(titlesArrray);
}
private SeriesItem(Parcel in) {
this.seasontitle = in.readString();
this.titlesArrray = in.createStringArray();
}
public SeriesItem() {
}
#Override
public int describeContents() {
return 0;
}
public static final Creator<SeriesItem> CREATOR = new Creator<SeriesItem>() {
#Override
public SeriesItem createFromParcel(Parcel in) {
return new SeriesItem(in);
}
#Override
public SeriesItem[] newArray(int i) {
return new SeriesItem[i];
}
};
public String getSeasontitle() {
return seasontitle;
}
public String[] gettitlesArrray() {
return titlesArrray;
}
}
when I debug this class the data of titlesArrray recevied well each title split from the other one
so I'm trying to display this data in recyleview like this way:
Season1
S1E1
S1E2
S1E3
Season2
S2E1
S2E2
S2E3
so this is my adapter of recycleview:
public class SeriesAdapter extends RecyclerView.Adapter<SeriesAdapter.RecyclerViewHolder> {
ArrayList<SeriesItem> mMoviesItems;
private Context context;
private final SeriesAdapterOnClickHandler mClickHandler;
public interface SeriesAdapterOnClickHandler {
void onClick(SeriesItem movie);
}
public SeriesAdapter(SeriesAdapterOnClickHandler clickHandler) {
mClickHandler = clickHandler;
}
class RecyclerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public final TextView seasontitle;
public final ListView titlesArray;
public RecyclerViewHolder(View view) {
super(view);
seasontitle = (TextView)itemView.findViewById(R.id.seasontitle);
titlesArray = (ListView) itemView.findViewById(R.id.titlesArray);
view.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int adapterPosition = getAdapterPosition();
SeriesItem movie = mMoviesItems.get(adapterPosition);
mClickHandler.onClick(movie);
}
}
#Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
context = viewGroup.getContext();
int layoutIdForListItem = R.layout.series_list_item;
LayoutInflater inflater = LayoutInflater.from(context);
boolean shouldAttachToParentImmediately = false;
View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
return new RecyclerViewHolder(view);
}
#Override
public void onBindViewHolder(RecyclerViewHolder holder, int position) {
holder.seasontitle.setText(String.valueOf(mMoviesItems.get(position).getSeasontitle()));
holder.titlesArray.setText(String.valueOf(mMoviesItems.get(position).gettitlesArrray()));
}
#Override
public int getItemCount() {
if (null == mMoviesItems)
return 0;
else {
return mMoviesItems.size();
}
}
public void setMovieData(ArrayList<SeriesItem> movieData) {
mMoviesItems = movieData;
notifyDataSetChanged();
}
}
I tried to include a listview to display the titlesArray inside this recycleview and the problem is with this line:
holder.titlesArray.setText(String.valueOf(mMoviesItems.get(position).gettitlesArrray()));
I can't use setText for ListView so how can to display the titlesArray content inside this recycleview?
I tried to include a listview to display the titlesArray inside this recycleview
Do not do that.
What you want to do is handle two different types, the season and the episode. This question that will help you with that.
How to create RecyclerView with multiple view type?
Use Gson to parse Json instead of the native, it is much easier to implement.
I am implementing an Adapter to take List and Hashmap and turn them into headers and children respectively for an Expandable ListView. In the constructor's Log statements it is showing that the values are being transferred to the local list successfully. But then it suddenly turns null.
I can't pinpoint what went wrong and where. Please help.
Here is my code for the Adapter class:
class ExpandableListViewAdapterDemo extends BaseExpandableListAdapter{
Context context = null;
private List<String> headersList;//semester's name and year
private HashMap<String, List<String>> tableList;//course names with its grades and gpa
static final String TAG = "**Adapter Demo**";
ExpandableListViewAdapterDemo(Context context, List<String> list,
HashMap<String, List<String>> hashMap){
this.context = context;
headersList = list;
tableList = hashMap;
Log.e(TAG, "hashmap list value = "+hashMap.get("Spring 2016"));
Log.e(TAG, "initial table list value = "+tableList.get("Spring 2016"));
printMap(tableList);
//printAll();
Log.e(TAG, "groupCount = "+getGroupCount());
}
void printAll(){
Log.e(TAG, "headers count = "+headersList.size());
for (int i = 0; i < headersList.size() ; i++) {
Log.e(TAG, "header at i="+i+" ,"+headersList.get(i));
}
printMap(tableList);
}
private static void printMap(HashMap mp) {
Iterator it = mp.entrySet().iterator();
while (it.hasNext()) {
HashMap.Entry pair = (HashMap.Entry)it.next();
Log.e(TAG, "#253 : "+pair.getKey() + " = " + pair.getValue());
it.remove(); // avoids a ConcurrentModificationException
}
}
#Override
public int getGroupCount() {
Log.e(TAG, "#299 : table list value = "+tableList.get("Spring 2016"));
return headersList.size();
}
#Override
public int getChildrenCount(int i) {
//Log.e(TAG, "at i="+i+" "+headersList.get(i));
int returns = 0;
Log.e(TAG, "#307 : table list value = "+tableList.get("Spring 2016"));
if (tableList.get(headersList.get(i)) != null)
returns = tableList.get(headersList.get(i)).size();
else
Log.e(TAG, "tableList is null");
Log.e(TAG, "details size = "+returns);
Log.e(TAG, "group count = "+getGroupCount());
int tosubtract = 2 * getGroupCount();
if (returns>tosubtract)
returns = returns - tosubtract - 2;
Log.e(TAG, "child count returns = "+String.valueOf(returns) );
return i;
}
#Override
public Object getGroup(int i) {
Log.e(TAG, "#323 : table list value = "+tableList.get("Spring 2016"));
return headersList.get(i);
}
#Override
public Object getChild(int i, int i1) {
Log.e(TAG, "#329 : table list value = "+tableList.get("Spring 2016"));
return tableList.get(headersList.get(i)).get(i1);
}
#Override
public long getGroupId(int i) {
Log.e(TAG, "#335 : table list value = "+tableList.get("Spring 2016"));
return i;
}
#Override
public long getChildId(int i, int i1) {
Log.e(TAG, "#340 : table list value = "+tableList.get("Spring 2016"));
return i1;
}
#Override
public boolean hasStableIds() {
Log.e(TAG, "#347 : table list value = "+tableList.get("Spring 2016"));
return false;
}
#Override
public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
Log.e(TAG, "#353 : table list value = "+tableList.get("Spring 2016"));
String semesterTitle = (String) getGroup(i);
if (view == null){
LayoutInflater inf = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inf.inflate(R.layout.previous_semesters_result_list_headers, null);
}
TextView semesterName = (TextView) view.findViewById(R.id.semester_name);
semesterName.setText(semesterTitle);
return view;
}
#Override
public View getChildView(int i, int i1, boolean b, View view, ViewGroup viewGroup) {
Log.e(TAG, "#367 : table list value = "+tableList.get("Spring 2016"));
String courseIdTitle = (String) getChild(i, i1);
String gpa = (String) getChild(i, i1+getChildrenCount(i));//previously i1+4
String grade = (String) getChild(i, i1+getChildrenCount(i)+getChildrenCount(i));
if (view == null){
LayoutInflater inf = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inf.inflate(R.layout.previous_semesters_results_list_child, null);
}
TextView courseIdValue = (TextView) view.findViewById(R.id.course_id_column_value);
courseIdValue.setText(courseIdTitle);
TextView gradeValue = (TextView) view.findViewById(R.id.grade_column_value);
gradeValue.setText(grade);
TextView gpaValue = (TextView) view.findViewById(R.id.gpa_column_value);
gpaValue.setText(gpa);
return view;
}
#Override
public boolean isChildSelectable(int i, int i1) {
Log.e(TAG, "#386 : table list value = "+tableList.get("Spring 2016"));
return true;
}
}
Here is my Log :
You removed the item while printing the map,
it.remove(); // avoids a ConcurrentModificationException
Just remove this it will work fine.
private static void printMap(HashMap mp) {
Iterator it = mp.entrySet().iterator();
while (it.hasNext()) {
HashMap.Entry pair = (HashMap.Entry)it.next();
Log.e(TAG, "#253 : "+pair.getKey() + " = " + pair.getValue());
//it.remove(); // avoids a ConcurrentModificationException
}
}
In your method printMap(), the last statement in the while block is
it.remove(); // avoids a ConcurrentModificationException
This statement may not cause an Exception but it removes the current entry from the HashMap. So after executing
printMap(tableList);
in the Constructor of ExpandableListViewAdapterDemo, the tableList will be empty.
İ have a problem about RecyclerView filter.
İ am using edittext on text change method for filter text query in recyclerview but when i filter my Product List is changing.
Note : all of that in fragment and fragment in viewpager.
My problem is that : when i write something it is working but at the same time my product list's elements are changing to result of filter.
So in example at first
MyList Has 40 items
FilteredDataList is empty
After i write "a" in edittext after that FilteredDataList is has 30 items but MyList has same 30 items. But i have not set anything to Mylist
My Data List ,i get it from sqlite
productList = new ArrayList<>();
productList = handler.getAllProduct();
My Filter Method
private List<Product> filter(List<Product> models, String query) {
query = query.toLowerCase();
List<Product> filteredModelList = new ArrayList<>();
filteredModelList.clear();
for (Product model : models) {
final String text = model.get_ProductName().toLowerCase();
if (text.contains(query)) {
filteredModelList.add(model);
}
}
return filteredModelList;
}
My Edittext OnChange Metod
searchEdt.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
if (s.length() != 0) {
List<Product> filteredModelList = filter( productList, s.toString());
rcAdapter.animateTo(filteredModelList);
pager_recycler_view.scrollToPosition(0);
} else {
rcAdapter.animateTo(productList);
pager_recycler_view.scrollToPosition(0);
}
}
});
My AdapterClass
public class ProductRecyclerViewAdapter extends RecyclerView.Adapter< ProductRecyclerViewHolder > {
private List<Product> itemList;
private Context context;
public ProductRecyclerViewAdapter(Context context, List<Product> itemList) {
this.itemList = itemList;
this.context = context;
}
#Override
public ProductRecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.product_card_single_item, null);
ProductRecyclerViewHolder rcv = new ProductRecyclerViewHolder(layoutView);
return rcv;
}
#Override
public void onBindViewHolder(ProductRecyclerViewHolder holder, int position) {
holder.productName.setText(itemList.get(position).get_ProductName());
holder.productWatCode.setText("%" +itemList.get(position).get_ProductWatCode());
holder.productPOR.setText("%" +itemList.get(position).get_ProductPOR());
holder.productRSP.setText("£" +itemList.get(position).get_ProductRSP());
holder.productDescription.setText(itemList.get(position).get_ProductDescription());
holder.productSKU.setText(itemList.get(position).get_ProductSKU());
holder.productPrice.setText("£" + itemList.get(position).get_ProductPrice());
// holder.productCountCart.setText("");
Picasso.with(context)
.load( "http://firmabayi.com/images/ilanK/" +itemList.get(position).get_ProductPhoto())
.placeholder(R.drawable.add_icon)
.error(R.drawable.minus_icon)
.into(holder.productPhoto);
// holder.countryPhoto.setImageResource(itemList.get(position).get_ProductName());
}
#Override
public int getItemCount() {
return this.itemList.size();
}
public void animateTo(List<Product> itemList) {
applyAndAnimateRemovals(itemList);
applyAndAnimateAdditions(itemList);
applyAndAnimateMovedItems(itemList);
}
private void applyAndAnimateRemovals(List<Product> newModels) {
for (int i = itemList.size() - 1; i >= 0; i--) {
final Product model = itemList.get(i);
if (!newModels.contains(model)) {
removeItem(i);
}
}
}
private void applyAndAnimateAdditions(List<Product> newModels) {
for (int i = 0, count = newModels.size(); i < count; i++) {
final Product model = newModels.get(i);
if (!itemList.contains(model)) {
addItem(i, model);
}
}
}
private void applyAndAnimateMovedItems(List<Product> newModels) {
for (int toPosition = newModels.size() - 1; toPosition >= 0; toPosition--) {
final Product model = newModels.get(toPosition);
final int fromPosition = itemList.indexOf(model);
if (fromPosition >= 0 && fromPosition != toPosition) {
moveItem(fromPosition, toPosition);
}
}
}
public Product removeItem(int position) {
final Product model = itemList.remove(position);
notifyItemRemoved(position);
return model;
}
public void addItem(int position, Product model) {
itemList.add(position, model);
notifyItemInserted(position);
}
public void moveItem(int fromPosition, int toPosition) {
final Product model = itemList.remove(fromPosition);
itemList.add(toPosition, model);
notifyItemMoved(fromPosition, toPosition);
}
}
i solved my problem it is only about adapter class one line :(
in adapter class
instead of
this.itemList = itemList;
use that
this.itemList = new ArrayList<>(itemList);
It is about your productList.
When you create a object like doing this;
Class a = b();
You are cloning your object. In deep, they are the same object.
So when you filtered object named a, b is being effected from this.
In short, don't do this. Instead of cloning object you should add each items to a from b by one by.
Like this;
productList = new ArrayList<>();
for( int i = 0 ; i <arrayFromSource.size() ; i++ )
{
productList.add(arrayFromSource.get(i));
}