I\'m trying to make a recyclerview filter based ChipGroup & Chip
I\'m use fragment on my app, so, the fragment who contain the RecyclerView contain a fr
It works like this way.
// com.google.android.material.chip.ChipGroup
app:singleSelection="true"
// com.google.android.material.chip.Chip (R.layout.chip)
style="@style/Widget.MaterialComponents.Chip.Choice"
// Inflate instead of NEW instance
val chip = layoutInflater.inflate(R.layout.chip, chipGroup, false) as Chip
chip.text = "Text"
chipGroup.addView(chip)
// setOnCheckedChangeListener
chipGroup.setOnCheckedChangeListener { group, checkedId ->
// The same checked chip
if (checkedId == -1) {
return@setOnCheckedChangeListener
}
// TODO
}
All chips need to have the android:checkable="true"
property for the trigger to exist on them.
In adittion to setting the initial check of any chip (without giving a tap), the order of execution must be first the creation of the listener with chipGroup.setOnCheckedChangeListener()
and then chip.isChecked = true
.
So you could handle the checkable property from the xml and isChecked dynamically.
<com.google.android.material.chip.ChipGroup
..
app:singleSelection="true">
<com.google.android.material.chip.Chip
..
android:checkable="true"/>
binding.chipGroup.setOnCheckedChangeListener { chipGroup, i ->
}
binding.firstChip.isChecked = true //default
GL
Chip Click listener will only work if the single selection was set to true in chipGroup.
app:singleSelection="true"
If you're using the style like below, then make sure it was also given to every individual chip as well.
style="@style/Widget.MaterialComponents.Chip.Choice"
like this:
<com.google.android.material.chip.ChipGroup
android:id="@+id/chip_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
app:singleSelection="true"
style="@style/Widget.MaterialComponents.Chip.Choice">
<com.google.android.material.chip.Chip
android:id="@+id/chip_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Widget.MaterialComponents.Chip.Choice"
android:text="@string/announcements"
android:textAppearance="@style/ChipThemeBold"/>
<com.google.android.material.chip.Chip
android:id="@+id/chip_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Widget.MaterialComponents.Chip.Choice"
android:text="@string/fyi"
android:textAppearance="@style/ChipThemeBold"/>
<com.google.android.material.chip.Chip
android:id="@+id/chip_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Widget.MaterialComponents.Chip.Choice"
android:text="@string/heartbeat"
android:textAppearance="@style/ChipThemeBold" />
<com.google.android.material.chip.Chip
android:id="@+id/chip_5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Widget.MaterialComponents.Chip.Choice"
android:text="@string/pitch"
android:textAppearance="@style/ChipThemeBold" />
<com.google.android.material.chip.Chip
android:id="@+id/chip_6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Widget.MaterialComponents.Chip.Choice"
android:text="@string/question"
android:textAppearance="@style/ChipThemeBold"
android:layout_marginEnd="15dp" />
</com.google.android.material.chip.ChipGroup>
Your code is fine the only issue is that setOnCheckedChangeListener()
only work when your ChipGroup
is for singleSelection
Read this documentation of ChipGroup
setOnCheckedChangeListener()
ALSO READ
Handling Checked Chips
Call setOnCheckedChangeListener(OnCheckedChangeListener) to register a callback to be invoked when the checked chip changes in this group. This callback is only invoked in single selection mode.
if you want use setOnCheckedChangeListener()
of ChipGroup
than you need to make app:singleSelection="true"
based on your below comment i have added sample code to manage to handle when ChipGroup selection
SAMPLE CODE for maintain selection in ChipGroup
Layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.chip.ChipGroup
android:id="@+id/chipGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
>
</com.google.android.material.chip.ChipGroup>
</androidx.constraintlayout.widget.ConstraintLayout>
<Button
android:layout_width="match_parent"
android:text="Get Result"
android:id="@+id/btnShowResult"
android:layout_gravity="bottom"
android:layout_height="wrap_content" />
</LinearLayout>
Activity code
public class Main3Activity extends AppCompatActivity {
public ChipGroup chipGroup;
public Button btnShowResult;
public ArrayList<Boolean> booleanArrayList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
chipGroup = findViewById(R.id.chipGroup);
btnShowResult = findViewById(R.id.btnShowResult);
btnShowResult.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
for (int i = 0; i < booleanArrayList.size(); i++) {
Log.e("RESULT", i + " :" + booleanArrayList.get(i));
}
}
});
for (int i = 0; i < 5; i++) {
Chip chip = new Chip(this);
chip.setId(i);
chip.setTag(i);
booleanArrayList.add(false);
chip.setText("Chip No : " + i);
chip.setCheckable(true);
chip.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
int tag = (int) compoundButton.getTag();
booleanArrayList.set(tag, b);
}
});
chipGroup.addView(chip);
}
chipGroup.invalidate();
chipGroup.setOnCheckedChangeListener(new ChipGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(ChipGroup chipGroup, int i) {
Chip chip = chipGroup.findViewById(i);
if (chip != null)
Toast.makeText(getApplicationContext(), "Chip is " + chip.getText().toString(), Toast.LENGTH_SHORT).show();
Log.e("OnCheckedChangeListener", "Called");
}
});
}
ChipGroup.OnCheckedChangeListener onCheckedChangeListener = new ChipGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(ChipGroup chipGroup, int i) {
}
};
}
For more information please check below articles
i have same issue, but it's not relate to ChipGroup
because i put the ChipGroup
in wrong place like this:
<androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.chip.ChipGroup />
<other full screen view />
<androidx.constraintlayout.widget.ConstraintLayout/>
it makes my ChipGroup
unfocusable, so just move the ChipGroup
to the bottom of parent view
<androidx.constraintlayout.widget.ConstraintLayout>
<other full screen view />
<-- change here -->
<com.google.android.material.chip.ChipGroup />
<androidx.constraintlayout.widget.ConstraintLayout/>
and it works, hope it helps
I will suggest don't make use of recyclerview with chips if you want horizontal scrolling because you got
HorizontalScrollView
and it works quite well with chipgroup:
Based on Nilesh Rathod's Answer. To add chips dynamically you need following code:
Activity File Code:
String[] fileNameChip = getIntent().getStringArrayExtra(Constants.CHIPS_NAME_ARRAY);
for (final String chipName : fileNameChip) {
LayoutInflater layoutInflater = getLayoutInflater();
Chip chip = (Chip)
layoutInflater.inflate(R.layout.cat_chip_group_item_choice, chipGroup, false);
chip.setText(chipName);
chip.setId(i); //HERE SET ID THAT WILL BE CHECKED_ID ON setOnCheckedChangeListener
chip.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "onClick: " + chipName );
}
});
chipGroup.addView(chip);
}
chipGroup.setOnCheckedChangeListener(new ChipGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(ChipGroup group, int checkedId) {
Log.d(TAG, "onCheckedChanged: " + checkedId);
}
});
Activity XML FILE:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<HorizontalScrollView
android:layout_width="match_parent"
android:scrollbars="none"
android:layout_height="wrap_content">
<com.google.android.material.chip.ChipGroup
android:id="@+id/chip_group_code_files"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:singleLine="true"
app:singleSelection="true" />
</HorizontalScrollView>
cat_chip_group_item_choice.xml:(Specify chip type:Choice,filter,Action,Normal)
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.chip.Chip
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/Widget.MaterialComponents.Chip.Choice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>