1
votes

Carte vérifiable à choix unique

J'ai implémenté un CardView vérifiable en suivant https: //medium.com/@AlbinPoignot/checkable-cardview-in-all-android-versions-7124ca6df1ab

Cependant, je dois laisser l'utilisateur sélectionner une seule option. Pour clarifier, si l'un est déjà coché et que l'utilisateur en sélectionne un autre, je dois désélectionner l'option précédente.

De plus, je dois quand retourner le CardView sélectionné conserve l'état coché.

Quelqu'un pourrait-il m'aider avec ces 2 tâches? Voici mon implémentation:

    public class CheckableCardView extends CardView implements Checkable {

        private static final int[] CHECKED_STATE_SET = {
                android.R.attr.state_checked
        };

        private boolean isChecked;
        private TextView itemText;

        public CheckableCardView(Context context) {
            super(context);
            init(null);
        }

        public CheckableCardView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(attrs);
        }

        public CheckableCardView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init(attrs);
        }

        private void init(AttributeSet attrs) {
            LayoutInflater.from(getContext()).inflate(R.layout.checkable_card_view, this, true);

            setClickable(true);
            setChecked(false);

            setCardBackgroundColor(ContextCompat.getColorStateList(getContext(), R.color.selector_card_view_background));

            if (attrs != null) {
                TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.CheckableCardView, 0, 0);
                try {
                    String text = ta.getString(R.styleable.CheckableCardView_card_text);
                    itemText = (TextView) findViewById(R.id.text);

                    if (text != null) {
                        setText(text);
                    }

                } finally {
                    ta.recycle();
                }
            }
        }

        public void setText(String text){
            itemText.setText(text);
        }

        @Override
        protected int[] onCreateDrawableState(int extraSpace) {
            final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
            if (isChecked()) {
                mergeDrawableStates(drawableState, CHECKED_STATE_SET);
            }
            return drawableState;
        }

        @Override
        public boolean performClick() {
            toggle();
            return super.performClick();
        }

        @Override
        public void setChecked(boolean checked) {
            this.isChecked = checked;
        }

        @Override
        public boolean isChecked() {
            return isChecked;
        }

        @Override
        public void toggle() {
            setChecked(!this.isChecked);
        }
    }


0 commentaires

3 Réponses :


4
votes

Vous pouvez également utiliser MaterialCard fournie par le Bibliothèque de composants de matériaux .
Cette carte implémente une interface Checkable par défaut.

Il suffit d'utiliser l'attribut android:checkable dans le xml:

final MaterialCardView cardView = findViewById(R.id.card);
cardView.setOnClickListener(new View.OnClickListener() {
  @Override public void onClick(View view) {
    //cardView.setChecked(!cardView.isChecked());
    cardView.toggle();
  }
});

ou setCheckable (true) dans votre code.

Une façon de passer à l'état vérifié est:

   <com.google.android.material.card.MaterialCardView
        android:checkable="true"
        ..>


2 commentaires

L'attribut vérifiable n'est disponible que dans la dépendance matérielle «1.1.0» et au-dessus. vous devrez ajouter 'implementation com.google.android.material: material: 1.1.0' dans votre Gradle


@DAVIDKATHOH La dernière version stable est actuellement la version 1.1.0.



0
votes

Vous pouvez le faire en déclarant:

 private OnClickListener onClickListener;

@Override
public boolean performClick() {
    toggle();
    onClickListener.onClick(this.isChecked);
    return super.performClick();
}

puis vous pouvez ajouter vos cartes à votre liste dans "onBindViewHolder"

 public void setOnClickListener(OnClickListener onClickListener) { this.onClickListener = onClickListener;}
public interface OnClickListener {
    void onClick(boolean b);
}

enfin vous pouvez ajouter une fonction de rappel comme "onClick"

 holder.cardView.setOnClickListener(new CheckableCardView.OnClickListener() {
        @Override
        public void onClick(boolean b) {
            if (b) {

                for(CheckableCardView checkableCardView : checkableCardViewList) {
                    checkableCardView.setChecked(false);
                }
                checkableCardViewList.get(position).setChecked(true);
                notifyDataSetChanged();
            }
        }
    });

pour le rappel, vous pouvez l'ajouter à votre CheckableCardView en bas

checkableCardViewList.add(position,holder.cardView);

et en haut

private List<CheckableCardView> checkableCardViewList = new ArrayList<>();


0 commentaires

0
votes

Pour ceux qui recherchent une solution simple à ce problème, voici le code:

<com.google.android.material.card.MaterialCardView
        android:id="@+id/cardONE"
        <!-- THIS IS NEEDED -->
        android:checkable="true"
        android:clickable="true"
        android:focusable="true" />

Ou la fonction:

fun setChecked(checkCard: MaterialCardView, uncheckCard: MaterialCardView){
    checkCard.isChecked = true
    uncheckCard.isChecked = false
}

cardONE.setOnClickListener {
    setChecked(it as MaterialCardView, cardTWO)
}

Ce n'est peut-être pas la manière la plus "élégante", mais cela fonctionne comme un charme.

Dépendances nécessaires

implémentation "com.google.android.material: material: 1.2.0"

Fichier XML

    cardONE.setOnClickListener {
        cardONE.isChecked = true // set the current card to checked
        cardTWO.isChecked = false // set the other card to unchecked
    }

    cardTWO.setOnClickListener {
        cardTWO.isChecked = true
        cardONE.isChecked = false
    }


0 commentaires