首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从材料组件库中添加芯片到android中的输入字段?

如何从材料组件库中添加芯片到android中的输入字段?
EN

Stack Overflow用户
提问于 2018-05-29 00:54:02
回答 7查看 27.9K关注 0票数 26

我已经看到,在android中,google添加了新的材料组件库,其中包含了材料芯片:

android的材料组件

Material.io芯片使用

GitHub上的材料部件

因此,我决定在我的项目中添加材料输入芯片,但不幸的是,我没有找到任何教程如何制作该芯片。我想创造一些类似Gmail芯片,但没有图像在一开始。

因为我正在使用appcompat库,所以我尝试使用android.support.design.chip.Chipandroid.support.design.chip.ChipGroup的材料芯片。但结果只是芯片没有任何输入字段。另外,我尝试创建一个独立的ChipDrawable,然后使用以下方法将其添加到EditText

代码语言:javascript
复制
Editable text = editText.getText();

text.setSpan(span, 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

但是我没有任何芯片的EditText是空的。那么,如何使用这个材料组件库创建像Gmail中那样的芯片输入呢?也许有人有经验,或者知道有什么教程,我可以看到如何创建这个?

提前感谢!

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2018-07-31 10:15:46

答案

没有在android中添加芯片的默认输入字段。他们提到了输入芯片,但我没有找到输入芯片的任何布局或视图组。所以我用Chipdrawable方法在编辑文本中添加芯片。这里使用的是AppCompatEdittext,您可以更改为任何监听文本输入的视图。参考文献

步骤1

添加芯片xml资源。chip.xml

res -> xml -> chip.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<chip xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 android:textAppearance="@style/ChipTextAppearance"
 app:chipBackgroundColor="@color/colorAccent"
 app:chipIcon="@drawable/ic_call_white_24dp"
 app:closeIconEnabled="true"  <!--property for close icon if no need set to false. -->
 app:closeIconTint="@android:color/white" />

然后在style.xml中添加文本外观样式(用于更改textStyle)

代码语言:javascript
复制
<style name="ChipTextAppearance" parent="TextAppearance.MaterialComponents.Chip">
    <item name="android:textColor">@android:color/white</item>
</style>

步骤2

使用AppCompatEdittext添加您在这里的视图

代码语言:javascript
复制
  <android.support.v7.widget.AppCompatEditText
    android:id="@+id/phone"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginEnd="8dp"
    android:layout_marginLeft="8dp"
    android:layout_marginRight="8dp"
    android:layout_marginStart="8dp"
    android:layout_marginTop="8dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/tvt_Contact" />

步骤3

将此代码添加到视图中,以获得所需的行为。

代码语言:javascript
复制
 private int SpannedLength = 0,chipLength = 4;

 AppCompatEditText Phone = findViewById(R.id.phone);

 Phone.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            if (charSequence.length() == SpannedLength - chipLength)
            {
                SpannedLength = charSequence.length();
            }
        }

        @Override
        public void afterTextChanged(Editable editable) {

            if(editable.length() - SpannedLength == chipLength) {
                ChipDrawable chip = ChipDrawable.createFromResource(getContext(), R.xml.chip);
                chip.setChipText(editable.subSequence(SpannedLength,editable.length()));
                chip.setBounds(0, 0, chip.getIntrinsicWidth(), chip.getIntrinsicHeight());
                ImageSpan span = new ImageSpan(chip);
                editable.setSpan(span, SpannedLength, editable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                SpannedLength = editable.length();
            }

        }
    });

当需要在编辑文本中添加新的芯片时,会根据需要更改chipLength。

输出

编辑的

您可以找到更多关于如何用span 这里对齐文本中心的信息。

在这里,我为您添加了一些解决方案中的代码。

代码语言:javascript
复制
public class VerticalImageSpan extends ImageSpan {

public VerticalImageSpan(Drawable drawable) {
    super(drawable);
}

@Override
public int getSize(@NonNull Paint paint, CharSequence text, int start, int end,
                   Paint.FontMetricsInt fontMetricsInt) {
    Drawable drawable = getDrawable();
    Rect rect = drawable.getBounds();
    if (fontMetricsInt != null) {
        Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();
        int fontHeight = fmPaint.descent - fmPaint.ascent;
        int drHeight = rect.bottom - rect.top;
        int centerY = fmPaint.ascent + fontHeight / 2;

        fontMetricsInt.ascent = centerY - drHeight / 2;
        fontMetricsInt.top = fontMetricsInt.ascent;
        fontMetricsInt.bottom = centerY + drHeight / 2;
        fontMetricsInt.descent = fontMetricsInt.bottom;
    }
    return rect.right;
}

@Override
public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end,
                 float x, int top, int y, int bottom, @NonNull Paint paint) {

    Drawable drawable = getDrawable();
    canvas.save();
    Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();
    int fontHeight = fmPaint.descent - fmPaint.ascent;
    int centerY = y + fmPaint.descent - fontHeight / 2;
    int transY = centerY - (drawable.getBounds().bottom - drawable.getBounds().top) / 2;
    canvas.translate(x, transY);
    drawable.draw(canvas);
    canvas.restore();
}

}

