6

I use chipgroup with dynamic chips. I want the chips to get wrapped in width according to their text. But it takes extra spaces even without padding.

Below is my code:

xml:

<com.google.android.material.chip.ChipGroup
    android:id="@+id/cg"
    android:layout_width="0dp"
    android:layout_weight="75"
    android:layout_height="wrap_content"
    android:layout_marginTop="20dp"
    android:layout_marginBottom="5dp"
    android:textColor="@android:color/black"
    android:textStyle="bold"
    android:textSize="12sp"
    app:singleSelection="false"
    app:chipSpacingVertical="5dp"
    app:chipSpacingHorizontal="5dp"
    app:singleLine="false"
    app:chipSpacing="2dp">

This is how to add chips dynamically:

for(int i=0;i<cartoonTypes.length;i++){
    chip = new Chip(this);
    chip.setText(cartoonTypes[i].trim());
    chip.setTextColor(Color.WHITE);
    chip.setChipBackgroundColor(getResources().getColorStateList(R.color.colorChip));
    chip.setTextSize(12);
    chip.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL);
    chip.setPadding(0,0,0,0);
    cgMovieGenre.addView(chip);
    ChipGroup.LayoutParams layoutParams = (ChipGroup.LayoutParams) chip.getLayoutParams();;
    int dpSize = px2dp(12);;
    layoutParams.height = dpSize;
    layoutParams.width = ChipGroup.LayoutParams.WRAP_CONTENT;
    chip.setLayoutParams(layoutParams);
}

method px2dp does this:

int px2dp(int px){
    metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);
    int h = (px * metrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT;
    return h;
}

My build.gradle has the following dependencies:

implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.0-beta01'
implementation 'androidx.cardview:cardview:1.0.0-beta01'
implementation 'com.google.android.material:material:1.0.0-beta01'

This is what I see:

screenshot, chip-group

I want the chip to use as minimal width as possible according to its text.

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
adi
  • 984
  • 15
  • 33

8 Answers8

7

You should set padding for chip in right way, try this:

chip.setChipStartPadding(0);
chip.setChipEndPadding(0);
JiajiaGu
  • 1,279
  • 14
  • 10
  • 1
    It reduces the space, but still has some space left and my gravity attribute is not working.It has some space on top even after trying many gravity attributes! – adi May 23 '19 at 03:26
  • I increased my chip height, and the gravity is fine now, but there is some more space present on the left and right..any inputs on them !! – adi May 23 '19 at 03:31
  • Add setTextStartPadding(0) and setTextEndPadding(0) to see if it would better meet your needs. – JiajiaGu May 23 '19 at 03:37
  • thanks, but there is an extra space only on the right now for some texts inspite of trimming the strings! – adi May 23 '19 at 03:55
  • if u dont mind could u have a look at this post on Sajith's answer:https://stackoverflow.com/questions/56244817/androidunable-to-make-multiline-chipgroup/56245456?noredirect=1#comment99143166_56245456 – adi May 23 '19 at 03:57
  • It is not totally correct. The issue is not this padding. Check my [answer](https://stackoverflow.com/a/58246871/2016562): you can check how the padding works inside a chip. – Gabriele Mariotti Oct 05 '19 at 09:08
4

Just remove in your code this line

//chip.setPadding(0,0,0,0);

The result with and without the padding:

enter image description here
enter image description here

Just to understand the padding inside the Chip:

 * <pre>
 *   chipStartPadding     iconEndPadding     closeIconStartPadding         chipEndPadding
 *    +                    +                                    +                      +
 *    |                    |                                    |                      |
 *    |  iconStartPadding  |  textStartPadding   textEndPadding | closeIconEndPadding  |
 *    |   +                |    +                            +  |                  +   |
 *    |   |                |    |                            |  |                  |   |
 *    v   v                v    v                            v  v                  v   v
 * +-----+----+-----------+----+----+---------------------+----+----+----------+----+-----+
 * |     |    |       XX  |    |    |  XX   X  X  X  XXX  |    |    | X      X |    |     |
 * |     |    |      XX   |    |    | X  X  X  X  X  X  X |    |    |  XX  XX  |    |     |
 * |     |    |  XX XX    |    |    | X     XXXX  X  XXX  |    |    |    XX    |    |     |
 * |     |    |   XXX     |    |    | X  X  X  X  X  X    |    |    |  XX  XX  |    |     |
 * |     |    |    X      |    |    |  XX   X  X  X  X    |    |    | X      X |    |     |
 * +-----+----+-----------+----+----+---------------------+----+----+----------+----+-----+
 *                  ^                           ^                         ^
 *                  |                           |                         |
 *                  +                           +                         +
 *             chipIconSize                  *dynamic*              closeIconSize
 * </pre>

Also some notes:

  • The chip.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL); doesn't work because chip text must be vertically center and start aligned.
    Chip uses a built-in setGravity(Gravity.CENTER_VERTICAL | Gravity.START);

  • Instead of chip.setChipBackgroundColor(getResources().getColorStateList(R.color.colorChip)); use the method chip.setChipBackgroundColorResource(R.color.colorChip)

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
3

