Search code examples
androidcheckedtextview

AlertDialog - CheckedTextView doesn't work


I have a custum list displayed on an AlertDialog.I want that whan I click on an item, the CheckedTextView is set checked. I tried for hours, but not setChecked() seems doesn't work...

Could anyone help me ?

final List<Producteur> p = DAOProducteur.getInstance(null).recherche(producteur);

AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle("Résultat(s) :");
builder.setSingleChoiceItems(
        new ArrayAdapter<Producteur>(
                activity, 
                R.layout.activity_recherche_producteurs, 
                p) {
                    @Override
                    public View getView(int position, View convertView, ViewGroup parent) {
                        LayoutInflater inflater = (LayoutInflater) parent.getContext()
                            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

                        View rowView = inflater.inflate(R.layout.activity_recherche_producteurs, parent, false);

                        // Chargement des éléments à partir du layout
                        TextView numProd        = (TextView) rowView.findViewById(R.id.num_prod);
                        TextView numLaiterie    = (TextView) rowView.findViewById(R.id.num_laiterie);
                        TextView numLabo        = (TextView) rowView.findViewById(R.id.num_labo);
                        TextView raisonSociale  = (TextView) rowView.findViewById(R.id.raison_sociale);
                        TextView adresse        = (TextView) rowView.findViewById(R.id.adresse);
                        final CheckedTextView checkBox = (CheckedTextView) rowView.findViewById(R.id.check_box);

                        // Mise en place des textes sur les éléments
                        numProd.setText("n° " + String.valueOf(p.get(position).getNumProd()));
                        numLaiterie.setText(", " + String.valueOf(p.get(position).getNumLaiterie()));
                        String nLabo = String.valueOf(p.get(position).getNumLabo());
                        nLabo = nLabo.substring(0, nLabo.length() - 1) + " " + nLabo.substring(nLabo.length() - 1, nLabo.length());
                        numLabo.setText(nLabo);
                        raisonSociale.setText(String.valueOf(p.get(position).getRaisonSociale()));
                        adresse.setText(String.valueOf(p.get(position).getAdresse()));
                        checkBoxList.put(position, checkBox);

                        return rowView;
                    }
                }, 
        -1, 
        new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int position) {
                producteurChoisi = p.get(position);
                checkBoxList.get(dernierCheck).setChecked(false);
                checkBoxList.get(position).setChecked(true);
                dernierCheck = position;
            }
        });
builder.setPositiveButton(R.string.valider, new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int position) {
                dialog.cancel();

                if(producteurChoisi != null) {
                    // Ajout du producteur dans la tournée modèle
                    DAOTourneeModele.getInstance(activity).nouveauProducteur(
                            date, 
                            tournee, 
                            tour, 
                            producteurChoisi.getNumProd());

                    // Ouverture du litrage correspondant au nouveau producteur
                    Intent i = new Intent(activity.getApplicationContext(), SaisieActivity.class);
                    i.putExtra("date", date);
                    i.putExtra("tournee", String.valueOf(tournee));
                    i.putExtra("tour", tour);
                    i.putExtra("producteur", String.valueOf(producteurChoisi.getNumProd()));
                    activity.startActivity(i);
                } else {
                    Toast.makeText(activity, getString(R.string.erreur_producteur_non_choisi), Toast.LENGTH_LONG).show();
                }
            }
        });
builder.setNegativeButton(R.string.quitter, new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
                new AjouteProdDialog().show(activity.getFragmentManager(), "dialog");
            }
        });
AlertDialog alert = builder.create();
alert.show();

SparseArray<CheckedTextView> checkBoxList = new SparseArray<CheckedTextView>(); and int dernierCheck = 0; are declared before.

And my xml file :

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >

    <TextView
        android:id="@+id/num_prod"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/etat"
        android:text="n° 477009"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/num_laiterie"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/etat"
        android:layout_toRightOf="@+id/num_prod"
        android:text=", 131" />

    <TextView
        android:id="@+id/num_labo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/etat"
        android:layout_centerHorizontal="true"
        android:layout_toRightOf="@+id/num_laiterie"
        android:text="477009 5" />

    <TextView
        android:id="@+id/raison_sociale"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/num_prod"
        android:layout_alignParentLeft="true"
        android:text="GAEC DE ST AIGNAN" />

    <TextView
        android:id="@+id/adresse"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/raison_sociale"
        android:layout_alignParentLeft="true"
        android:text="KERAIGNAN" />

    <CheckedTextView
        android:id="@+id/check_box"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:checkMark="?android:attr/listChoiceIndicatorSingle" />

</RelativeLayout>

Solution

  • Firstly

    I can not see a call for notifydatasetChange() that will refresh the ListView. So in onClick() after changing backing datasource, you should refresh the adapter too.

    Alternative

    In getView() you can set onClickListener for checkBox and for every onClick() callback you should update backing datasource and call `toggle() on checkbox to toggle the state.

    Code

    Model class class Model {

    public Model(String data, boolean state) {
        this.data = data;
        this.state = state;
    }
    
    String data;
    Boolean state;
        // getter and setters 
       }
    

    Custom Adapter

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = inflater.inflate(R.layout.single_row, null, false);
        TextView tv = (TextView) view.findViewById(R.id.content);
        CheckedTextView ctv = (CheckedTextView) view.findViewById(R.id.checker);
        Model m = backingsource.get(position);
        tv.setText(m.getData());
        ctv.setChecked(m.getState());
        return view;
    }
    

    Activity

    public class MainActivity extends Activity implements OnClickListener {
        CustomAdapter mAdapter = null;
        List<Model> mDataSource = null;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mDataSource = new ArrayList<Model>();
            mDataSource.add(new Model("Tom", false));
            mDataSource.add(new Model("Goffy", false));
            mDataSource.add(new Model("Ron", false));
            mDataSource.add(new Model("Pit", false));
            mDataSource.add(new Model("Dwyane", false));
            mDataSource.add(new Model("John", false));
            mDataSource.add(new Model("Son", false));
    
            mAdapter = new CustomAdapter(this, mDataSource);
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setSingleChoiceItems(mAdapter, -1, this);
            builder.setTitle("Customized");
            builder.create().show();
        }
    
        @Override
        public void onClick(DialogInterface dialog, int which) {
            Log.d("@gaurav", "which " + which);
            Model m = mDataSource.get(which);
            boolean b = m.getState();
            b = !b;
            m.setState(b);
            mAdapter.notifyDataSetChanged();
        }
          }
    

    single_row.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" >
    
        <TextView
            android:id="@+id/content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Some text" >
        </TextView>
    
        <CheckedTextView
            android:id="@+id/checker"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checkMark="?android:attr/listChoiceIndicatorSingle" />
    
    </LinearLayout>