I have a recycler view which has cards in it. I am using a SearchView to filter the List I pass to the Adapter. I have done something like so :-
class EmployeeAdapter : RecyclerView.Adapter, IFilterable
{
private IEnumerable<IGrouping<string, EmployeeModel>> dupes;
private Activities.EmployeeActivity employeeActivity;
private List<IGrouping<string, EmployeeModel>> _items;
private List<EmployeeModel> mList;
private CustomTextView txtPlace;
private CustomTextView txtTime;
public EmployeeAdapter(List<EmployeeModel> mList, Activities.EmployeeActivity employeeActivity)
{
// TODO: Complete member initialization
this.mList = mList;
this.employeeActivity = employeeActivity;
dupes = mList.GroupBy(x => x.EmployeeName).Where(x => x.Skip(1).Any());
//Filter = new SuggestionFilter(this);
}
public override int ItemCount
{
get { return dupes.Count(); }
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
ViewHolder vh = holder as ViewHolder;
Typeface faceThin = Typeface.CreateFromAsset(employeeActivity.Assets, "Fonts/Roboto-Thin.ttf");
Typeface faceBold = Typeface.CreateFromAsset(employeeActivity.Assets, "Fonts/Roboto-Bold.ttf");
vh.txtEmployeeName.Text = dupes.ElementAt(position).Key;
foreach(EmployeeModel x in dupes.ElementAt(position))
{
var layoutChild = new RelativeLayout(employeeActivity);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WrapContent, RelativeLayout.LayoutParams.WrapContent);
lp.AddRule(LayoutRules.AlignParentLeft);
txtPlace = new CustomTextView(employeeActivity);
txtPlace.Text = x.Place;
txtPlace.LayoutParameters = lp;
layoutChild.AddView(txtPlace);
RelativeLayout.LayoutParams lp1 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WrapContent, RelativeLayout.LayoutParams.WrapContent);
lp1.AddRule(LayoutRules.AlignParentRight);
txtTime = new CustomTextView(employeeActivity);
txtTime.LayoutParameters = lp1;
layoutChild.AddView(txtTime);
vh.layoutPeopleRow.AddView(layoutChild);
vh.layoutVerticalCheckin.RemoveView(vh.layoutPeopleRow);
vh.layoutVerticalCheckin.AddView(vh.layoutPeopleRow);
}
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.people_card_row, parent, false);
// Create a ViewHolder to hold view references inside the CardView:
ViewHolder vh = new ViewHolder(itemView);
return vh;
}
public class ViewHolder : RecyclerView.ViewHolder
{
public CustomTextView txtEmployeeName{ get; private set; }
public ImageView Image { get; private set; }
public LinearLayout layoutPeopleRow { get; private set; }
public LinearLayout layoutVerticalCheckin { get; private set; }
public CustomTextView txtCheckinTime { get; private set; }
public ViewHolder(View itemView)
: base(itemView)
{
// Locate and cache view references:
Image = itemView.FindViewById<ImageView>(Resource.Id.imgEmpPic);
txtEmployeeName = itemView.FindViewById<CustomTextView>(Resource.Id.txtEmployeeName);
layoutPeopleRow = itemView.FindViewById<LinearLayout>(Resource.Id.layoutPeopleRow);
layoutVerticalCheckin = itemView.FindViewById<LinearLayout>(Resource.Id.layoutVerticalCheckin);
}
}
public Filter Filter
{
get;
private set;
}
public void AnimateTo(List<EmployeeModel> models)
{
ApplyAndAnimateRemovals(models);
ApplyAndAnimateAdditions(models);
ApplyAndAnimateMovedItems(models);
}
private void ApplyAndAnimateMovedItems(List<EmployeeModel> newModels)
{
for (int toPosition = newModels.Count() - 1; toPosition >= 0; toPosition--) {
EmployeeModel model = newModels.ElementAt(toPosition);
int fromPosition = mList.IndexOf(model);
if (fromPosition >= 0 && fromPosition != toPosition) {
MoveItem(fromPosition, toPosition);
}
}
}
private void MoveItem(int fromPosition, int toPosition)
{
EmployeeModel model = mList.ElementAt(fromPosition);
mList.Remove(model);
mList.Add(model);
this.NotifyItemMoved(fromPosition, toPosition);
}
private void ApplyAndAnimateAdditions(List<EmployeeModel> newModels)
{
for (int i = 0, count = newModels.Count(); i < count; i++) {
EmployeeModel model = newModels.ElementAt(i);
if (!mList.Contains(model)) {
AddItem(i, model);
}
}
}
private void AddItem(int i, EmployeeModel model)
{
mList.Add(model);
this.NotifyItemInserted(i);
}
private void ApplyAndAnimateRemovals(List<EmployeeModel> newModels)
{
for (int i = mList.Count() - 1; i >= 0; i--) {
EmployeeModel model = mList.ElementAt(i);
if (!newModels.Contains(model)) {
RemoveItem(i);
}
}
}
private EmployeeModel RemoveItem(int i)
{
EmployeeModel model = mList.ElementAt(i);
mList.Remove(model);
this.NotifyItemRemoved(i);
return model;
}
}
There are two problems:
The Search is working fine, but when I make a search OnBinderViewHolder is triggered and the components in the OnBindViewHolder show up multiple times.
The list goes empty when I search once and the next search shows nothing when I clear the SearchView.
This is my Activity
void search_QueryTextChange(object sender, Android.Support.V7.Widget.SearchView.QueryTextChangeEventArgs e)
{
if (string.IsNullOrEmpty(e.NewText))
{
List<EmployeeModel> filteredModelList = filter(mList, "");
}
else
{
List<EmployeeModel> filteredModelList = filter(mList, e.NewText);
mAdapter.AnimateTo(filteredModelList);
mRecyclerView.ScrollToPosition(0);
}
}
private List<EmployeeCheckinModel> filter(List<EmployeeModel> models, String query)
{
query = query.ToLower();
List<EmployeeModel> filteredModelList = new List<EmployeeModel>();
foreach (EmployeeModel model in models) {
String text = model.EmployeeName.ToLower();
if (text.Contains(query)) {
filteredModelList.Add(model);
}
}
return filteredModelList;
}
Related
I would like to update panel wise items in inner adapter item android recyclerview. When we pass the data dynamically.Data displaying is working fine. When we go to update the inner adapter item, it's not getting updated. But last item was getting update fine.
Activity.
public class PannelCreation extends AppCompatActivity {
RecyclerView userPanelRecycler;
List<String> roomPanels = new ArrayList<>();
List<JSONObject> roomItemObject = new ArrayList<JSONObject>();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pannel_creation);
userPanelRecycler = findViewById(R.id.user_panel_recycler);
for(int i=0; i<=5;i++){
roomPanels.add("Panels "+i)
}
PanelAdapter panelAdapter = new PanelAdapter(getApplicationContext(),roomPanels);
userPanelRecycler.setLayoutManager(new LinearLayoutManager(this));
userPanelRecycler.setHasFixedSize(true);
userPanelRecycler.setAdapter(panelAdapter);
}
}
// OuterAdapter
class PanelAdapter extends RecyclerView.Adapter<PanelAdapter.ViewHolder>{
Context context;
List<String> roomPanelList;
RecyclerView.RecycledViewPool recycledViewPool;
List<ItemData> itemDataList = new ArrayList<>();
public PanelAdapter(Context context, List<String> roomPanels) {
this.context = context;
this.roomPanelList = roomPanels;
recycledViewPool = new RecyclerView.RecycledViewPool();
}
#NonNull
#Override
public PanelAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.panel_wise_layout,parent,false);
ViewHolder viewHolder = new ViewHolder(view);
viewHolder.itemsRecycler.setRecycledViewPool(recycledViewPool);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull PanelAdapter.ViewHolder holder, int position) {
holder.userPanelName.setText(roomPanelList.get(position));
String cur_panelName = roomPanelList.get(position);
itemsAdapter = new ItemsAdapter(context);
holder.itemsRecycler.setLayoutManager(new GridLayoutManager(context,3));
holder. itemsRecycler.setHasFixedSize(true);
holder.itemsRecycler.setAdapter(itemsAdapter);
holder.itemsRecycler.setNestedScrollingEnabled(false);
try {
roomItemObject.clear();
JSONArray metaArray = new JSONArray(metaData);
int count = 0;
for(int i = 0;i<metaArray.length();i++){
JSONObject object = metaArray.getJSONObject(i);
String name = object.getString("name");
String[] rNum = name.split("_");
if(rNum[0].equalsIgnoreCase(roomNumber)){
roomItemObject.add(object);
}
count = count+1;
}
if(count == metaArray.length()){
int count1 = 0;
itemDataList.clear();
for(int i =0; i < roomItemObject.size();i++){
JSONObject itemObject1 = roomItemObject.get(i);
String groupNames = itemObject1.getString("groupNames");
String types = itemObject1.getString("type");
String metaValue = itemObject1.getString("metadata");
JSONObject panelObject = new JSONObject(metaValue);
String panel_name = panelObject.getString("panelName");
JSONObject valueObject = new JSONObject(panel_name);
String value = valueObject.getString("value");
if(value.equalsIgnoreCase(cur_panelName)){
String labels = itemObject1.getString("label");
String names = itemObject1.getString("name");
String state = itemObject1.getString("state");
String groupName = itemObject1.getString("groupNames");
String tags = itemObject1.getString("tags");
ItemData itemData = new ItemData();
itemData.setLabelName(labels);
itemData.setState(state);
itemData.setItemName(names);
itemData.setTags(tags);
itemData.setTypes(types);
itemData.setGroup(groupName);
itemDataList.add(itemData);
itemsAdapter.addItems(itemDataList);
itemsAdapter.notifyDataSetChanged();
}
}
}
}catch (JSONException e){
e.printStackTrace();
}
}
#Override
public int getItemCount() {
return roomPanelList.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
public class ViewHolder extends RecyclerView.ViewHolder{
RecyclerView itemsRecycler;
TextView userPanelName;
Button deletePanel;
public ViewHolder(#NonNull View itemView) {
super(itemView);
itemsRecycler = itemView.findViewById(R.id.panel_item_recycler);
userPanelName = itemView.findViewById(R.id.test_panel_name);
deletePanel = itemView.findViewById(R.id.delete_panel);
}
}
}
//Inner Adapter
class ItemsAdapter extends RecyclerView.Adapter<ItemsAdapter.ItemHolder>{
Context mContext;
List<ItemData> innerItemDataList = new ArrayList<>();
List<JSONObject> itemObjectList = new ArrayList<JSONObject>();
List<JSONObject> recObjectList = new ArrayList<>();
ItemData itemData;
public ItemsAdapter(Context context) {
this.mContext = context;
this.itemData = new ItemData();
}
public void addItems(List<ItemData> itemData){
this.innerItemDataList.clear();
this.innerItemDataList.addAll(itemData);
notifyDataSetChanged();
}
#NonNull
#Override
public ItemsAdapter.ItemHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(mContext).inflate(R.layout.panel_wise_item,parent,false);
return new ItemHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull ItemHolder holder, int position) {
itemData = innerItemDataList.get(position);
if(itemData != null){
holder.itemNames.setText(itemData.getLabelName());
}
#Override
public int getItemCount() {
return innerItemDataList.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
public class ItemHolder extends RecyclerView.ViewHolder {
TextView itemNames;
LinearLayout itemLayout;
ImageView itemImg;
public ItemHolder(#NonNull View itemView) {
super(itemView);
itemNames = itemView.findViewById(R.id.panel_item_name);
itemLayout = itemView.findViewById(R.id.panel_light_linear);
itemImg = itemView.findViewById(R.id.panel_item_img);
}
}
public void updateItem(String itemName,String state){
for(int j=0;j<innerItemDataList.size();j++){
if(itemName.equalsIgnoreCase(innerItemDataList.get(j).getItemName())){
innerItemDataList.get(j).setState(state);
notifyDataSetChanged();
}
}
}
}
//Inner adapter data model class
public class ItemData {
String labelName;
String itemName;
String state;
String group;
String tags;
String types;
public String getTypes() {
return types;
}
public void setTypes(String types) {
this.types = types;
}
public String getTags() {
return tags;
}
public void setTags(String tags) {
this.tags = tags;
}
public String getLabelName() {
return labelName;
}
public void setLabelName(String labelName) {
this.labelName = labelName;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
}
How to update specific item in inner adapter android nested recycler view.Can anyone guide me how to deal with update specific item. One more thing have observed inner adapter returns last position of array list only. Items are updating fine in last position of array list. When trying to updating the rest of position array list items, not getting updated.
Thanks in Advance.
Amar.
In outer adapter when ever data changes need to notify. Try this code
panelAdapter.notifyDataSetChanged();
I have implemented recyclerview and it loads 10 tasks at a time. Once every task is completed, I am removing the task with a completed button. It loads the 11th item if I scroll to the bottom at one condition there has to be atleast one uncompleted task present on the page. If I clear all 10 items it just shows me loading animation and nothing happens. I have to close the app and open again to load the tasks again.
I have implemented a PaginationActivity, PaginationAdapter and scroll listener for the page. It loads data from a local database whenever you have reached the end of the page and you have got more tasks to load.
PaginationActivity.java
public class PaginationActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
PaginationAdapter adapter;
LinearLayoutManager linearLayoutManager;
public static ArrayList<String> reasonsdata = new ArrayList<String>();
public static String rslt="";
public static String[] reasons;
public static boolean chk = true;
public static String payTypeSelected;
public static String reasonSelected;
public static HashMap<String, EditText> drivernotesMap = new HashMap<String, EditText>();
public static HashMap<String, EditText> paynoteMap = new HashMap<String, EditText>();
public static HashMap<String, String> paytypeMap = new HashMap<String, String>();
RecyclerView rv;
ProgressBar progressBar;
private static final int PAGE_START = 0;
private boolean isLoading = false;
private boolean isLastPage = false;
private int TOTAL_PAGES;
private int currentPage = PAGE_START;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pagination_main);
fillspinner();
rv = (RecyclerView) findViewById(R.id.main_recycler);
progressBar = (ProgressBar) findViewById(R.id.main_progress);
adapter = new PaginationAdapter(this);
linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
rv.setLayoutManager(linearLayoutManager);
rv.setItemAnimator(new DefaultItemAnimator());
rv.setAdapter(adapter);
rv.addOnScrollListener(new PaginationScrollListener(linearLayoutManager) {
#Override
protected void loadMoreItems() {
isLoading = true;
currentPage += 1;
// mocking network delay for API call
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
loadNextPage();
}
}, 1000);
}
#Override
public int getTotalPageCount() {
return TOTAL_PAGES;
}
#Override
public boolean isLastPage() {
return isLastPage;
}
#Override
public boolean isLoading() {
return isLoading;
}
});
// mocking network delay for API call
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
loadFirstPage();
}
}, 1000);
}
private void fillspinner() {
reasonsdata.clear();
try
{
rslt="START";
CallReasons cr = new CallReasons();
cr.join();
cr.start();
while(rslt=="START") {
try {
Thread.sleep(10);
}catch(Exception ex) {
}
}
}
catch (Exception ex) {
ex.printStackTrace();
}
if(rslt == "Success"){
reasonsdata.add("<--- Select Reason --->");
for(int i =0; i< reasons.length;i++){
reasonsdata.add(reasons[i]);
}
}
}
public void loadFirstPage() {
Log.d(TAG, "loadFirstPage: ");
TOTAL_PAGES = Run.getTotalPages();
//List<Run> runs = Run.createRuns(adapter.getItemCount());
List<Run> runs = Run.createRuns(adapter.getMaxID());
progressBar.setVisibility(View.GONE);
adapter.addAll(runs);
if (currentPage <= TOTAL_PAGES) adapter.addLoadingFooter();
else isLastPage = true;
}
public void loadNextPage() {
Log.d(TAG, "loadNextPage: " + currentPage);
//List<Run> runs = Run.createRuns(adapter.getItemCount());
List<Run> runs = Run.createRuns(adapter.getMaxID());
adapter.removeLoadingFooter();
isLoading = false;
adapter.addAll(runs);
if (currentPage != TOTAL_PAGES) adapter.addLoadingFooter();
else isLastPage = true;
}
}
PaginationAdapter.java
public class PaginationAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int ITEM = 0;
private static final int LOADING = 1;
private List<Run> runs = new ArrayList<>();
private Context context;
private boolean isLoadingAdded = false;
private String cash = "CASH";
private String cheque = "CHEQUE";
SQLiteDatabase db;
//PaginationActivity func_call;
public PaginationAdapter(Context context) {
this.context = context;
runs = new ArrayList<>();
//func_call = new PaginationActivity();
}
public List<Run> getRuns() {
return runs;
}
public void setRuns(List<Run> runs) {
this.runs = runs;
}
#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);
//viewHolder = getViewHolder(parent, inflater);
//func_call.loadNextPage();
break;
}
return viewHolder;
}
#NonNull
private RecyclerView.ViewHolder getViewHolder(ViewGroup parent, LayoutInflater inflater) {
RecyclerView.ViewHolder viewHolder;
View v1 = inflater.inflate(R.layout.activity_main, parent, false);
viewHolder = new RunVH(v1);
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final Run run = runs.get(position);
switch (getItemViewType(position)) {
case ITEM:
final RunVH runVH = (RunVH) holder;
//adding text areas to show data
//Completed task button
runVH.btnSave.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Toast.makeText(context, "Mark as Completed", Toast.LENGTH_LONG).show();
remove(run);
}
}
} catch (Exception ex) {
//pbbar.setVisibility(View.GONE);
ex.printStackTrace();
}
}
});
break;
case LOADING:
break;
}
}
#Override
public int getItemCount() {
return runs == null ? 0 : runs.size();
}
//#Override
public int getMaxID() {
if(runs == null || runs.size() == 0){
return 0;
}else{
Run test = runs.get(runs.size()-2);
int maxid = (int) test.getProperty(0);
return maxid;
}
}
#Override
public int getItemViewType(int position) {
return (position == runs.size() - 1 && isLoadingAdded) ? LOADING : ITEM;
}
public void add(Run run) {
runs.add(run);
notifyItemInserted(runs.size() - 1);
}
public void addAll(List<Run> runList) {
for (Run run : runList) {
add(run);
}
}
public void remove(Run run) {
int position = runs.indexOf(run);
if (position > -1) {
runs.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, runs.size());
}
/*if(runs.size() < 0){
clear();
func_call.loadNextPage();
}*/
}
public void clear() {
isLoadingAdded = false;
while (getItemCount() > 0) {
remove(getItem(0));
}
}
public boolean isEmpty() {
return getItemCount() == 0;
}
public void addLoadingFooter() {
isLoadingAdded = true;
add(new Run());
}
public void removeLoadingFooter() {
isLoadingAdded = false;
int position = runs.size() - 1;
Run item = getItem(position);
if (item != null) {
runs.remove(position);
notifyItemRemoved(position);
}
}
public Run getItem(int position) {
return runs.get(position);
}
protected class RunVH extends RecyclerView.ViewHolder {
private TextView textEsky;
private TextView textAdjusted;
private TextView textAddress;
private TextView textNew;
private TextView textTrusted;
private TextView textName;
private TextView textMobile;
private TextView textHome;
private TextView textWork;
private TextView payType;
private EditText textPayNote;
private EditText textDeliveryInst;
private EditText textDriverNotes;
private final Spinner reasons;
private RadioGroup rg;
private Button btnSave;
private CheckBox IsDriverData;
public RunVH(View itemView) {
super(itemView);
textEsky = (TextView) itemView.findViewById(R.id.idEsky);
textAdjusted = (TextView) itemView.findViewById(R.id.idAdjusted);
textAddress = (TextView) itemView.findViewById(R.id.idAddress);
textNew = (TextView) itemView.findViewById(R.id.idNew);
textTrusted = (TextView) itemView.findViewById(R.id.idTrusted);
textName = (TextView) itemView.findViewById(R.id.idName);
textMobile = (TextView) itemView.findViewById(R.id.idMobile);
textHome = (TextView) itemView.findViewById(R.id.idHome);
textWork = (TextView) itemView.findViewById(R.id.idWork);
payType = (TextView) itemView.findViewById(R.id.idPayType);
textPayNote = (EditText) itemView.findViewById(R.id.idPayNoteText);
textDeliveryInst = (EditText) itemView.findViewById(R.id.idDeliInsText);
textDriverNotes = (EditText) itemView.findViewById(R.id.idDriverNotesText);
IsDriverData = (CheckBox) itemView.findViewById(R.id.idCheckBox);
reasons = (Spinner) itemView.findViewById(R.id.idReason);
rg = (RadioGroup) itemView.findViewById(R.id.Radiogroup);
btnSave = (Button) itemView.findViewById(R.id.button);
}
}
protected class LoadingVH extends RecyclerView.ViewHolder {
public LoadingVH(View itemView) {
super(itemView);
}
}
}
PaginationScrollListener.java
public abstract class PaginationScrollListener extends RecyclerView.OnScrollListener {
LinearLayoutManager 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) {
loadMoreItems();
}
}
}
protected abstract void loadMoreItems();
public abstract int getTotalPageCount();
public abstract boolean isLastPage();
public abstract boolean isLoading();
}
I could be wrong, but it looks to me like the only time you call loadNextPage() is when the RecyclerView gets a scroll event. Removing ViewHolders doesn't cause scroll events iirc.
If you register an AdapterDataObserver on the PaginationAdapter, you can listen in on removal/add events and trigger loads when there aren't any tasks left. You could probably do the same thing with some small changes to that commented-out code in remove(Run):
if (runs.isEmpty()) {
func_call.loadNextPage();
}
EDIT:
Btw, you see where you called adapter = new PaginationAdapter(this); in the PaginationActivity.onCreate method? The this here is your PaginationActivity, which means you can assign it to a PaginationAdapter field like so:
/**
* #param context the activity this adapter will appear in
*/
public PaginationAdapter(Context context) {
this.context = context;
runs = new ArrayList<>();
func_call = (PaginationActivity)context;
}
That should be enough to prevent crashes. For better separation of concerns, you'll probably want to switch over to AdapterDataObserver-based logic (I think this is called the open/closed principle? Maybe?).
I have been very meticulous in following this guide to implement pagination in my RecyclerView. Only difference is I'm using Retrofit to retrieve data from the API.
When I open my activity it stops after a while, and when I check Logcat, it says: IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{31a22aa position=4 id=-1, oldPos=2,... This is what my RecyclerView adapter looks like:
public class CuratedSectionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static int VIEW_TYPE_HEADER = 0;
private static int VIEW_TYPE_ITEM = 1;
private static int VIEW_TYPE_LOADING = 2;
private RecyclerView mRecyclerView;
private OnLoadMoreListener mOnLoadMoreListener;
private boolean isLoading;
private int visibleThreshold = 2;
private int lastVisibleItem, totalItemCount;
private List<Object> itemList;
public CuratedSectionAdapter(List<Object> itemList, RecyclerView recyclerView, LinearLayoutManager layoutManager) {
this.itemList = itemList;
this.mRecyclerView = recyclerView;
final LinearLayoutManager linearLayoutManager = layoutManager;
mRecyclerView.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 (!isLoading && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
if (mOnLoadMoreListener != null) {
mOnLoadMoreListener.onLoadMore();
}
isLoading = true;
}
}
});
}
public void setOnLoadMoreListener(OnLoadMoreListener mOnLoadMoreListener) {
this.mOnLoadMoreListener = mOnLoadMoreListener;
}
private class ItemViewHolder extends RecyclerView.ViewHolder {
RecyclerView itemRecyclerView;
CuratedSectionNestedAdapter nestedAdapter;
LinearLayoutManager layoutManager;
ItemViewHolder(View view) {
super(view);
itemRecyclerView = view.findViewById(R.id.recyclerView_nested);
layoutManager = new LinearLayoutManager(view.getContext(), LinearLayoutManager.HORIZONTAL, false);
}
}
private class HeaderViewHolder extends RecyclerView.ViewHolder {
TextView textViewHeader;
Typeface montserratMedium = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/Montserrat-Medium.ttf");
HeaderViewHolder(View view) {
super(view);
textViewHeader = view.findViewById(R.id.textView_header);
textViewHeader.setTypeface(montserratMedium);
}
}
private class LoadingViewHolder extends RecyclerView.ViewHolder {
ProgressBar progressBar;
LoadingViewHolder(View itemView) {
super(itemView);
progressBar = itemView.findViewById(R.id.progress_bar);
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder.getItemViewType() == VIEW_TYPE_HEADER) {
HeaderViewHolder viewHolder = (HeaderViewHolder) holder;
CuratedSectionHeader header = (CuratedSectionHeader) itemList.get(position);
viewHolder.textViewHeader.setText(header.getHeaderName());
} else if (holder.getItemViewType() == VIEW_TYPE_ITEM){
ItemViewHolder viewHolder = (ItemViewHolder) holder;
List<CuratedSectionItem> items = (List<CuratedSectionItem>) itemList.get(position);
if (viewHolder.nestedAdapter != null) {
viewHolder.nestedAdapter.setItems(items);
} else {
viewHolder.nestedAdapter = new CuratedSectionNestedAdapter(items);
viewHolder.itemRecyclerView.setLayoutManager(viewHolder.layoutManager);
viewHolder.itemRecyclerView.setAdapter(viewHolder.nestedAdapter);
}
} else if (holder.getItemViewType() == VIEW_TYPE_LOADING){
LoadingViewHolder viewHolder = (LoadingViewHolder) holder;
viewHolder.progressBar.setIndeterminate(true);
}
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_HEADER) {
return new HeaderViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.main_explore_header_row, parent, false));
} else if (viewType == VIEW_TYPE_ITEM) {
return new ItemViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.main_explore_row, parent, false));
} else if (viewType == VIEW_TYPE_LOADING) {
return new LoadingViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_loading_item, parent, false));
}
throw new RuntimeException("Adapter " + viewType + "not found");
}
#Override
public int getItemCount() {
return itemList.size();
}
#Override
public int getItemViewType(int position) {
if(isHeader(position)) {
return VIEW_TYPE_HEADER;
} else if(isLoading(position)) {
return VIEW_TYPE_LOADING;
} else {
return VIEW_TYPE_ITEM;
}
}
public boolean isHeader(int position) {
return itemList.get(position) instanceof CuratedSectionHeader;
}
public boolean isLoading(int position) {
return position > itemList.size();
}
public void setLoaded() {
isLoading = false;
}
}
It may have something to do with how I constructed LoadingViewHolder, but I think I did that one correctly. On the other hand, this is what the activity looks like:
public class ExploreFeedActivity extends Activity {
private RecyclerView recyclerView;
private CuratedSectionAdapter curatedSectionAdapter;
private LinearLayoutManager layoutManager;
private Sections curated;
int mStart = 0;
int mLimit = 2;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_explore);
curated = new Sections();
curated.loadSections(mStart, mLimit);
recyclerView = findViewById(R.id.recycler_view_main);
layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
}
private class Sections {
ArrayList<CuratedSection> sections = new ArrayList<>();
public Thread[] thread;
private Sections() {}
public void setSections(ArrayList<CuratedSection> sections) {
this.sections = sections;
}
public void setSectionStories(String sectionId, List<CuratedSectionItem> stories) {
for(CuratedSection s : sections){
if(s.id != null && s.id.equals(sectionId)) {
s.stories = stories;
}
}
}
public void loadStories(String sessionKey) {
thread = new Thread[sections.size()];
for( int s = 0; s < sections.size(); s++) {
thread[s] = new Thread(new LoadStories(sessionKey, sections.get(s)));
thread[s].start();
}
for( int f = 0; f < sections.size(); f++) {
try {
thread[f].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
curatedSectionAdapter = new CuratedSectionAdapter(this.getAdapterInfo(), recyclerView, layoutManager);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(curatedSectionAdapter);
curatedSectionAdapter.setOnLoadMoreListener(new OnLoadMoreListener() {
#Override
public void onLoadMore() {
Log.e("haint", "Load More");
curated.sections.add(null);
curatedSectionAdapter.notifyItemInserted(curated.sections.size() - 1);
// Load more data for recyclerview
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Log.e("haint", "Load Further");
// Remove loading item
curated.sections.remove(curated.sections.size() - 1);
curatedSectionAdapter.notifyItemRemoved(curated.sections.size());
// Load data
curated.loadSections(2, 2);
curatedSectionAdapter.notifyDataSetChanged();
curatedSectionAdapter.setLoaded();
}
}, 5000);
}
});
}
public void loadSections(int start, int limit) {
swipeRefreshLayout.setRefreshing(false);
LoadSections load = new LoadSections(start, limit);
load.run();
}
public List<Object> getAdapterInfo() {
List<Object> list = new ArrayList<>();
for (int i = 0; i < sections.size(); i++) {
CuratedSection section = sections.get(i);
CuratedSectionHeader header = new CuratedSectionHeader();
header.setHeaderName(section.header);
list.add(header);
list.add(section.stories);
}
return list;
}
}
private class LoadSections implements Runnable {
int start, limit;
LoadSections(int start, int limit) {
this.start = start;
this.limit = limit;
}
#Override
public void run() {
SharedPreferences prefs = getSharedPreferences("user_session", MODE_PRIVATE);
final String sessionKey = prefs.getString("session_key", null);
Call<JsonArray> call;
call = TravelersApi.endpoint().getCuratedSections(sessionKey);
call.enqueue(new Callback<JsonArray>() {
#Override
public void onResponse(Call<JsonArray> call, Response<JsonArray> response) {
if(response.code() != 200) {
Toast.makeText(getApplicationContext(), "Cannot load page as of the moment.", Toast.LENGTH_SHORT).show();
return;
}
JsonArray rawSections = response.body();
if(rawSections.size() == 0) {
//TODO: show placeholder
return;
}
for(int i = start; i < start+limit; i++) {
JsonObject jSection = rawSections.get(i).getAsJsonObject();
final CuratedSection section = new CuratedSection();
section.id = jSection.get("id").getAsString();
section.header = jSection.get("section_header").getAsString();
section.isShown = jSection.get("is_shown").getAsBoolean();
section.stories = new ArrayList<>();
curated.sections.add(section);
}
curated.setSections(curated.sections);
curated.loadStories(sessionKey);
}
#Override
public void onFailure(Call<JsonArray> call, Throwable t) {
Log.d("ERROR!", t.toString());
t.printStackTrace();
}
});
}
}
private class LoadStories implements Runnable {
String sessionKey;
CuratedSection section;
LoadStories(String sessionKey, CuratedSection section) {
this.sessionKey = sessionKey;
this.section = section;
}
#Override
public void run() {
Call<JsonArray> subCall;
subCall = TravelersApi.endpoint().getCuratedSectionTopics(sessionKey, section.id);
try {
Response<JsonArray> response = subCall.execute();
if(response.code() != 200) {
Toast.makeText(getApplicationContext(), "Cannot load page as of the moment.", Toast.LENGTH_SHORT).show();
return;
}
JsonArray rawStories = response.body();
if(rawStories.size() == 0) {
//TODO: show placeholder
return;
}
ArrayList<CuratedSectionItem> stories = new ArrayList<>();
for(int i = 0; i < rawStories.size(); i++) {
JsonObject jStories = rawStories.get(i).getAsJsonObject();
JSONObject temp = new JSONObject(jStories.toString());
JsonObject author = jStories.get("author").getAsJsonObject();
CuratedSectionItem story = new CuratedSectionItem();
story.title = jStories.get("title").getAsString();
story.avatar = author.get("profile_photo").getAsString();
stories.add(story);
}
section.stories = stories;
} catch (IOException e) {
Log.d("ERROR!", e.toString());
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
It's interesting to note that my RecyclerView adapter curatedSectionAdapter was instantiated in the method loadStories inside the private class Sections. I have tried moving that part to onCreate but then the activity won't display anything. I also suspect that the way I constructed the for loop in the callback in LoadSections has something to do with the crash.
I have a RecyclerView and when a user clicks on an item, that item gets selected and its id is saved in a JSON Array. Similarly, if the user selects an item and later decides to unselect it, the item should be removed from the JSON Array and an updated array should be created. I am able to create a JSON Array on onClick but at !onClick I am not able to remove the JSON Object from the JSON Array.
Here is my Adapter Class:
public class ClientListAdapter extends RecyclerView.Adapter<ClientListAdapter.ViewHolder> {
private Context context;
private List<ClientListData> clientListData;
public JSONArray clientArray = new JSONArray();
public ClientListAdapter(List<ClientListData> clientListData, Context context) {
super();
this.clientListData = clientListData;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.client_list_item, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(final ClientListAdapter.ViewHolder holder, final int position) {
final ClientListData clientListDataModel = clientListData.get(position);
holder.clientList.setText(clientListDataModel.getClientName());
holder.itemView.setBackgroundColor(clientListDataModel.isSelected() ? Color.GRAY : Color.WHITE);
holder.clientList.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
clientListDataModel.setSelected(!clientListDataModel.isSelected());
try {
JSONObject clientObject = new JSONObject();
if(clientListDataModel.isSelected()) {
holder.itemView.setBackgroundColor(Color.GRAY);
clientObject.put("id", clientListData.get(position).getClientId());
clientArray.put(clientObject);
}
if(!clientListDataModel.isSelected()) {
holder.itemView.setBackgroundColor(Color.WHITE);
for(int i=0; i<clientArray.length(); i++) {
clientObject = clientArray.getJSONObject(i);
clientObject.remove(clientListData.get(position).getClientId());
//clientArray.put(clientObject);
}
}
//clientArray.put(clientObject);
} catch (JSONException e) {
e.printStackTrace();
}
Log.e("client id array", ""+clientArray);
}
});
}
#Override
public int getItemCount() {
return clientListData == null ? 0:clientListData.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
public TextView clientList;
public ViewHolder(View itemView) {
super(itemView);
clientList = (TextView) itemView.findViewById(R.id.tv_client_list);
}
}
}
and here is my Model Class:
public class ClientListData {
private String clientId;
private String clientName;
private boolean isSelected = false;
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientName() {
return clientName;
}
public void setClientName(String clientName) {
this.clientName = clientName;
}
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean selected) {
isSelected = selected;
}
}
Note that I have created a boolean variable in the Model Class to listen to onClicks.
Note:- since I am using org.json, I am not able to use the remove method on JSON Array, after a lot of search I came across this question.
Try this:[UPDATE]
if (!clientListDataModel.isSelected()) {
holder.itemView.setBackgroundColor(Color.WHITE);
for (int i = 0; i < clientArray.length(); i++) {
clientObject = clientArray.getJSONObject(i);
if (clientObject.getString("id").equals(clientListDataModel.getClientId())) {
clientArray=removeFromJsonArray(clientArray,i);
break;
}
}
}
removeFromJsonArray function:
private JSONArray removeFromJsonArray(JSONArray array,int position){
if(array==null)return null;
JSONArray newArray = new JSONArray();
for (int i=0;i<array.length();i++)
{
//Excluding the item at position
if (i != position)
{
newArray.put(jsonArray.get(i));
}
}
return newArray;
}
Add This code in activity
private ArrayList<Integer> selectedIdList = new ArrayList<>();
ClientListAdapter adapter=new ClientListAdapter (list,this,new View.OnClickListener() {
#Override
public void onClick(View v) {
int position=(Integer)v.getTag();
if(list.size()>position){
ClientListDataModel clientListDataModel=list.get(position);
if clientListDataModel!= null) {
clientListDataModel.setSelected(!clientListDataModel.isSelected());
boolean isSelected = clientListDataModel.isSelected();
if (!isSelected) {
if (selectedIdList.contains(clientListDataModel.getId())) {
int index = selectedIdList.indexOf(clientListDataModel.getId());
selectedIdList.remove(index);
}
} else {
if (!selectedIdList.contains(clientListDataModel.getId())) {
selectedIdList.add(clientListDataModel.getId());
}
}
}
adapter.notifyItemChanged(pos);
}
});
And at sending time
public JSONArray clientArray = new JSONArray();
if(!selectedIdList.empty()){
for(int i=0; i<selectedIdList.size(); i++) {
JSONObject clientObject = new JSONObject();
clientObject.put("id", selectedIdList.get(i));
clientArray.put(clientObject);
}
}
public class ClientListAdapter extends RecyclerView.Adapter<ClientListAdapter.ViewHolder> {
private Context context;
private List<ClientListData> clientListData;
public JSONArray clientArray = new JSONArray();
OnClickListener onClickListener;
public ClientListAdapter(List<ClientListData> clientListData, Context context,OnClickListener onclick) {
super();
this.clientListData = clientListData;
this.context = context;
onClickListener=onclick;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.client_list_item, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(final ClientListAdapter.ViewHolder holder, final int position) {
final ClientListData clientListDataModel = clientListData.get(position);
holder.clientList.setText(clientListDataModel.getClientName());
holder.itemView.setBackgroundColor(clientListDataModel.isSelected() ? Color.GRAY : Color.WHITE);
holder.clientList.setTag(position);
holder.clientList.setOnClickListener(onClickListener);
}
#Override
public int getItemCount() {
return clientListData == null ? 0:clientListData.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
public TextView clientList;
public ViewHolder(View itemView) {
super(itemView);
clientList = (TextView) itemView.findViewById(R.id.tv_client_list);
}
}
I'm trying to implement searchview. It works somehow, but the problem is that after you start typing it is one-way street. You get the info but if you delete text, you won't get the result as it was in the beginning. I'm working with cardviews.
Marker is a model(gettitle etc.)
My Adapter:
public class AdapterRestavracije extends
RecyclerView.Adapter<AdapterRestavracije.ViewHolderRestavracije> {
ArrayList<Marker> arrayList;
private LayoutInflater layoutInflater;
private VolleySingleton mVolleySingleton;
Context context;
public AdapterRestavracije(Context context, ArrayList<Marker> models) {
layoutInflater = LayoutInflater.from(context);
this.context = context;
mVolleySingleton = VolleySingleton.getsIstance();
arrayList = new ArrayList<Marker>(models);
// this.arrayList = new ArrayList<Marker>();
}
public void setRestaurants(ArrayList<Marker> arrayList) {
this.arrayList = arrayList;
notifyItemChanged(0, arrayList.size());
}
#Override
public ViewHolderRestavracije onCreateViewHolder(ViewGroup parent, int viewType) {
View view = layoutInflater.inflate(R.layout.restaurants_rview, parent, false);
ViewHolderRestavracije viewHolder = new ViewHolderRestavracije(view);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolderRestavracije holder, int position) {
Marker currentRest = arrayList.get(position);
holder.name.setText(currentRest.getTitle());
holder.address.setText(currentRest.getAddress());
holder.placilo.setText(currentRest.getValue_of_charge() + " €");
holder.oddaljenost.setText(currentRest.getOddaljenost());
holder.idrestavracije.setText(currentRest.getId());
try {
holder.ratingBarOverall.setRating(Float.parseFloat(currentRest.getOverallRating()));
} catch (Exception e) {
holder.ratingBarOverall.setRating(0);
}
Log.d("RESTAVRACIJEEEEE", currentRest.getTitle());
}
#Override
public int getItemCount() {
return arrayList.size();
}
class ViewHolderRestavracije extends RecyclerView.ViewHolder {
private TextView name, oddaljenost, address, textPlacilo, placilo, idrestavracije;
private RatingBar ratingBarOverall;
private int id;
public View view;
public ViewHolderRestavracije(View itemView) {
super(itemView);
view = itemView;
name = (TextView) itemView.findViewById(R.id.tvNameRestaurant);
oddaljenost = (TextView) itemView.findViewById(R.id.tvOddaljenost);
address = (TextView) itemView.findViewById(R.id.tvAddress);
textPlacilo = (TextView) itemView.findViewById(R.id.tvDoplacilo);
placilo = (TextView) itemView.findViewById(R.id.tvDoplaciloEvri);
idrestavracije = (TextView) itemView.findViewById(R.id.idrestavracije);
ratingBarOverall = (RatingBar) itemView.findViewById(R.id.ratingOverallRestavracije);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//id = getAdapterPosition();
//Log.d("CLICKED", idrestavracije.getText().toString() + "");
//Log.d("CLICKED", name.getText().toString() + "");
String idrest = idrestavracije.getText().toString();
// Log.d("CLICKED", intid + "");
// Intent i = new Intent(context, RestaurantActivity.class);
// i.putExtra("ID_rest", intid);
// context.startActivity(i);
Intent i = new Intent(context, RestaurantActivity.class);
Bundle bundle = new Bundle();
bundle.putString("ID_rest", idrest);
i.putExtras(bundle);
context.startActivity(i);
}
});
}
}
////PRIPRAVA ZA SEARCH//////
public void animateTo(ArrayList<Marker> models) {
applyAndAnimateRemovals(models);
applyAndAnimateAdditions(models);
applyAndAnimateMovedItems(models);
}
private void applyAndAnimateRemovals(ArrayList<Marker> newModels) {
for (int i = arrayList.size() - 1; i >= 0; i--) {
final Marker model = arrayList.get(i);
if (!newModels.contains(model)) {
removeItem(i);
}
}
}
private void applyAndAnimateAdditions(ArrayList<Marker> newModels) {
for (int i = 0, count = newModels.size(); i < count; i++) {
final Marker model = newModels.get(i);
if (!arrayList.contains(model)) {
addItem(i, model);
}
}
}
private void applyAndAnimateMovedItems(ArrayList<Marker> newModels) {
for (int toPosition = newModels.size() - 1; toPosition >= 0; toPosition--) {
final Marker model = newModels.get(toPosition);
final int fromPosition = arrayList.indexOf(model);
if (fromPosition >= 0 && fromPosition != toPosition) {
moveItem(fromPosition, toPosition);
}
}
}
public Marker removeItem(int position) {
final Marker model = arrayList.remove(position);
notifyItemRemoved(position);
return model;
}
public void addItem(int position, Marker model) {
arrayList.add(position, model);
notifyItemInserted(position);
}
public void moveItem(int fromPosition, int toPosition) {
final Marker model = arrayList.remove(fromPosition);
arrayList.add(toPosition, model);
notifyItemMoved(fromPosition, toPosition);
}
////PRIPRAVA ZA SEARCH//////
}
MY FRAGMENT:
---OTHER CODE----
#Override
public void onViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);
setHasOptionsMenu(true);
recyclerView = (RecyclerView) view.findViewById(R.id.listRestaurants);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
// recyclerView.setItemAnimator(new DefaultItemAnimator());
listRestaurants = new ArrayList<Marker>();
jsonRequest(latitude, longitude);
adapterRestavracije = new AdapterRestavracije(getActivity(),listRestaurants);
recyclerView.setAdapter(adapterRestavracije);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.main_menu2, menu);
MenuItem item = menu.findItem(R.id.action_search);
final SearchView sv = (SearchView) MenuItemCompat.getActionView(item);
sv.setOnQueryTextListener(this);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onQueryTextSubmit(String query) {
// Utils.LogDebug("Submitted: "+query);
Log.d("Clicked: ", query);
return false;
}
#Override
public boolean onQueryTextChange(String query) {
// Utils.LogDebug("Changed: " + newText);
final ArrayList<Marker> filteredModelList = filter(listRestaurants, query);
adapterRestavracije.animateTo(filteredModelList);
recyclerView.scrollToPosition(0);
//Log.d("Query Changed: ", query);
return false;
}
private ArrayList<Marker> filter(ArrayList<Marker> listRestaurants, String query) {
query = query.toLowerCase();
final ArrayList<Marker> filteredModelList = new ArrayList<Marker>();
for (Marker model : listRestaurants) {
final String text = model.getTitle().toLowerCase();
if (text.contains(query)) {
filteredModelList.add(model);
}
}
return filteredModelList;
}
---OTHER CODE----
Thanks for the help.
Wow, fixed the problem. The problem was that the arraylist wasn't declared as final. So now that i did that it works :).
Example:
before:
List<ExampleModel> mModels;
after:
private final List<ExampleModel> mModels;