1

i write a own ArrayAdapter like this one:

public class PoiListAdapter extends ArrayAdapter<Poi> implements Filterable {

    private Context context;
    private final List<Poi> valuesPoi;
    private ItemsFilter mFilter;

    public PoiListAdapter(Context context, List<Poi> valuesPoi) {
        super(context, R.layout.poilist);
        this.context = context;
        this.valuesPoi = valuesPoi;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View rowView = inflater.inflate(R.layout.poilist, parent, false);
        TextView textViewName = (TextView) rowView.findViewById(R.id.name_poi);
        TextView textViewDis = (TextView) rowView
                .findViewById(R.id.discrip_poi);
        textViewName.setText(valuesPoi.get(position).getName());
        textViewDis.setText(valuesPoi.get(position).getDiscription());
        return rowView;
    }

    /**
     * Implementing the Filterable interface.
     */
    public Filter getFilter() {
        if (mFilter == null) {
            mFilter = new ItemsFilter(this);
        }
        return mFilter;
    }

    public List<Poi> getValuesPoi() {
        return valuesPoi;
    }

    public void addValuesPoi(Poi p) {
        valuesPoi.add(p);
    }
      @Override
  public void clear() {
    valuesPoi.clear();
  }
}

For this Adapter I want to implement a search function. Therefore I implement a custom Filter-Class:

public class ItemsFilter extends Filter {

private PoiListAdapter poiListAdapter;

public ItemsFilter(PoiListAdapter poiListAdapter) {
    this.poiListAdapter = poiListAdapter;
}

@Override
protected FilterResults performFiltering(CharSequence constraint) {
    constraint = constraint.toString().toLowerCase();
    FilterResults result = new FilterResults();
    ArrayList<Poi> filterList = new ArrayList<Poi>();
    if (constraint != null && constraint.toString().length() > 0) {
        ArrayList<Poi> orginalList = new ArrayList<Poi>(
                poiListAdapter.getValuesPoi());

        for (Poi p : orginalList) {
            if (p.getName().toLowerCase().contains(constraint))
                filterList.add(p);
        }
        Log.i("DEBUG", orginalList.toString());
        result.values = filterList;
        result.count = filterList.size();

    } else {

        result.values = poiListAdapter.getValuesPoi();
        result.count = poiListAdapter.getValuesPoi().size();

    }
    return result;
}

@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
    ArrayList<Poi> fitems = (ArrayList<Poi>) results.values;
    poiListAdapter.clear();
    for (Poi p : fitems) {
        poiListAdapter.addValuesPoi(p);
        poiListAdapter.notifyDataSetChanged();
    }
}

The 1. Problem

....is that i got a java.util.concurrentmodificationexception for:

for (Poi p : fitems) {
            poiListAdapter.addValuesPoi(p);
            poiListAdapter.notifyDataSetChanged();
        }

I think the problem is that I want to modifi a Arraylist under access. I think I have to work with synchronized, but I have never worked with it before.

UPDATE: This is problem is solved! Here the Code:

for(Iterator<Poi> i = fitems.iterator(); i.hasNext();) {
        Poi p = i.next();
        poiListAdapter.addValuesPoi(p);
        //poiListAdapter.notifyDataSetChanged();
    }

The 2. Problem

The List view is empty at start. At the start i want to shown all elements! Also is nothing displayed by searching an element! Listview shows nothing at the moment!

1
  • First Problem is solved! Commented Jun 21, 2013 at 12:26

4 Answers 4

2

ConcurentModification can be avoided in two ways :

  1. poiListAdapter.addValuesPoi(p) add this code in a synchronized method .Synchronized method can't be accessed concurrently .

  2. Use Collections.synchronizedList

Sign up to request clarification or add additional context in comments.

Comments

1

The for-each loop use an Iterator internally, and you can not add nothing to your collection while you are iterating (that's why of the exception). Try creating a new instance of the ArrayList and interate upon it

@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
    ArrayList<Poi> fitems = new ArrayList((ArrayList<Poi>) results.values);
    poiListAdapter.clear();
    for (Poi p : fitems) {
        poiListAdapter.addValuesPoi(p);
        poiListAdapter.notifyDataSetChanged();
    }
}

