Search code examples
javaandroidandroid-listview

Android Java: Custom adapter for listview for scrolling and filtering issue


I have searched online that I need a custom adapter for my listview to solve the scrolling and filtering issue. I am using fragments since I have some tabs on my main activity.

I have tried to implement different variations of codes that I found but I could not make it work.

public class Symptoms extends Fragment {
    String filename = "symptoms.txt";
    private static final String TAG = "SymptomsFragment";
    ReadFile rf = new ReadFile();
    String[] lines;
    ListView simpleList;
    Context context;
    private EditText filterText;
    private ArrayAdapter<String> arrayAdapter;
    ArrayList<String> listItems = new ArrayList<String>();
    int count = 0;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        final View mView = inflater.inflate(R.layout.symptoms_layout,container,false);
        simpleList = (ListView) mView.findViewById(R.id.list);
        filterText = (EditText) mView.findViewById(R.id.editText);
        try {
            lines = rf.readLines(filename, getContext());
            arrayAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, lines);
            simpleList.setAdapter(arrayAdapter);
        }
        catch(IOException e) {
            // Print out the exception that occurred
            Toast.makeText(getContext(), "Unable to create "+filename+": "+e.getMessage(), Toast.LENGTH_LONG).show();
        }
        filterText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) { }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                arrayAdapter.getFilter().filter(s);
            }

            @Override
            public void afterTextChanged(Editable s) { }
        });
        simpleList.setCacheColorHint(Color.TRANSPARENT);
        simpleList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        simpleList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                TextView tv = (TextView)view.findViewById(android.R.id.text1);
                String selectedSymptom = tv.getText().toString();
                if(!listItems.contains(selectedSymptom)) {
                    tv.setTextColor(Color.WHITE);
                    tv.setBackgroundColor(Color.CYAN);
                    listItems.add(selectedSymptom);
                }else{
                    tv.setTextColor(Color.BLACK);
                    tv.setBackgroundColor(Color.TRANSPARENT);
                    listItems.remove(selectedSymptom);
                }
                System.out.println(listItems);
            }
        });
        return mView;
    }
}

I am reading a text file and saving each line to an arraylist element and I am using the ArrayAdapter for my listview. I am changing the background and text color of the selected items. However when I am using the "EditText" to search on the listview or when I am scrolling the elements that were highlighted are getting shuffled (visually only). I have found many solutions online for people that were facing the same problem with their checkboxes in the listview but I was having a really hard time to implement those solutions. How should the Custom Listview adapter look like in this situation? Thanks in advance!


Solution

  • Try change:

    arrayAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, lines);
    

    To:

            arrayAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, lines){
                @Override
                public View getView(int position, View convertView, ViewGroup parent) {
                    TextView tv1 = (TextView)super.getView(position, convertView, parent);
                    String selectedSymptom = getItem(position);
                    if(listItems.contains(selectedSymptom)) {
                        tv1.setTextColor(Color.WHITE);
                        tv1.setBackgroundColor(Color.CYAN);
                    }else{
                        tv1.setTextColor(Color.BLACK);
                        tv1.setBackgroundColor(Color.TRANSPARENT);
                    }
                    return tv1;
                }
            };
    

    Hope that helps!