Saboor880 9 Junior Poster

Hello! I have a grid view with the row model having a image view and text view in it. I set a custom adapter to populate the the grid view with images and texts successfully.
But now I want to use a search view to filter the grid view on the base of text in text views. For this I implemented Filterable interface .
When i enter the string in my search view nothing happens. I am pasting my code also. Please check it . All the code is in one class.

Please view the code in the inner classes ImageAdapter and CustomerFilter specially. I have searched on internet for this problem, but by problem not solved. Please guide me what mistake i am doing?

package com.example.hp430.tabsexample;

import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.SearchView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.ads.MobileAds;

import java.util.ArrayList;
import java.util.zip.Inflater;

import static com.example.hp430.tabsexample.MainActivity.MYPREF;
import static com.example.hp430.tabsexample.MainActivity.gridname;

public class TabFragment1 extends android.support.v4.app.Fragment {
    private AdView adView;
    SharedPreferences sharedpreferences;

 @Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup `container, Bundle savedInstanceState) {`
View rootview = inflater.inflate(R.layout.tab_fragment_1,container,false);
SearchView sv = rootview.findViewById(R.id.searchview1);
GridView gridview = (GridView)rootview.findViewById(R.id.pfgrid);

  gridview.setAdapter(new ImageAdapter(getActivity()));

    sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            return false;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
           new ImageAdapter(getActivity()).getFilter().filter(newText);
            return false;
        }
    });

    adView = rootview.findViewById(R.id.ad_view 
    gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            sharedpreferences = getActivity().getSharedPreferences(MYPREF, Context.MODE_PRIVATE);
            String n = sharedpreferences.getString(gridname,"namekey");
           // Toast.makeText(getContext(),n,Toast.LENGTH_SHORT).show();
           Intent i = new Intent(getActivity(),WebViewActivity.class);
           i.putExtra("type",n);
            i.putExtra("position",position);
           startActivity(i);
        }
    });
    // Inflate the layout for this fragment
    return rootview;
}

@Override
public void onAttach(Context context) {
    super.onAttach(context);

}

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

}

@Override
public void onPause() {
    super.onPause();
    if (adView != null) {
        adView.resume();
    }
}

@Override
public void onResume() {
    super.onResume();
    if (adView != null) {
        adView.resume();
    }
    }

    // Inner Class ImageAdapter  in class TabFragment1
public class ImageAdapter extends BaseAdapter implements Filterable{

    private Context mContext;
    // Constructor
    public ImageAdapter(Context c) {
        mContext = c;
    }

    @Override
    public int getCount() {
        return mThumbIds.length;
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ImageView imageView;

        TextView txt;
        LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        if (convertView == null ) {

            convertView = inflater.inflate(R.layout.row_grid, parent, false);

            }
        imageView = convertView.findViewById(R.id.mimageView);
        txt = convertView.findViewById(R.id.mtextView);

        ViewGroup.LayoutParams lp = imageView.getLayoutParams();
        lp.width = 170;
        lp.height = 170;
        imageView.requestLayout();

        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        imageView.setPadding(8, 8, 8, 8);

        imageView.setImageResource(mThumbIds[position]);
        txt.setText(mThumbNames[position]);

        return convertView;
    }

    public Integer[] mThumbIds = {
            R.drawable.alkaram,R.drawable.khaadi,R.drawable.deepakperwani,R.drawable.hsy,
            R.drawable.chenone,R.drawable.mariab,R.drawable.warda,R.drawable.firdous,R.drawable.sanasafinaz,
            R.drawable.sapphire,R.drawable.kayseria,R.drawable.jj,R.drawable.bareeze,R.drawable.gulahmad,
            R.drawable.crossstich,R.drawable.nishatlinen
   };

    public String[] mThumbNames = {
            "Alkaram", "Khaadi","DeepakPerwani", "HSY","Chenone","Mari.b","Warda","Firdous","SanaSafinaz",
            "Sapphire","Kayseria","Junaid Jamshaid","Bareeze","Gul Ahmad","CrossStich","NishatLinen"

    };

    @Override
    public Filter getFilter() {
       Filter filter=null;
        if(filter==null){
            filter = new CustomFilter();
        }
        return filter;
    }

    //Inner class CustomeFilter  in class ImageAdapter
    class CustomFilter extends Filter{
        ArrayList Filterlist = new ArrayList();
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults();
            if(constraint !=null && constraint.length()>0){

                constraint = constraint.toString().toUpperCase();

                //Filtering
                for(int i=0;i<mThumbNames.length;i++){
                    if(mThumbNames[i].toUpperCase().contains(constraint)){
                        int image = mThumbIds[i];
                        String name = mThumbNames[i];

                        Filterlist.add(name);

                    }
                }

                results.count = Filterlist.size();
                results.values =Filterlist;
                Toast.makeText(getActivity(),"count= "+Filterlist.size(),Toast.LENGTH_LONG).show();

            }

            else{
                results.count = Filterlist.size();
                results.values =Filterlist;
            }

            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            Filterlist = (ArrayList ) results.values;
            notifyDataSetChanged();
        }
    }// end class CustomFilter

   }//end  class ImageAdapter

}// end parent class i-e TabFragment1

Dani AI

Generated

Quick diagnosis: the GridView never sees your filtered data because the adapter you call getFilter() on is not the same adapter attached to the GridView, and the Filter you wrote never updates the adapter’s visible data set. Other problems: the filter list is never cleared, getCount() / getView() still read the original arrays, and you show a Toast from inside performFiltering() (which runs off the UI thread).

Fix checklist for

  • Keep one adapter instance as a field, set it once on the GridView, and call adapter.getFilter().filter(query) on that same instance. Do not create a new adapter in onQueryTextChange.
  • Adapter should hold two lists: original (unchanged source) and filtered (what getCount() and getView() return).
  • In performFiltering() build a new filtered list (clear previous), return it in FilterResults.
  • In publishResults() replace the adapter’s filtered list and call notifyDataSetChanged() on the adapter (UI thread).
  • Don’t mutate UI from performFiltering(); show any Toasts or UI hints inside publishResults() if needed.
  • Use proper generics and return a single Filter instance from getFilter().

Minimal example (illustrates structure; integrate into your fragment):

// simple item holder
static class Item { String name; int imageRes; Item(String n, int r){ name = n; imageRes = r; } }

// adapter
public class MyAdapter extends BaseAdapter implements Filterable {
    private final List<Item> original;
    private final List<Item> filtered;
    private final LayoutInflater inflater;
    private ItemFilter filter;

    public MyAdapter(Context c, List<Item> items){
        inflater = LayoutInflater.from(c);
        original = new ArrayList<>(items);
        filtered = new ArrayList<>(items);
    }

    @Override public int getCount(){ return filtered.size(); }
    @Override public Item getItem(int pos){ return filtered.get(pos); }
    @Override public long getItemId(int pos){ return pos; }
    @Override public View getView(int pos, View cv, ViewGroup p){
        View v = (cv != null) ? cv : inflater.inflate(R.layout.row_grid, p, false);
        ImageView iv = v.findViewById(R.id.mimageView);
        TextView tv = v.findViewById(R.id.mtextView);
        Item it = filtered.get(pos);
        iv.setImageResource(it.imageRes);
        tv.setText(it.name);
        return v;
    }

    @Override public Filter getFilter(){ if(filter==null) filter = new ItemFilter(); return filter; }

    private class ItemFilter extends Filter {
        @Override protected FilterResults performFiltering(CharSequence constraint){
            List<Item> res = new ArrayList<>();
            if(constraint == null || constraint.length() == 0) res.addAll(original);
            else {
                String q = constraint.toString().toLowerCase(Locale.getDefault());
                for(Item it : original) if(it.name.toLowerCase(Locale.getDefault()).contains(q)) res.add(it);
            }
            FilterResults fr = new FilterResults(); fr.values = res; fr.count = res.size();
            return fr;
        }
        @Override protected void publishResults(CharSequence c, FilterResults r){
            filtered.clear();
            filtered.addAll((List<Item>) r.values);
            notifyDataSetChanged();
        }
    }
}

Usage in the fragment: create the adapter once, call gridView.setAdapter(adapter), and in onQueryTextChange call adapter.getFilter().filter(newText); and return true. This pattern will make the GridView reflect filtered results correctly.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.