Search code examples
javaandroidlistviewandroid-listfragmentcustom-arrayadapter

Filter data by input in custom ArrayAdapter displays empty items


I implemented EditText widget to filter items in ListFragment using custom ArrayAdapter.

It works fine but the filtered list contains EMPTY items as well as filtered items.

I found that i should clear the adapter before to repopulate it, right?

Could it be something like

adapter.clear();
listview.getAdapter().notifyDataSetChanged();

Anyway I cannot find working solution.

Any clue to fix this bug, please?

public class CustomListAdapter extends ArrayAdapter<UnitView> {

    private static final String TAG = "FRAGMENT TWO";
    private final Activity context;
    private final UnitView[] dataSource;
    private UnitView[] unitViews;

    public CustomListAdapter(Activity context, UnitView[] units) {
        super(context, R.layout.unit, units);

        this.context = context;
        this.unitViews = units;
        this.dataSource = units;
    }

    public View getView(int position,View view,ViewGroup parent) {
        view = null;
        try
        {

         if (view == null)
         {

            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.listview_item, null);

            UnitView uv = unitViews[position];
            view.setTag(uv);

             TextView textViewTypeName = (TextView) view.findViewById(R.id.textViewTypeName);
             textViewTypeName.setText(uv.getDeviceTypeName());

             // Code to populate widgets ....

        }

        }
        catch (Exception ex)
        {

            Log.d(TAG, ex.getMessage());
        }

        return view;
    };

    // Filter input data in ListFragment
    public void filter(String charText) {

        try
        {
            charText = charText.toLowerCase(Locale.getDefault());

            unitViews = new UnitView[dataSource.length];

            if (charText.length() == 0) {
                unitViews = Arrays.copyOf(this.dataSource, this.dataSource.length);
            }
            else
            {
                List<UnitView> result = new ArrayList<UnitView>();
                for (UnitView uv : dataSource)
                {
                    if (uv.getNumber().toLowerCase(Locale.getDefault()).contains(charText))
                    {
                        result.add(uv);
                    }
                }

                if(result.size() > 0)
                {
                    unitViews = result.toArray(new UnitView[result.size()]);
                }
            }

            notifyDataSetChanged();
        }
        catch (Exception ex)
        {
            Log.d(TAG, ex.getMessage());
        }
    }

    public static boolean isBlank(String value) {
        return (value == null || value.equals("") || value.equals("null") || value.trim().equals(""));
    }
}

FragmentTwo.java

protected void onPostExecute(String s) {
            super.onPostExecute(s);

            try {
                Gson gson = new Gson();
                unitViews = gson.fromJson(s, UnitView[].class);

                if (unitViews.length > 0) {

                    ArrayList<String> names = new ArrayList<String>();

                    for (int i = 0; i < unitViews.length; i++) {

                        String name = unitViews[i].getName();
                        names.add(name);
                    }
                    String[] values = names.toArray(new String[unitViews.length]);

                    adapter = new CustomListAdapter(getActivity(), unitViews);
                    setListAdapter(adapter);

                    // Locate the EditText in listview_main.xml
                    editSearch = (EditText)getActivity().findViewById(R.id.editSearch);

                    // Capture Text in EditText
                    editSearch.addTextChangedListener(new TextWatcher() {

                        @Override
                        public void afterTextChanged(Editable arg0) {                         

                            // TODO Auto-generated method stub
                            String text = editSearch.getText().toString().toLowerCase(Locale.getDefault());
                            adapter.filter(text);
                        }

                        @Override
                        public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
                        }

                        @Override
                        public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
                        }
                    });

                    Log.d(TAG, s);
                }
            }
            catch (Exception ex)
            {
                Log.e(TAG, "Error: ", ex);
            }
        }

Solution

  • Ok, I found solution by relocating filter code to onPostExecute and re-initializing adapter.

    protected void onPostExecute(String s) {
                super.onPostExecute(s);
    
                try {
                    Gson gson = new Gson();
                    unitViews = gson.fromJson(s, UnitView[].class);
    
                    if (unitViews.length > 0) {
    
                        ArrayList<String> names = new ArrayList<String>();
    
                        for (int i = 0; i < unitViews.length; i++) {
    
                            String name = unitViews[i].getName();
                            names.add(name);
                        }
                        String[] values = names.toArray(new String[unitViews.length]);
    
                        adapter = new CustomListAdapter(getActivity(), unitViews);
                        setListAdapter(adapter);
    
    
                        // Locate the EditText in listview_main.xml
                        editSearch = (EditText)getActivity().findViewById(R.id.editSearch);
    
                        // Capture Text in EditText
                        editSearch.addTextChangedListener(new TextWatcher() {
    
                            @Override
                            public void afterTextChanged(Editable arg0) {
    
                                // TODO Auto-generated method stub
                                String text = editSearch.getText().toString().toLowerCase(Locale.getDefault());
    
    
                                // adapter.filter(text);
    
                                try
                                {
                                    text = text.toLowerCase(Locale.getDefault());
    
    
    
                                    UnitView[] resultUnitViews = new UnitView[0];
    
                                    if (text.length() == 0) {
                                        resultUnitViews = Arrays.copyOf(unitViews, unitViews.length);
                                    }
                                    else
                                    {
                                        List<UnitView> result = new ArrayList<UnitView>();
                                        for (UnitView uv : unitViews)
                                        {
                                            if (uv.getNumber().toLowerCase(Locale.getDefault()).contains(text))
                                            {
                                                result.add(uv);
                                            }
                                        }
    
                                        if(result.size() > 0)
                                        {
                                            resultUnitViews = result.toArray(new UnitView[result.size()]);
    
                                            adapter = new CustomListAdapter(getActivity(), resultUnitViews);
                                            setListAdapter(adapter);
                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    Log.d(TAG, ex.getMessage());
                                }
                            }
    
                            @Override
                            public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
                            }
    
                            @Override
                            public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
                            }
                        });
    
                        Log.d(TAG, s);
                    }
                }
                catch (Exception ex)
                {
                    Log.e(TAG, "Error: ", ex);
                }
            }