For chips, it's not (inner) "padding", but (outer) "spacing":

  • app:chipSpacing  —  Adds spacing to both the horizontal and vertical axis.
  • app:chipSpacingHorizontal  —  Adds spacing to the horizontal axis.
  • app:chipSpacingVertical  —  Adds spacing to the vertical axis.

the least spacing with line-wrapping would be:

app:singleLine="false"
app:chipSpacing="0dp"

alternatively, wrap the ChipGroup in a HorizontalScrollView with app:singleLine="true".

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
3

Probably just removing chip.setTextSize() may help you get rid of the space on the right (however, I'm still wondering how to change the font size). If not, this is the solution I use in my project:

  1. Define a style for your chips:
    <style name="ListChip" parent="Widget.MaterialComponents.Chip.Entry" >
        <style name="ListChip" parent="Widget.MaterialComponents.Chip.Entry" >
        <item name="rippleColor">@null</item>
        <item name="closeIcon">@null</item>
        <item name="chipBackgroundColor">?attr/background_highlight_color</item>
        <item name="android:checkable">false</item>
        <item name="android:textSize">8sp</item> //This has not effect
        <item name="android:textColor">?attr/text_color</item>
    </style>
  1. Create a layout resource file with the root element com.google.android.material.chip.Chip and apply the newly created style:
    <?xml version="1.0" encoding="utf-8"?>
     <com.google.android.material.chip.Chip
        style="@style/ListChip"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:ellipsize="end">
     </com.google.android.material.chip.Chip>
  1. In the code, create your chips not by using Chip chip = new Chip(this); but by inflating the newly created chip layout:
    Chip chip = (Chip) LayoutInflater.from(chipGroup.getContext()).inflate(R.layout.chip_in_list, chipGroup, false);
  1. Do not call chip.setTextSize() on the newly created chip.
Oleh Romanenko
  • 289
  • 1
  • 11
1

I was creating chips programmatically so i had to do this in kotlin:

chip.minimumWidth = 0
chip.setEnsureMinTouchTargetSize(false)
Zohab Ali
  • 8,426
  • 4
  • 55
  • 63
0

that extra space is of close icon , just set this

val chip = Chip(this)
chip.closeIcon = null
Rishabh Shukla
  • 461
  • 6
  • 19
0

In the new <com.google.android.material.chip.Chip there is an attribute called app:chipMinTouchTargetSize.This will get rid of the extra spaces

app:chipMinHeight="20dp"
app:chipMinTouchTargetSize="22dp"
Narendra_Nath
  • 4,578
  • 3
  • 13
  • 31
-1

first thing first, create you attr (values/attrs.xml):

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="ChipView">
        <attr name="CustomChipStyle" format="reference"/>
    </declare-styleable>
</resources>

after that add to your theme set your R.attr.CustomChipChoiceStyle to your theme (values/styles.xml) example:

<style name="APPTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
    <item name="colorPrimary">@color/primaryColor</item>
    <item name="colorPrimaryDark">@color/primaryColor</item>
    <item name="colorAccent">@color/secondaryColor</item>
    <item name="CustomChipChoiceStyle">@style/ChipTextAppearance</item>
</style>

    <style name="ChipTextAppearance" parent="@style/Widget.MaterialComponents.Chip.Choice">
        <item name="android:minWidth">130dp</item>
        <item name="chipMinHeight">50dp</item>
<item name="android:textAlignment">center</item>
    </style>

if you have a chipGroup like this:

    <com.google.android.material.chip.ChipGroup
        android:id="@+id/chipGroup"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:singleSelection="true"/>

you can add from code something like that:

val list = listOf("credit", "cash")
list.forEach{
            val chip = Chip(context, null, R.attr.CustomChipStyle).apply {
                text = it
            }
            chipGroup.addView(chip)
        }

and that's it.

enter image description here

Alex Zaraos
  • 6,443
  • 2
  • 26
  • 21