Ошибка ListView при получении одной позиции OnCheckedChange
Я пытаюсь создать просмотр списка, чтобы показать пользователей, которые могут быть добавлены нажатием кнопки ToggleButton. Проблема в том, что когда вы нажимаете кнопку toggleButton, возвращается более одного идентификатора, и каждый раз, когда я перемещаю прокрутку, возвращаются все больше идентификаторов... без нажатия кнопки.: S
Снимок экрана приложения (только один клик в первом элементе):
LogCat получает по меткам SELECCIONAT(проверено) и DESSELECCIONAT(не проверено) (2 раза первый элемент и один раз второй элемент... одним щелчком мыши...
Код:
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;
}
}
Основная деятельность:
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());
}
}
1 ответ
Это связано с тем, что listView обновляется сам, поэтому onCreateView предоставляет значения по умолчанию. Мое решение - создать ArrayList со состояниями ToggleButton. так что добавьте:
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);
}
});