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!
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 [~ # ~]
[~ # ~] 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);
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'
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
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"