0

OnQueryTextChange Listener is not updating ArrayList used in RecyclerAdapter class.

I have made a static ArrayList to access the stored data in ArrayList used in background class, and call the update method of RecyclerAdapter class to refresh the RecyclerView by OnQueryTextChange method. But RecyclerView is not refreshing.

MainActivity.java:

package com.example.varundhuria.recyclerfilterexample

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void recycle(View view) {
        startActivity(new Intent(this,Search.class));
    }
}

Search.java:

package com.example.varundhuria.recyclerfilterexample;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import java.util.ArrayList;
import java.util.Arrays;

public class Search extends AppCompatActivity implements SearchView.OnQueryTextListener {
    RecyclerAdapter adapter;
        ArrayList<AndroidVersions> list2=new ArrayList<>();

    public Search(){

    }

    public Search(ArrayList<AndroidVersions> list) {
        this.list2=list;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);
        background bg=new background(this);
        bg.execute();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.toolbar_menu, menu);
        MenuItem menuItem=menu.findItem(R.id.toolbar_search);
        SearchView searchView= (SearchView) menuItem.getActionView();
        searchView.setOnQueryTextListener(this);
        return true;
    }
    @Override
    public boolean onQueryTextSubmit(String s) {
        return false;
    }

    @Override
    public boolean onQueryTextChange(String s) {
        adapter=new RecyclerAdapter();
        String userInput=s.toLowerCase();
        ArrayList<AndroidVersions> newList=new ArrayList<>();
        for(AndroidVersions av:adapter.list2){
            if(av.getVersions().toLowerCase().contains(userInput)){
                newList.add(av);
            }
        }
        adapter.updateList(newList);
        return true;
    }
}

RecyclerAdapter.java:

package com.example.varundhuria.recyclerfilterexample;

import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {
    public ArrayList<AndroidVersions> list=new ArrayList<>();
    public static ArrayList<AndroidVersions> list2=new ArrayList<>();

    public RecyclerAdapter(){
    }

    public RecyclerAdapter(ArrayList<AndroidVersions> list) {
        this.list = list;
        this.list2=list;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view= LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.text_view_layout,viewGroup,false);
        MyViewHolder myViewHolder=new MyViewHolder(view);
        return myViewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, int i) {
        AndroidVersions av=list.get(i);
        myViewHolder.VersionName.setText(av.getVersions());
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    public void updateList(ArrayList<AndroidVersions> newList) {
        list=new ArrayList<>();
        list.addAll(newList);
        notifyDataSetChanged();
    }

    public static class MyViewHolder extends RecyclerView.ViewHolder {
        TextView VersionName;
        public MyViewHolder(View itemView) {
            super(itemView);
            VersionName=(TextView)itemView.findViewById(R.id.text1);
        }
    }
}

background.java:

package com.example.varundhuria.recyclerfilterexample;

import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import java.util.ArrayList;
public class background extends AsyncTask<String,AndroidVersions,String> {
    Activity activity;
    RecyclerView recyclerView;
    RecyclerView.Adapter adapter;
    RecyclerView.LayoutManager layoutManager;
    ArrayList<AndroidVersions> list=new ArrayList<>();
    Context ctx;

    public background(Context ctx) {
        this.ctx = ctx;
        activity=(Activity)ctx;
    }

    @Override
    protected void onPreExecute() {
        try {
            recyclerView = (RecyclerView) activity.findViewById(R.id.myRecycle);
            layoutManager = new LinearLayoutManager(ctx);
            recyclerView.setLayoutManager(layoutManager);
            recyclerView.setHasFixedSize(true);
            adapter = new RecyclerAdapter(list);
            recyclerView.setAdapter(adapter);
        } catch (Exception e) {
            Log.d("Runtime Error", e.getMessage());
        }
    }

    @Override
    protected void onPostExecute(String o) {
        //super.onPostExecute(o);
    }

    @Override
    protected String doInBackground(String... voids) {
        String result = "";
        AndroidVersions av= new AndroidVersions("pie");
        publishProgress(av);
        AndroidVersions av2= new AndroidVersions("Oreo");
        publishProgress(av2);
        AndroidVersions av3= new AndroidVersions("Nougat");
        publishProgress(av3);

        return result;
    }

    @Override
    protected void onProgressUpdate(AndroidVersions... values) {
        list.add(values[0]);
        adapter.notifyDataSetChanged();
        //super.onProgressUpdate(values);
    }
}

Androidversions.java:

package com.example.varundhuria.recyclerfilterexample;

public class AndroidVersions {
    String versions;

    public AndroidVersions(String versions) {
        this.versions = versions;
    }

    public String getVersions() {
        return versions;
    }

    public void setVersions(String versions) {
        this.versions = versions;
    }

}

OnQueryTextChange updates ArrayList inside RecyclerView adapter with background class and shows the searched result.

sourav.bh
  • 467
  • 1
  • 7
  • 20
Varun
  • 1
  • take a look at https://stackoverflow.com/questions/4198425/updating-the-list-view-when-the-adapter-data-changes – FabioStein Dec 19 '18 at 19:46

2 Answers2

1

There are two main reasons for failing to achieve search results:

  1. Your OnQueryTextChange() method always creates a new RecyclerView adapter, hence it contains empty list of data while searching.
  2. Your onProgressUpdate() method in background.java class, just updates the list itself but not updating the adapter list of data. So adapter.notifyDataSetChanged() has no effect. However, if you correctly update the adapter, you will not receive the search result either. Because you are not using that adapter in Search.java class, rather using a new adapter instead.

My suggestions would be not to use the RecyclerView adapter inside background.java class at all. To retrieve the result from onProgressUpdate() you can implement a callback/listener in Search.java class and then update your adapter accordingly once you receive a callback.

sourav.bh
  • 467
  • 1
  • 7
  • 20
  • Thank you Sir, I have added a AsynTask class inside Search.java to access the same ArrayList, it works fine. Thank you very much for your valuable sugession to resolve this problem. – Varun Dec 22 '18 at 02:17
  • Hi, @Varun would you mind marking this answer accepted, this could help others who face similar issues. – sourav.bh Dec 24 '18 at 13:50
0

You are creating a new adapter each time the query text is changed. You should call the updateList() method on the adapter set to the recycler view.

Charan M
  • 489
  • 3
  • 7