the for-each is something like:

for(Iterator<Poi> i = fitms.iterator(); i.hasNext(); ) {
  Poi item = i.next();    
}

Problem 2:

The List is empty at start probably because the dataset you submit is empty

Comments

1

@JavaNullPointer : I was having the same problem as you did. I tried to implement the solutions provided here but was having different kinds of problem.. after thinking for a while, I assumed that the default Filter might be using toString() method of the object to filter... this turned to me right. It saved me a lot of hassle..

reading at your codes, I believe you want to filter by the name field of Poi class. if so, then the quick solution would be SOLUTION:

public class Poi{

//your constructors and methods

@Override
public String toString(){
   return getName(); 
}

Comments

0

i could solve my Problems. Here my solution!

    package hsos.ds.helper;

import hsos.ds.db.Poi;

import java.util.ArrayList;
import java.util.List;
import android.widget.Filter;

public class ItemsFilter extends Filter {

    private PoiListAdapter poiAdapter;
    private List<Poi> valuesPoi;
    private List<Poi> filteredPoi;

    public ItemsFilter(PoiListAdapter _poiAdapter) {
        this.poiAdapter = _poiAdapter;
        this.valuesPoi = poiAdapter.getValuesPoi();
        this.filteredPoi = poiAdapter.getFilteredPoi();
    }

    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        FilterResults result = new FilterResults();
        constraint = constraint.toString().toLowerCase();

        if (constraint == null || constraint.length() == 0) {
            ArrayList<Poi> list = new ArrayList<Poi>(valuesPoi);
            result.values = valuesPoi;
            result.count = valuesPoi.size();

        } else {
            final ArrayList<Poi> orginalList = new ArrayList<Poi>(valuesPoi);
            final ArrayList<Poi> filterList = new ArrayList<Poi>();
            int count = orginalList.size();
            for (int i = 0; i < count; i++) {
                final Poi p = orginalList.get(i);
                if (p.getName().toLowerCase().contains(constraint))
                    filterList.add(p);
            }
            result.values = filterList;
            result.count = filterList.size();
        }
        return result;
    }

    @SuppressWarnings("unchecked")
    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        filteredPoi = (List<Poi>) results.values;
        poiAdapter.notifyDataSetChanged();
        poiAdapter.clear();
        int count = filteredPoi.size();
        for (int i = 0; i < count; i++) {
            poiAdapter.add(filteredPoi.get(i));
            poiAdapter.notifyDataSetInvalidated();
        }
    }
}

and the Adapter:

public class PoiListAdapter extends ArrayAdapter implements Filterable {

private List<Poi> valuesPoi;
private List<Poi> filteredPoi;
private ItemsFilter mFilter;

public PoiListAdapter(Context context, List<Poi> valuesPoi) {
    super(context, R.layout.poilist);
    this.valuesPoi = new ArrayList<Poi>(valuesPoi);
    this.filteredPoi = new ArrayList<Poi>(valuesPoi);
    this.mFilter = new ItemsFilter(this);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    if (v == null) {
        LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.poilist, null);
    }

    Poi p = filteredPoi.get(position);

    if (p != null) {
        TextView tt = (TextView) v.findViewById(R.id.name_poi);
        TextView bt = (TextView) v.findViewById(R.id.discrip_poi);
        if (tt != null) {
            tt.setText(p.getName());
        }
        if (bt != null) {
            bt.setText(p.getDiscription());
        }
    }
    return v;
}

@Override
public Filter getFilter() {
    if (mFilter == null) {
        mFilter = new ItemsFilter(this);
    }
    return mFilter;
}

public List<Poi> getValuesPoi() {
    return valuesPoi;
}


public List<Poi> getFilteredPoi() {
    return filteredPoi;

}

}

To show the complete list onStart() i insert the a little "hack" in the onStart()-Method of my activity because the complete list is shown after an input:

if(searchText!=null){
        searchText.setText(" ");
        searchText.setText("");
    }

1 Comment

Any idea how to resolve this? stackoverflow.com/questions/20524417/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.