简体   繁体   中英

ListView error getting one OnCheckedChange position

I'm trying to create a listview to show users that can be added by pressing a ToggleButton. The problem is that when you press a toggleButton more than one id is returned, and every time I move the scroll more ids are returned .. without pressing any. :S

App Screenshot (only one click in the first element):

App屏幕截图(在第一个元素中只需单击一下):

LogCat recieving on SELECCIONAT(checked) AND DESSELECCIONAT(unchecked) TAGS (2 times the first element, and one time the second element.. with only one click...

LogCat正在接收...:

The code:

MyAdapter:

public class MyAdapter extends ArrayAdapter<Usuari> {

    private final List<Usuari> list;
    private final Activity context;
    boolean checkAll_flag = false;
    boolean checkItem_flag = false;

    public MyAdapter(Activity context, List<Usuari> list) {
        super(context, R.layout.row, list);
        this.context = context;
        this.list = list;
    }

    static class ViewHolder {
        protected TextView nom_usuari;
        protected ToggleButton boto_agregar;
    }

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

        ViewHolder viewHolder = null;
        if (convertView == null) {
            LayoutInflater inflator = context.getLayoutInflater();
            convertView = inflator.inflate(R.layout.row, null);
            viewHolder = new ViewHolder();
            viewHolder.nom_usuari = (TextView) convertView
                    .findViewById(R.id.nom_usuari);
            viewHolder.boto_agregar = (ToggleButton) convertView
                    .findViewById(R.id.boto_agregar);

            viewHolder.boto_agregar
                    .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

                        public void onCheckedChanged(CompoundButton buttonView,
                                boolean isChecked) {
                            int getPosition = (Integer) buttonView.getTag(); // Here
                                                                                // we
                                                                                // get
                                                                                // the
                                                                                // position
                                                                                // that
                                                                                // we
                                                                                // have
                                                                                // set
                                                                                // for
                                                                                // the
                                                                                // checkbox
                                                                                // using
                                                                                // setTag.
                            list.get(getPosition).setSelected(
                                    buttonView.isChecked()); // Set the value of
                                                                // checkbox to
                                                                // maintain its
                                                                // state.
                            String nom = list.get(getPosition).getName();
                            if (isChecked) {
                                Log.d("SELECCIONAT", nom);

                            } else {
                                Log.d("DESSELECCIONAT", nom);

                            }
                        }
                    });

            convertView.setTag(viewHolder);
            convertView.setTag(R.id.nom_usuari, viewHolder.nom_usuari);
            convertView.setTag(R.id.boto_agregar, viewHolder.boto_agregar);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        viewHolder.boto_agregar.setTag(position); // This line is important.

        viewHolder.nom_usuari.setText(list.get(position).getName());
        viewHolder.boto_agregar.setChecked(list.get(position).isSelected());

        return convertView;
    }

}

Usuari.java:

public class Usuari {

        private String nom;
        private boolean selected;

        public Usuari(String nom, boolean selected) {
            this.nom = nom;
            this.selected =selected;
        }

        public String getName() {
            return nom;
        }

        public boolean isSelected() {
            return selected;
        }

        public void setSelected(boolean selected) {
            this.selected = selected;
        }
    } 

MainActivity:

    public class BuscarUsuaris extends Activity implements OnQueryTextListener {
        ToggleButton boto_agregar;
        TextView nom_usuari;
        ListView listView;
        private SearchView searchView;

        public boolean pressed = false;
        ArrayAdapter<Usuari> adapter;
        List<Usuari> list = new ArrayList<Usuari>();



        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.buscar_usuaris);
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
                    .permitAll().build();
            StrictMode.setThreadPolicy(policy);
            ActionBar actionBar = getActionBar();
            actionBar.setDisplayHomeAsUpEnabled(true);
            nom_usuari = (TextView) findViewById(R.id.nom_usuari);
            boto_agregar=(ToggleButton)findViewById(R.id.boto_agregar);

            listView = (ListView) findViewById(R.id.listView1);
            adapter = new MyAdapter(this,list);
            listView.setAdapter(adapter);


            SharedPreferences dades_login = getSharedPreferences("perfil",
                    MODE_PRIVATE);
            String id = dades_login.getString("id", "");


        }


 private void connect(String busqueda) {
            String data = null;


            adapter.clear(); 
            List<NameValuePair> parametres = new ArrayList<NameValuePair>();
            parametres.add(new BasicNameValuePair("busqueda", busqueda));
            try {
                DefaultHttpClient client = new DefaultHttpClient();
                HttpPost request = new HttpPost(
                        "MY_HOST");
                request.setEntity(new UrlEncodedFormEntity(parametres));
                HttpResponse response = client.execute(request);
                HttpEntity entity = response.getEntity();
                data = EntityUtils.toString(entity);
                Log.e("DADES OBTINGUDES", data);

                try {

                    JSONArray json = new JSONArray(data);
                    int limit = 50;
                    if(json.length()<limit){limit=json.length();}
                    for (int i = 0; i < limit; i++) {
                        JSONObject obj = json.getJSONObject(i);
                        String nombre = obj.getString("nombre");
                        boolean selected = false;
                        Log.e("PERSONA TROBADA:", nombre);

                        list.add(new Usuari(nombre,selected));

                        listView.setAdapter(adapter);

                    }

                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            } catch (ClientProtocolException e) {
                Log.d("HTTPCLIENT", e.getLocalizedMessage());
            } catch (IOException e) {
                Log.d("HTTPCLIENT", e.getLocalizedMessage());
            }

        }

This is because the listView refresh itself so onCreateView gives you the default values. My solution is to create an ArrayList with the states of ToggleButton. so add:

ArrayList<Boolean> isChecked;
//in your constructor
isChecked = new ArrayList<Boolean>();
for(int i=0;i<list.size();i++){
    isChecked.add(false);
}

//on your getView 

viewHolder.boto_agregar.setChecked(isChecked.get(position));

 viewHolder.boto_agregar.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
       private pos = position;
       public void onCheckedChanged(CompoundButton buttonView,
                                boolean isChecked) {
               isChecked.set(pos, isChecked);
       }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM