Domanda

Ho un elenco di caselle di controllo nell'elenco vincolato da Personalizzato simpleCursorAdapter.Secondo la mia abitudine simpleCursorAdapter, ho sovrascritto newView E bindView con le mie modificheSono riuscito in qualche modo a fare la scelta multipla.La cosa strana è che, dopo aver eliminato un elemento dalla mia lista, la casella di controllo del primo elemento viene selezionata all'improvviso.Come succede?Come posso risolverlo?

Mio SimpleCursorAdapter classe:

public class MyListCursorAdapter extends SimpleCursorAdapter
{
    private Context context;
    private int layout;

    public MyCursorAdapter(Context context, int layout, Cursor c,
            String[] from, int[] to)
    {
        super(context, layout, c, from, to);
        this.context = context;
        this.layout = layout;
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent)
    {
        Cursor c = getCursor();
        final LayoutInflater inflater = LayoutInflater.from(context);
        View v = inflater.inflate(layout, parent, false);
        CheckBox chkBoxBtn = (CheckBox) v.findViewById (R.id.deleteTwittChkBox);
        if (chkBoxBtn != null)
        {
            chkBoxBtn.setChecked(false);
        }
        return v;
    }

    @Override
    public void bindView(View v, Context context, Cursor c)
    {
        --binding view to my textsview in my items
        //now it's the importat part:
            CheckBox chkBoxBtn = (CheckBox) v.findViewById(R.id.deleteTwittChkBox);
    if (chkBoxBtn != null)
    {
        chkBoxBtn.setId(Integer.valueOf(c.getString(c
                .getColumnIndex(MyUsers.User._ID))));
        chkBoxBtn.setOnClickListener(new OnItemClickListener(chkBoxBtn, v));
        chkBoxBtn.setChecked(false);
    }
    }

    //i couldnt find another way of doing this, but this is how i set listeners to my checkboxses
    static ArrayList<String> checkedItemsList = new ArrayList<String>();

    private class OnItemClickListener implements OnClickListener
    {
        private int mPosition;
        private CheckBox chkBox;
        OnItemClickListener(CheckBox mChkBox, View v)
        {
            chkBox = mChkBox;
            chkBox.setChecked(false);
        }

        @Override
        public void onClick(View v)
        {
            if (chkBox.isChecked())
            {
                checkedItemsList.add(String.valueOf(chkBox.getId()));
            }
            else
            {
                checkedItemsList.remove(String.valueOf(chkBox.getId()));
            }
        }
    }
}

Ecco la parte di codice da ListActivity classe che descrive il pulsante che elimina gli elementi della casella selezionata:

OnClickListener btListener = new OnClickListener()
{
    public void onClick(View view)
    {
        // long[] items = listView.getCheckItemIds();
        int x = 0;
        Uri myUri = Uri
        .parse("content://com.idan.datastorageprovider/users");
        String where = "_id" + "=?";
        //here i am tatking all checkboxes which ive added from the  adapter class
        ArrayList<String> checkedItemsList =   MySimpleCursorAdapter.checkedItemsList;
        for (String itemID : checkedItemsList)
        {
            getContentResolver()
            .delete(myUri, where, new String[] { itemID});
            checkedItemsList.remove(itemID);
        }
    }
};
È stato utile?

Soluzione

Dubito che SimpleCursorAdapter sia la classe giusta da estendere qui.

Lo stato "selezionato" è collegato in qualche modo all'XML dei dati?NO?Quindi hai bisogno del tuo adattatore personalizzato!

Fondamentalmente tutti gli adattatori devono implementare un modo per generare una vista da un dato elemento (più precisamente la posizione di un elemento!).Questo verrà chiamato in qualsiasi momento in cui l'elenco desidera visualizzare un elemento.Ora, il trucco che utilizza è riutilizzare gli elementi della visualizzazione elenco creati in precedenza che non possono più essere visualizzati sullo schermo!Così:quando scorri l'elenco verso il basso e un elemento scompare in alto, ESATTAMENTE questo oggetto di visualizzazione verrà riutilizzato per il successivo elemento visualizzato.

Pertanto, quando questo metodo viene chiamato con una data vista "vecchia" che dovrebbe essere riutilizzata, tutti gli elementi contenuti dovranno essere impostati in base ai dati degli elementi.Se una casella di controllo fa parte di questo gioco, dovrai disporre di uno spazio di archiviazione per lo stato selezionato!Non è sufficiente avere una casella di controllo poiché ci saranno meno oggetti casella di controllo quanti sono gli elementi della lista!

I SimpleCursorAdapter sono lì per - sì - rappresentare cose SEMPLICI.Un XML che descrive i dati (immagini e testo, come afferma la documentazione).A causa di questa semplicità, tutto ciò che devi fare qui è fornire un metodo per creare NUOVI oggetti vista elemento: non stai assolutamente intercettando il processo di riutilizzo!Fondamentalmente sa solo come inserire i dati in un oggetto vista esistente, ma non sa come gestire le caselle selezionate/deselezionate!

La tua soluzione:scrivi la tua estensione BaseAdapter e fai ciò che deve essere fatto:implementare "getView" (e alcuni altri metodi come getItem, getItemId e getCount).Non è affatto difficile!Questo Dimostrazione dell'API utilizza un BaseAdapter e il mExpanded lo stato qui è sostanzialmente identico agli stati della casella di controllo!

Buona fortuna!

Altri suggerimenti

Potrebbe essere necessario chiamare notifyDataSetChanged quando si modificano i dati.

Il problema è probabilmente che si sta chiamando setChecked dall'interno del onItemClickListener. Un modo hacky intorno a questo è di fare quanto segue prima e dopo la chiamata setChecked da dentro il vostro ascoltatore:

chkBox.setClickable(false);
chkBox.setChecked(false);
checkBox.setClickable(true);

In questo modo evitare che l'onItemClickListener da sempre chiamato quando si chiama manualmente setChecked.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top