narkelion
narkelion

Reputation: 7

How to implement adapters and to filter results in a lit?

I'm trying to develop an app, and I'm quite stuck on this problem. I need to filter a list (made up of Libraries), in order to show whether they are open on the morning or not.

I have a class for each library, in which there are two global boolean variable called "isMattina" (isMorning) and "isPomeriggio" ("isAfternoon").

I followed up some guides on the internet, and now my code looks like this:

package com.matteocunsolo.apposto;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.os.Bundle;
import android.os.Environment;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ListView;
import android.widget.AdapterView;
import android.widget.Spinner;
import android.widget.Toast;

import com.matteocunsolo.apposto.IOFromFile;

public class BiblioList extends Activity {
    private Spinner spinner1;
    public static Context context;
    public int length;
    public ArrayList<String> list;
    private Button btnSubmit;
    public boolean[] elencoOrari = TimeBooleanArray.create();
    public Filter mioFiltro;
    public StableArrayAdapter adapter;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.lista);
        setContext();
        addListenerOnButton();
        addListenerOnSpinnerItemSelection();
        final ListView listview = (ListView) findViewById(R.id.listview);
        String filePath = Environment.getExternalStorageDirectory() + "/ApPosto/";
        //InputStream is = getResources().openRawResource(R.raw.elenco_titoli);
        String[] values = IOFromFile.readTextFile(filePath + "elenco_Titoli.txt");
        length = values.length;
        list = new ArrayList<String>();
        for (int i = 0; i < values.length; ++i) {
            list.add(values[i]);
        }
        adapter = new StableArrayAdapter(this, android.R.layout.simple_list_item_1, list);
        listview.setAdapter(adapter);
        Toast.makeText(getApplicationContext(), Integer.toString(list.size()), Toast.LENGTH_SHORT).show();
        listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
                if(position == 0) {
                Intent i = new Intent(BiblioList.this, InfoBiblioteca1.class); 
                startActivity(i);
                }
            else if(position == 1) {
                Intent i = new Intent( BiblioList.this, InfoBiblioteca2.class); 
                startActivity(i);
                }
            else if(position == 4) {
                Intent i = new Intent( BiblioList.this, InfoBiblioteca3.class); 
                startActivity(i);
            }
            else if(position == 5) {
                Intent i = new Intent( BiblioList.this, InfoBiblioteca4.class); 
                startActivity(i);
            }
            }
        });
    }

    public void setContext() {
        context = getApplicationContext();
    }

    public void addListenerOnSpinnerItemSelection() {
        spinner1 = (Spinner) findViewById(R.id.spinner1);
        spinner1.setOnItemSelectedListener(new CustomOnItemSelectedListener());
    }

    public void addListenerOnButton() {
        spinner1 = (Spinner) findViewById(R.id.spinner1);
        btnSubmit = (Button) findViewById(R.id.button1);     
        btnSubmit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(spinner1.getSelectedItem().toString() == null)
                    Toast.makeText(BiblioList.this, "adapter NULL", Toast.LENGTH_SHORT).show();
                else 
                    adapter.getFilter().filter(spinner1.getSelectedItem().toString());
              }

            });
        }


    private class StableArrayAdapter extends ArrayAdapter<String> implements Filterable {
        HashMap<String, Integer> mIdMap = new HashMap<String, Integer>();

        public StableArrayAdapter(Context context, int textViewResourceId, List<String> objects) {
            super(context, textViewResourceId, objects);
            for (int i = 0; i < objects.size(); ++i) {
                mIdMap.put(objects.get(i), i);
            }
        }

        @Override
        public long getItemId(int position) {
          String item = getItem(position);
          return mIdMap.get(item);
        }

        @Override
        public boolean hasStableIds() {
          return true;
        }
        @Override 
        public Filter getFilter() { 
            if (mioFiltro == null) 
                mioFiltro = new MyFilter(); 
            return mioFiltro; 
        }
    }


    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.returntomap, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if(item.getItemId() == R.id.change_layout){ 
            Intent i = new Intent(BiblioList.this, LaunchActivity.class);
            overridePendingTransition(R.anim.anim_in, R.anim.anim_out);
            startActivity(i);
        }

        return true;
    } 

    private class MyFilter extends Filter {

        @Override 
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults(); 
            // We implement here the filter logic 
            if (constraint == null || constraint.length() == 0) { 
                // No filter implemented we return all the list 
                results.values = list; 
                results.count = list.size(); 
            } else { 
                // We perform filtering operation 
                List<String> nlist = new ArrayList<String>();
                if(constraint.equals("Mattina")) {
                    for(int i = 0; i < 4; i = i+2) {
                        if(elencoOrari[i])
                            nlist.add(list.get(i));
                    }
                }
                if(constraint.equals("Pomeriggio")) {
                    for(int i = 1; i < 4; i = i+2) {
                        if(elencoOrari[i])
                            nlist.add(list.get(i));
                    }
                }

                results.values = nlist; 
                results.count = nlist.size(); 
            } return results;
        } 
        @SuppressWarnings("unchecked")
        @Override 
        protected void publishResults(CharSequence constraint, FilterResults results) {
            if (results.count == 0) 
                adapter.notifyDataSetInvalidated(); 
            else { 
                list = (ArrayList<String>) results.values; 
                adapter.notifyDataSetChanged(); 
            } 
        } 
    }

}

This is TimeBooleanArray.java:

package com.matteocunsolo.apposto;

public class TimeBooleanArray {

    public static boolean[] create() {
        boolean[] elencoOrari = new boolean[4];
        for(int i = 0; i<elencoOrari.length; i++) {
            elencoOrari[i] = false;
        }
        if(InfoBiblioteca1.isMattina)
            elencoOrari[0] = true;
        if(InfoBiblioteca1.isPomeriggio)
            elencoOrari[1] = true;
        if(InfoBiblioteca2.isMattina)
            elencoOrari[2] = true;
        if(InfoBiblioteca2.isPomeriggio)
            elencoOrari[3] = true;

        return elencoOrari;
    }
}

Running this app and clicking on the "Filtra" Button, I get no errors from the LogCat, but simply nothing happens. The list remain the same, with the same 6 entries instead of the 1 with the right boolean value.

Than you all in advance!

Upvotes: 0

Views: 2005

Answers (1)

Karakuri
Karakuri

Reputation: 38595

Your code in publishResults never actually changes the content stored by the adapter. The adapter keeps its own reference to the list. You can use clear() and addAll() to change the content of your list.

@Override  
protected void publishResults(CharSequence constraint, FilterResults results) {
    if (results.count == 0) 
        adapter.notifyDataSetInvalidated(); 
    else {  
        adapter.clear();
        adapter.addAll(results.values); 
        adapter.notifyDataSetChanged();
    }  
}

Upvotes: 1

Related Questions