web-dev-qa-db-fra.com

Comment ajouter des puces de la bibliothèque de composants de matériaux au champ de saisie dans Android?

J'ai vu que dans Android-P, Google ajoutait une nouvelle bibliothèque de composants matériels contenant des puces matérielles:

Composants matériels pour Android

tilisation des puces Material.io

Composants matériels sur GitHub

J'ai donc décidé d'ajouter des puces d'entrée de matériel à mon projet, mais malheureusement je n'ai trouvé aucun tutoriel pour le faire. Je veux créer quelque chose comme des puces Gmail mais sans image au début.

Parce que j'utilise la bibliothèque appcompat, j'ai essayé d'utiliser des puces matérielles par Android.support.design.chip.Chip et Android.support.design.chip.ChipGroup. Mais le résultat était juste des puces sans aucun champ d'entrée. J'ai également essayé de créer un ChipDrawable autonome, puis de l'ajouter à EditText en utilisant

Editable text = editText.getText();

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

Mais j'ai eu EditText vide sans puces. Alors, comment puis-je créer des puces comme dans Gmail en utilisant cette bibliothèque de composants matériels? Peut-être que quelqu'un a de l'expérience ou connaît des tutoriels où je pourrais voir comment créer cela?

Merci d'avance!

10
IDmikael

Réponse

Aucun champ de saisie par défaut pour ajouter des puces dans Android. Ils ont mentionné les puces d'entrée, mais je n'ai trouvé aucune disposition ou groupe de vues pour les puces d'entrée. Je fais donc avec la méthode Chipdrawable pour ajouter des puces dans edittext. Ici, j'utilise AppCompatEdittext vous pouvez changer pour n'importe quelle vue qui écoute les entrées de texte. Référence .

Étape 1

Ajouter une ressource xml de puce. chip.xml

res -> xml -> chip.xml

<?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/ChipTextApperance"
 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" />

Ajoutez ensuite le style d'apparence du texte dans style.xml (pour changer le style de texte)

<style name="ChipTextApperance" parent="TextAppearance.MaterialComponents.Chip">
    <item name="Android:textColor">@Android:color/white</item>
</style>

Étape 2

Ajoutez votre vue ici en utilisant AppCompatEdittext

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

Étape 3
Ajoutez ce code à votre vue pour obtenir le comportement souhaité.

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

        }
    });

Modifiez la longueur de la puce selon vos besoins lorsque de nouvelles puces doivent être ajoutées dans edittext.

[~ # ~] sortie [~ # ~]

enter image description here

[~ # ~] modifié [~ # ~]

Vous pouvez en savoir plus sur l'alignement du centre du texte avec span ici .

Ici, j'ai ajouté du code de la solution qui résoudra pour vous ..

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

}

Et changez votre classe d'imagespan comme ci-dessous

VerticalImageSpan span = new VerticalImageSpan(chip);
16

Nous pouvons le faire en utilisant la conception de puces matérielles elle-même sans ajouter de styles supplémentaires.

Ajoutez-le sur l'application Gradle pour AndroidX

implémentation 'com.google.Android.material: material: 1.0.0-beta01'

Pour une version antérieure à AndroidX, utilisez cette

implémentation 'com.Android.support:design:28.0.0'

enter image description here

Fragment

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

Fichier XML:

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

Pour plus de référence Cliquez ici

1
Naveen Kumar M

Vous pouvez utiliser la puce matérielle "com.google.Android.material.chip.Chip" et "l'implémentation" com.google.Android.material: material: 1.0.0 "" ajouter dans build.gradle

Style de filtre = "@ style/Widget.MaterialComponents.Chip.Filter"

Choice Chips style = "@ style/Widget.MaterialComponents.Chip.Choice"

Entrée d'entrée: style = "@ style/Widget.MaterialComponents.Chip.Entry"

0
Arul Pandian