Search code examples
androidjsonandroid-recyclerviewassetssearchview

Android - SearchView filtering a JSON in Assets folder displayed in a RecyclerView


I would need help to figure out how to filter search results through a JSON file placed in the assets folder, displaying it in a RecyclerView. I've previously successfully achieved it by using a JSON uploaded on Firebase, but since I've moved it to the local assets I got lost. I understand I should use some other filtering class, but any attempt seemed to fail. Here's my code so far:

ADAPTER

public class AdapterJSON extends RecyclerView.Adapter<AdapterJSON.MyViewHolderJSON> {

    Context contextJSON;
    ArrayList<String> lang1;
    ArrayList<String> lang2;

    public AdapterJSON(Context contextJSON, ArrayList<String> lang1, ArrayList<String> lang2) {
        this.contextJSON = contextJSON;
        this.lang1 = lang1;
        this.lang2 = lang2;
    }

    @NonNull
    @Override
    public MyViewHolderJSON onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View vJSON = LayoutInflater.from(contextJSON).inflate(R.layout.sections_row, parent, false);
        return new MyViewHolderJSON(vJSON);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolderJSON holder, int position) {

        holder.italian.setText(lang1.get(position));
        holder.indonesian.setText(lang2.get(position));

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(contextJSON, "Yo", Toast.LENGTH_SHORT).show();
            }
        });
    }

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

    public class MyViewHolderJSON extends RecyclerView.ViewHolder {

        TextView italian, indonesian;

        public MyViewHolderJSON(@NonNull View itemView) {
            super(itemView);

            italian = itemView.findViewById(R.id.tvfirstName);
            indonesian = itemView.findViewById(R.id.tvlastName);
        }
    }
}

SEARCH ACTIVITY CLASS

public class SearchActivityJSON extends AppCompatActivity {

    RecyclerView recyclerView;
    AdapterJSON mainAdapter;
    Button button_logout;
    ArrayList<String> lang1 = new ArrayList<>();
    ArrayList<String> lang2 = new ArrayList<>();

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

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        Objects.requireNonNull(getSupportActionBar()).setTitle("");


        recyclerView = findViewById(R.id.recyclerviewId);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setHasFixedSize(true);

        button_logout = findViewById(R.id.button_logout);

        button_logout.setOnClickListener(view -> {
            Intent intent = new Intent(SearchActivityJSON.this, HomeActivity.class);
            startActivity(intent);
        });

    }
@Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.menu_item, menu);
        MenuItem item = menu.findItem(R.id.searchId);
        SearchView searchView = (SearchView) item.getActionView();

        searchView.setIconifiedByDefault(true);
        searchView.setFocusable(true);
        searchView.setIconified(false);
        searchView.requestFocusFromTouch();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {

            @Override
            public boolean onQueryTextSubmit(String newText) {
                mysearch(newText);
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                mysearch(newText);
                return false;
            }
        });
        return super.onCreateOptionsMenu(menu);
    }
    private void mysearch(String newText) {

        String jsonString = loadJSONfromAssets();

        if (newText.isEmpty()) {
            Toast.makeText(this, "There is nothing", Toast.LENGTH_SHORT).show();


    } else {

            try {
                assert jsonString != null;
                JSONObject json = new JSONObject(jsonString);
                JSONArray m_Array = json.getJSONArray("CommonWords");
                for (int i = 0; i < m_Array.length(); i++) {

                    JSONObject inside = m_Array.getJSONObject(i);
                    lang1.add(inside.getString("italian"));
                    lang2.add(inside.getString("indonesian"));
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
            mainAdapter = new AdapterJSON(this, lang1, lang2);
            recyclerView.setAdapter(mainAdapter);
            Toast.makeText(this, "There is something", Toast.LENGTH_SHORT).show();
 }
    }

private String loadJSONfromAssets() {
        String json;
        try {
            InputStream is = getAssets().open("assetPhrasebook.json");
            int size = is.available();
            byte[] buffer = new byte[size];
            is.read(buffer);
            is.close();

            json = new String (buffer, StandardCharsets.UTF_8);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return json;
    }
}

JSON FILE

{
    "Kosong": [
        {
            "italian": "",
            "indonesian": "",
        }
    ],
    "CommonWords": [
        {
            "italian": "Si",
            "indonesian": "Ya",
        },
        {
            "italian": "No",
            "indonesian": "Tidak",
        },
        {
            "italian": "Forse",
            "indonesian": "Mungkin",
        },
        {
            "italian": "Grazie",
            "indonesian": "Terima kasih",
        },
        {
            "italian": "Prego",
            "indonesian": "Sama sama",
        }
 ]
}

Thank you for whoever could help me.


Solution

  • I got it by myself and I share the solution if someone needs that:

    ADAPTER

    public class AdapterSearchJSON extends RecyclerView.Adapter<AdapterSearchJSON.myViewHolderSearchJSON> {
    
    Context context;
    ArrayList<String> lang1;
    ArrayList<String> lang2;
    
    public AdapterSearchJSON(Context context, ArrayList<String> lang1, ArrayList<String> lang2) {
    
        this.context = context;
        this.lang1 = lang1;
        this.lang2 = lang2;
    }
    
    public void updateData(ArrayList<String> lang1, ArrayList<String> lang2){
        this.lang1 = lang1;
        this.lang2 = lang2;
        notifyDataSetChanged();
    }
    
    @NonNull
    @Override
    public myViewHolderSearchJSON onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    
        View vJSON = LayoutInflater.from(parent.getContext()).inflate(R.layout.search_results_row, parent, false);
        return new myViewHolderSearchJSON(vJSON);
    }
    
    @Override
    public void onBindViewHolder(@NonNull myViewHolderSearchJSON holder, int position) {
    
        holder.italian.setText(lang1.get(position));
        holder.indonesian.setText(lang2.get(position));
    }
    
    @Override
    public int getItemCount() {
        return lang1.size();
    }
    
    public class myViewHolderSearchJSON extends RecyclerView.ViewHolder {
        TextView italian, indonesian;
    
        public myViewHolderSearchJSON(@NonNull View itemView) {
            super(itemView);
    
            italian = itemView.findViewById(R.id.firstLanguage);
            indonesian = itemView.findViewById(R.id.italian);
        }
    
    }}
    

    SEARCHVIEW ACTIVITY

    public class SearchActivityJSON extends AppCompatActivity {
    
    RecyclerView recyclerView;
    AdapterSearchJSON adapterSearchJSON;
    Button button_logout;
    ArrayList<String> lang1;
    ArrayList<String> lang2;
    
    String searchStr = "";
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test_search);
    
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        Objects.requireNonNull(getSupportActionBar()).setTitle("");
    
        lang1 = new ArrayList<>();
        lang2 = new ArrayList<>();
    
        recyclerView = findViewById(R.id.recyclerviewId);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setHasFixedSize(true);
    
        adapterSearchJSON = new AdapterSearchJSON(this, lang1, lang2);
        recyclerView.setAdapter(adapterSearchJSON);
    
        button_logout = findViewById(R.id.button_logout);
    
        addItemFromJSON();
    
        final Handler handler = new Handler(Looper.getMainLooper());
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                //Do something after 100ms
                searchStr = "";
                addItemFromJSON();
                adapterSearchJSON.updateData(lang1,lang2);
    
            }
        }, 100);
    
        //intent back button
        button_logout.setOnClickListener(view -> {
            Intent intent = new Intent(SearchActivityJSON.this, HomeActivity.class);
            startActivity(intent);
        });
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    
        getMenuInflater().inflate(R.menu.menu_item, menu);
        MenuItem item = menu.findItem(R.id.searchId);
        SearchView searchView = (SearchView) item.getActionView();
    
        searchView.setIconifiedByDefault(true);
        searchView.setFocusable(true);
        searchView.setIconified(false);
        searchView.requestFocusFromTouch();
    
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
    
            @Override
            public boolean onQueryTextSubmit(String newText) {
                return false;
            }
    
            @Override
            public boolean onQueryTextChange(String newText) {
    
                searchStr = newText;
                addItemFromJSON();
                adapterSearchJSON.updateData(lang1,lang2);
    
                return true;
            }
        });
        return true;
    }
    
    private String loadJSONfromAssets() {
        String json;
        try {
            InputStream is = getAssets().open("assetPhrasebook.json");
            int size = is.available();
            byte[] buffer = new byte[size];
            is.read(buffer);
            is.close();
    
            json = new String (buffer, StandardCharsets.UTF_8);
    
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return json;
    }
    
    private void addItemFromJSON() {
    
        ArrayList<String> lang1t = new ArrayList<>();
        ArrayList<String> lang2t = new ArrayList<>();
    
        try {
    
            String name = "";
    
            String jsonString = loadJSONfromAssets();
    
            assert jsonString != null;
            JSONObject json = new JSONObject(jsonString);
            JSONArray m_Array = json.getJSONArray("CommonWords");
            for (int i = 0; i < m_Array.length(); i++) {
                JSONObject inside = m_Array.getJSONObject(i);
                if (inside.getString("italian").trim().toLowerCase().contains(searchStr.trim().toLowerCase()))
                {
                    lang1t.add(inside.getString("italian"));
                    lang2t.add(inside.getString("indonesian"));
                }
            }         
    
            this.lang1 = lang1t;
            this.lang2 = lang2t;
    
        } catch (Exception e) {
            e.printStackTrace();
        }
    }}
    

    Safe to use!