【问题标题】:android chips taking extra spaces;unable to wrap安卓芯片占用额外空间;无法换行
【发布时间】:2019-10-09 12:31:58
【问题描述】:

我使用带有动态芯片的芯片组。我希望芯片根据它们的文字被包裹在宽度中。但即使没有填充,它也会占用额外的空间。

下面是我的代码:

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">

这是动态添加筹码的方法:

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);
}

方法 px2dp 这样做:

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

我的build.gradle 有以下依赖项:

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'

这是我看到的:

我希望芯片根据其文本使用尽可能小的宽度。

【问题讨论】:

    标签: android android-layout material-components-android material-components android-chips


    【解决方案1】:

    您应该以正确的方式为芯片设置填充,试试这个:

    chip.setChipStartPadding(0);
    chip.setChipEndPadding(0);
    

    【讨论】:

    • 它减少了空间,但仍然有一些空间,我的重力属性不起作用。即使在尝试了许多重力属性后,它的顶部还有一些空间!
    • 我增加了我的芯片高度,现在重力很好,但是左右两侧还有一些空间......任何输入!
    • 添加 setTextStartPadding(0) 和 setTextEndPadding(0) 看看是否能更好地满足您的需求。
    • 谢谢,但现在只有在右边有一个额外的空间用于一些文本,尽管修剪了字符串!
    • 如果你不介意可以看看 Sajith 的这个帖子:stackoverflow.com/questions/56244817/…
    【解决方案2】:

    对于芯片,它不是(内部)“填充”,而是(外部)“间距”:

    • app:chipSpacing  —  向水平轴和垂直轴添加间距。
    • app:chipSpacingHorizontal  —  在水平轴上添加间距。
    • app:chipSpacingVertical  —  在垂直轴上添加间距。

    换行的最小间距是:

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

    或者,使用app:singleLine="true"ChipGroup 包装在HorizontalScrollView 中。

    【讨论】:

      【解决方案3】:

      可能只是删除 chip.setTextSize() 可能会帮助您摆脱右侧的空间(但是,我仍然想知道如何更改字体大小)。 如果没有,这是我在项目中使用的解决方案:

      1. 为您的筹码定义样式:
          <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. 使用根元素com.google.android.material.chip.Chip创建一个布局资源文件并应用新创建的样式:
          <?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. 在代码中,创建您的芯片不是使用 Chip chip = new Chip(this);,而是通过扩展新创建的芯片布局:
          Chip chip = (Chip) LayoutInflater.from(chipGroup.getContext()).inflate(R.layout.chip_in_list, chipGroup, false);
      
      1. 不要在新创建的芯片上调用 chip.setTextSize()

      【讨论】:

        【解决方案4】:

        只需在您的代码中删除这一行

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

        有和没有填充的结果:


        只是为了了解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>
        

        还有一些注意事项:

        • chip.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL); 不起作用,因为芯片文本必须垂直居中并开始对齐
          芯片使用内置setGravity(Gravity.CENTER_VERTICAL | Gravity.START);

        • 使用chip.setChipBackgroundColorResource(R.color.colorChip)方法代替chip.setChipBackgroundColor(getResources().getColorStateList(R.color.colorChip));

        【讨论】:

        • 如何去掉垂直内边距?
        【解决方案5】:

        首先,创建你的 attr (values/attrs.xml):

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

        然后添加到您的主题 将您的 R.attr.CustomChipChoiceStyle 设置为您的主题 (values/styles.xml) 示例:

        <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>
        

        如果你有这样的芯片组:

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

        您可以从代码中添加类似的内容:

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

        就是这样。

        【讨论】:

          【解决方案6】:

          我正在以编程方式创建芯片,所以我必须在 kotlin 中执行此操作:

          chip.minimumWidth = 0
          chip.setEnsureMinTouchTargetSize(false)
          

          【讨论】:

            猜你喜欢
            • 2012-01-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-06-11
            • 2020-06-12
            • 1970-01-01
            • 1970-01-01
            • 2020-06-04
            相关资源
            最近更新 更多