I want to know how can I apply stroke color to card view onClick and also deselect it when clicked again
Also, I have multiple card views, so if one is already selected and the stroke color is applied but if the user clicks another card view the stroke color disappeared from the first and is applied to the respected card view
How can I achieve this?
Right now I have applied a stroke color to one card view
Just as a note further, I want to get the selected CardView
id or the amount when the donate button is clicked and pass the card view (amount) to the payment gateway.
This is how it looks like:
donate_fragment.xml // only the card view section and the button
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="50dp"
android:text="@string/select_an_amount"
android:textColor="@color/white"
android:textSize="25sp"
android:textStyle="bold|normal" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="30dp"
android:orientation="horizontal">
<com.google.android.material.card.MaterialCardView
android:layout_width="100dp"
android:layout_height="80dp"
app:strokeColor="@color/wallet_holo_blue_light"
app:strokeWidth="3dp"
android:layout_marginEnd="10dp"
android:backgroundTint="@color/Card_Elevation_Color"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="10dp"
app:cardElevation="2dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/_0_5"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold|normal" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:layout_width="100dp"
android:layout_height="80dp"
android:layout_marginEnd="10dp"
android:backgroundTint="@color/Card_Elevation_Color"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="10dp"
app:cardElevation="2dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/_1"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold|normal" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:layout_width="100dp"
android:layout_height="80dp"
android:backgroundTint="@color/Card_Elevation_Color"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="10dp"
app:cardElevation="2dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/_5"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold|normal" />
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<com.google.android.material.card.MaterialCardView
android:layout_width="100dp"
android:layout_height="80dp"
android:layout_marginEnd="10dp"
android:backgroundTint="@color/Card_Elevation_Color"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="10dp"
app:cardElevation="2dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/_10"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold|normal" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:layout_width="100dp"
android:layout_height="80dp"
android:layout_marginEnd="10dp"
android:backgroundTint="@color/Card_Elevation_Color"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="10dp"
app:cardElevation="2dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/_50"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold|normal" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:layout_width="100dp"
android:layout_height="80dp"
android:backgroundTint="@color/Card_Elevation_Color"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="10dp"
app:cardElevation="2dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/_100"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold|normal" />
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
<com.google.android.material.button.MaterialButton
android:id="@ id/donateBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="45dp"
android:layout_marginTop="30dp"
android:layout_marginEnd="45dp"
android:text="@string/donate"
android:textAlignment="center"
android:textSize="17sp"
app:cornerRadius="10dp" />
Updated Code
public class Donate extends Fragment {
LinearLayout linearLayout1, linearLayout2;
MaterialCardView cardView1, cardView2, cardView3, cardView4, cardView5, cardView6;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.donate_fragment, container, false);
//LinearLayout
linearLayout1 = view.findViewById(R.id.linearLayout1);
linearLayout2 = view.findViewById(R.id.linearLayout2);
//CardView
cardView1 = view.findViewById(R.id.cardView1);
cardView2 = view.findViewById(R.id.cardView2);
cardView3 = view.findViewById(R.id.cardView3);
cardView4 = view.findViewById(R.id.cardView4);
cardView5 = view.findViewById(R.id.cardView5);
cardView6 = view.findViewById(R.id.cardView6);
View.OnClickListener listener1 = view1 -> {
if (view1 instanceof MaterialCardView) {
MaterialCardView card = (MaterialCardView) view1;
boolean isChecked = card.isChecked();
clearCardSelection(linearLayout1);
clearCardSelection(linearLayout2);
card.setChecked(!isChecked);
}
};
View.OnClickListener listener2 = view2 -> {
if (view2 instanceof MaterialCardView) {
MaterialCardView card = (MaterialCardView) view2;
boolean isChecked = card.isChecked();
clearCardSelection(linearLayout1);
clearCardSelection(linearLayout2);
card.setChecked(!isChecked);
}
};
View.OnClickListener listener3 = view3 -> {
if (view3 instanceof MaterialCardView) {
MaterialCardView card = (MaterialCardView) view3;
boolean isChecked = card.isChecked();
clearCardSelection(linearLayout1);
clearCardSelection(linearLayout2);
card.setChecked(!isChecked);
}
};
View.OnClickListener listener4 = view4 -> {
if (view4 instanceof MaterialCardView) {
MaterialCardView card = (MaterialCardView) view4;
boolean isChecked = card.isChecked();
clearCardSelection(linearLayout1);
clearCardSelection(linearLayout2);
card.setChecked(!isChecked);
}
};
View.OnClickListener listener5 = view5 -> {
if (view5 instanceof MaterialCardView) {
MaterialCardView card = (MaterialCardView) view5;
boolean isChecked = card.isChecked();
clearCardSelection(linearLayout1);
clearCardSelection(linearLayout2);
card.setChecked(!isChecked);
}
};
View.OnClickListener listener6 = view6 -> {
if (view6 instanceof MaterialCardView) {
MaterialCardView card = (MaterialCardView) view6;
boolean isChecked = card.isChecked();
clearCardSelection(linearLayout1);
clearCardSelection(linearLayout2);
card.setChecked(!isChecked);
}
};
cardView1.setOnClickListener(listener1);
cardView2.setOnClickListener(listener2);
cardView3.setOnClickListener(listener3);
cardView4.setOnClickListener(listener4);
cardView5.setOnClickListener(listener5);
cardView6.setOnClickListener(listener6);
return view;
}
private void clearCardSelection(LinearLayout layout) {
for (int i = 0; i < layout.getChildCount(); i ) {
View child = layout.getChildAt(i);
if (child instanceof MaterialCardView)
((MaterialCardView) child).setChecked(false);
}
}
}
CodePudding user response:
You can use a selector for the stroke color to change for the state_checked
:
selector.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#36B3E0" android:state_checked="true" />
<item android:color="@android:color/transparent" android:state_checked="false" />
</selector>
Apply that to the CardView
:
app:checkedIcon="@null"
app:strokeColor="@drawable/selector"
android:checkable="true"
checkedIcon
is set to have not tick icon for the checked card.
Then change the check status in OnClickListener
But precede that by clearing all the checked cards using their surrounding ViewGroup
, here's an extension function for that:
fun ViewGroup.clearCardSelection() {
this.children.forEach {
if (it is MaterialCardView)
it.isChecked = false
}
}
And the listener:
val listener = View.OnClickListener {
if (it is MaterialCardView) {
val isChecked = it.isChecked
linearlayout1.clearCardSelection() // top LinearLayout
linearlayout2.clearCardSelection() // bottom LinearLayout
it.isChecked = !isChecked
}
}
cardView.setOnClickListener(listener) // repeat this for the 6 cards
And this is the result:
Make sure to save the checked card state permanently to avoid losing it during configuration changes.
UPDATE
Here is the java equivalent:
private void clearCardSelection(LinearLayout layout) {
for (int i = 0; i < layout.getChildCount(); i ) {
View child = layout.getChildAt(i);
if (child instanceof MaterialCardView)
((MaterialCardView) child).setChecked(false);
}
}
View.OnClickListener listener = view -> {
if (view instanceof MaterialCardView) {
MaterialCardView card = (MaterialCardView) view;
boolean isChecked = card.isChecked();
clearCardSelection(linearlayout1);
clearCardSelection(linearlayout2);
card.setChecked(!isChecked);
}
};
cardView.setOnClickListener(listener); // repeat for all the cards
When I tested that in java; I got NPE on the MaterialCaredView
layout, that was because of setting app:checkedIcon="@null"
to null, to fix this, replace app:checkedIcon="@null"
with app:checkedIcon="@android:color/transparent"