并更改图片类如下所示

代码语言:javascript
复制
VerticalImageSpan span = new VerticalImageSpan(chip);
票数 32
EN

Stack Overflow用户

发布于 2020-05-12 09:40:03

如果您想要在多行芯片上实现类似gmail的行为,那么前面所有的解决方案都不适用于我。为了做到这一点,我不得不避免使用FlexboxLayout.,而不是使用ChipGroup

your_recipient_layout:

代码语言:javascript
复制
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/recipient_label_TV"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        android:layout_gravity="center_vertical" />

    <com.google.android.flexbox.FlexboxLayout
        android:id="@+id/recipient_group_FL"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_gravity="center_vertical"
        app:flexWrap="wrap"
        app:alignItems="stretch"
        app:alignContent="space_around"
        app:showDivider="beginning|middle|end"
        app:dividerDrawable="@drawable/divider">

        <EditText
            android:id="@+id/recipient_input_ET"
            android:layout_width="wrap_content"
            android:layout_height="32dp"
            app:layout_flexGrow="1"
            android:background="@android:color/transparent"
            android:imeOptions="actionDone"
            android:inputType="text"/>

    </com.google.android.flexbox.FlexboxLayout>

</LinearLayout>

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recipients_list_RV"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:visibility="gone" />

现在的诀窍是在小组中增加一个新的芯片,但作为第二位。就像这样:

代码语言:javascript
复制
private fun addNewChip(person: String, chipGroup: FlexboxLayout) {
    val chip = Chip(context)
    chip.text = person
    chip.chipIcon = ContextCompat.getDrawable(requireContext(), R.mipmap.ic_launcher_round)
    chip.isCloseIconEnabled = true
    chip.isClickable = true
    chip.isCheckable = false
    chipGroup.addView(chip as View, chipGroup.childCount - 1)
    chip.setOnCloseIconClickListener { chipGroup.removeView(chip as View) }
}
票数 26
EN

Stack Overflow用户

发布于 2019-02-25 11:06:49

我们可以这样做,使用材料芯片设计本身,而不添加任何额外的风格。

将其添加到AndroidX的应用程序级上

实现'com.google.android.material:material:1.0.0-beta01‘

对于比AndroidX更早的用户,请使用此

实现“com.android.Support:design:28.0”

片段

代码语言:javascript
复制
class EntryChipDemoFragment : Fragment() {
    private lateinit var mView: View

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        mView = inflater.inflate(R.layout.fragment_entry_chip_demo, container, false)

        mView.etValue.setOnEditorActionListener(TextView.OnEditorActionListener { v, actionId, _ ->
            if (actionId == EditorInfo.IME_ACTION_DONE) {
                val txtVal = v.text
                if(!txtVal.isNullOrEmpty()) {
                    addChipToGroup(txtVal.toString(), mView.chipGroup2)
                    mView.etValue.setText("")
                }

                return@OnEditorActionListener true
            }
            false
        })

        return mView
    }


    private fun addChipToGroup(txt: String, chipGroup: ChipGroup) {
        val chip = Chip(context)
        chip.text = txt
//        chip.chipIcon = ContextCompat.getDrawable(requireContext(), baseline_person_black_18)
        chip.isCloseIconEnabled = true
        chip.setChipIconTintResource(R.color.chipIconTint)

        // necessary to get single selection working
        chip.isClickable = false
        chip.isCheckable = false
        chipGroup.addView(chip as View)
        chip.setOnCloseIconClickListener { chipGroup.removeView(chip as View) }
        printChipsValue(chipGroup)
    }

    private fun printChipsValue(chipGroup: ChipGroup) {
        for (i in 0 until chipGroup.childCount) {
            val chipObj = chipGroup.getChildAt(i) as Chip
            Log.d("Chips text :: " , chipObj.text.toString())

        }
    }

    companion object {
        @JvmStatic
        fun newInstance() = EntryChipDemoFragment()
    }
}

XML文件:

代码语言:javascript
复制
<HorizontalScrollView
    android:id="@+id/chipGroup2HorizontalView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="8dp"
    android:layout_marginTop="16dp"
    android:scrollbars="none"
    app:layout_constraintVertical_bias="0.62">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <androidx.appcompat.widget.AppCompatTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Skills: " />

        <com.google.android.material.chip.ChipGroup
            android:id="@+id/chipGroup2"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:duplicateParentState="false">

        </com.google.android.material.chip.ChipGroup>

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/textInputLayout"
            android:layout_width="wrap_content"
            android:layout_height="43dp"
            android:layout_marginStart="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginBottom="5dp"
            android:minWidth="32dp"
            android:visibility="visible"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@id/chipGroup2HorizontalView"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintWidth_min="32dp">

            <androidx.appcompat.widget.AppCompatEditText
                android:id="@+id/etValue"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@android:color/transparent"
                android:imeOptions="actionDone"
                android:maxLines="1"
                android:singleLine="true" />

        </com.google.android.material.textfield.TextInputLayout>

    </LinearLayout>


</HorizontalScrollView>

欲获得更多参考,单击此处

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50574943

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档