3 Stimmen

Checkbox in ListView funktioniert nicht ordnungsgemäß

Ich implementiere das Kontrollkästchen mit der ListView für jedes Element der ListView. Das Problem, das ich habe, ist, dass wenn ich auf ein einzelnes Kontrollkästchen klicke und dann scrolle, einige andere Kontrollkästchen, die nicht angeklickt wurden, zufällig angeklickt werden. Ich habe viele Links auf SO durchgelesen, aber sie haben mein Problem nicht gelöst.

public class CustomListViewAdapter extends ArrayAdapter {

ViewHolder holder = null;
private LayoutInflater inflator = null;
private ArrayList orderList = null;
ArrayList allViews;

public CustomListViewAdapter(Context context, int resource,
        List objects) {
    super(context, resource, objects);

    orderList = (ArrayList) objects;
    inflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    allViews = new ArrayList();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if(convertView == null) {
        convertView = inflator.inflate(R.layout.listview_add_order, null);
        holder = new ViewHolder();
        convertView.setTag(holder);
        holder.txtViewName = (TextView) convertView.findViewById(R.id.txtViewAddOrder);
        holder.spinnerAddorder = (Spinner) convertView.findViewById(R.id.spinnerAddOrder);
        holder.checkAddorder = (CheckBox) convertView.findViewById(R.id.checkAddOrder);
        holder.checkAddorder.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();

        holder.checkAddorder.setTag(holder);
    }

    allViews.add(position, holder.spinnerAddorder);

    holder.checkAddorder.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View view) {
            CheckBox cchk = (CheckBox)view;
            ViewHolder checkPosition = (ViewHolder) view.getTag();

            if(cchk.isChecked()) {

                checkPosition.spinnerAddorder.setVisibility(View.VISIBLE);

            } else {
                checkPosition.spinnerAddorder.setVisibility(View.INVISIBLE);
            }
        }
    });

    List list = new ArrayList();
    list.add("Select Quantity");
    list.add("1");
    list.add("2");
    list.add("3");
    ArrayAdapter dataAdapter = new ArrayAdapter(this.getContext(),R.layout.spinner_add_order_style, list);
    dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_item);
    holder.spinnerAddorder.setAdapter(dataAdapter);

    if(holder.checkAddorder.isChecked()) {

        ViewHolder checkPosition = (ViewHolder) holder.checkAddorder.getTag();
        checkPosition.spinnerAddorder.setVisibility(View.VISIBLE);
    } else {

        ViewHolder checkPosition = (ViewHolder) holder.checkAddorder.getTag();
        checkPosition.spinnerAddorder.setVisibility(View.INVISIBLE);
    }

    Client order = orderList.get(position);

    holder.txtViewName.setText(order.getFirstName());
    return  convertView;
}

private static class ViewHolder {
    public TextView txtViewName = null;
    public Spinner spinnerAddorder = null;
    public CheckBox checkAddorder = null;
}

     }

meine XML-Datei ist

5voto

Koded101 Punkte 375

Das passiert aufgrund des View-Recyclings. Was du tun musst, ist ein Array von z. B. Booleans zu führen und jedes Mal, wenn ein Kontrollkästchen aktiviert wird, den entsprechenden Boolean umzuschalten. Dann prüfe in deiner getView-Methode die entsprechende Position im Boolean-Array und setze den Zustand des Kontrollkästchens.

In dieser Richtung habe ich es geändert, damit es korrekt angezeigt wird. Habe nicht überprüft, was der Rest deines Codes macht. ^_^

public class CustomListViewAdapter extends ArrayAdapter {

ViewHolder holder = null;
private LayoutInflater inflator = null;
private ArrayList orderList = null;
ArrayList allViews;

boolean[] checkedStates; //********** NEU ********

public CustomListViewAdapter(Context context, int resource,
        List objects) {
    super(context, resource, objects);

    orderList = (ArrayList) objects;
    inflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    allViews = new ArrayList();

    checkedStates = new boolean[objects.size()]; //********** NEU ********
}

@Override   //********** NEU ******** position Argument ist jetzt final 
public View getView(final int position, View convertView, ViewGroup parent) {
    if(convertView == null) {
        convertView = inflator.inflate(R.layout.listview_add_order, null);
        holder = new ViewHolder();
        convertView.setTag(holder);
        holder.txtViewName = (TextView) convertView.findViewById(R.id.txtViewAddOrder);
        holder.spinnerAddorder = (Spinner) convertView.findViewById(R.id.spinnerAddOrder);
        holder.checkAddorder = (CheckBox) convertView.findViewById(R.id.checkAddOrder);
        holder.checkAddorder.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();

        holder.checkAddorder.setTag(holder);
    }

    allViews.add(position, holder.spinnerAddorder);

    holder.checkAddorder.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View view) {

              checkedStates[position] = !checkedStates[position]; //********** NEU ********
        }
    });

    holder.checkAddorder.setChecked(checkedStates[position]); //********** NEU ********

    List list = new ArrayList();
    list.add("Select Quantity");
    list.add("1");
    list.add("2");
    list.add("3");
    ArrayAdapter dataAdapter = new ArrayAdapter(this.getContext(),R.layout.spinner_add_order_style, list);
    dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_item);
    holder.spinnerAddorder.setAdapter(dataAdapter);

    if(checkedStates[position]) { //********** AM NEUESTEN ******** angenommen, true bedeutet ausgewählt und false bedeutet nicht ausgewählt

        ViewHolder checkPosition = (ViewHolder) holder.checkAddorder.getTag();
        checkPosition.spinnerAddorder.setVisibility(View.VISIBLE);
    } else {

        ViewHolder checkPosition = (ViewHolder) holder.checkAddorder.getTag();
        checkPosition.spinnerAddorder.setVisibility(View.INVISIBLE);
    }

    Client order = orderList.get(position);

    holder.txtViewName.setText(order.getFirstName());
    return  convertView;
}

private static class ViewHolder {
    public TextView txtViewName = null;
    public Spinner spinnerAddorder = null;
    public CheckBox checkAddorder = null;
}

     }

1voto

Akshay Sharma Punkte 157

Setzen Sie einfach die focusable-Eigenschaft auf false. Fügen Sie einen onClickListener auf CheckBox im Adapter hinzu.

{ }

0voto

gavrbhat Punkte 190

Verwenden Sie die bidirektionale Datenbindung, um den Checkbox-Zustand zu handhaben https://developer.android.com/topic/libraries/data-binding/two-way#kotlin

`

/>

class LoginViewModel : BaseObservable { // val data = ...

@Bindable
fun getRememberMe(): Boolean {
    return data.rememberMe
}

fun setRememberMe(value: Boolean) {
    // Vermeidet Endlosschleifen.
    if (data.rememberMe != value) {
        data.rememberMe = value

        // Reagiere auf die Änderung.
        saveData()

        // Benachrichtige Beobachter über einen neuen Wert.
        notifyPropertyChanged(BR.remember_me)
    }
}

}

`

0voto

Überschreiben Sie diese Methoden in Ihrem Adapter:

override fun getItemId(position: Int) = position.toLong()

override fun getItemViewType(position: Int) = position

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X