web-dev-qa-db-fra.com

Texte de contour Android

Existe-t-il un moyen simple d’avoir du texte en noir? J'ai des textviews de couleurs différentes, mais certaines couleurs n'apparaissent pas aussi bien sur mon arrière-plan. Je me demandais donc s'il existait un moyen facile d'obtenir un contour noir ou autre chose qui ferait l'affaire. Je préférerais ne pas avoir à créer une vue personnalisée et à créer un canevas, etc.

68
Falmarri

Vous pouvez placer une ombre derrière le texte, ce qui peut souvent améliorer la lisibilité. Essayez d’essayer avec 50% d’ombres noires translucides sur votre texte vert. Vous trouverez des détails sur la procédure à suivre ici: Android - shadow on text?

Pour vraiment ajouter un trait autour du texte, vous devez faire quelque chose d'un peu plus compliqué, comme ceci: Comment dessinez-vous du texte avec une bordure sur un MapView sous Android?

49
Steve Pomeroy

Donc, un peu tard, mais MagicTextView fera les contours de texte, entre autres.

enter image description here

<com.qwerjk.better_text.MagicTextView
    xmlns:qwerjk="http://schemas.Android.com/apk/res/com.qwerjk.better_text"
    Android:textSize="78dp"
    Android:textColor="#ff333333"
    Android:layout_width="fill_parent"
    Android:layout_height="wrap_content"
    qwerjk:strokeColor="#FFff0000"
    qwerjk:strokeJoinStyle="miter"
    qwerjk:strokeWidth="5"
    Android:text="Magic" />

Note: J'ai fait ceci, et j'en publie plus pour le bien des futurs voyageurs que l'OP. C'est du spam à la limite, mais être sur le sujet, peut-être acceptable?

49
ABentSpoon

l’effet de contour peut être obtenu à l’aide de l’ombre dans TextView:

    Android:shadowColor="#000000"
    Android:shadowDx="1.5"
    Android:shadowDy="1.3"
    Android:shadowRadius="1.6"
    Android:text="CCC"
    Android:textAllCaps="true"
    Android:textColor="@Android:color/white"
48
Rafał

Le cadre prend en charge text-shadow, mais pas text-outline. Mais il y a un truc: l'ombre est quelque chose de translucide qui s'estompe. Redessine une ombre quelques temps et tout l'alpha sera résumé et un résultat est un contour. 

Une implémentation très simple étend TextView et remplace la méthode draw. Chaque fois qu'un tirage est demandé, notre sous-classe effectue 5 à 10 dessins.

public class OutlineTextView extends TextView {

    // Constructors

    @Override
    public void draw(Canvas canvas) {
        for (int i = 0; i < 5; i++) {
            super.draw(canvas);
        }
    }

}


<OutlineTextView
    Android:shadowColor="#000"
    Android:shadowRadius="3.0" />
20
Zsolt Safrany

C'est une question assez ancienne mais je ne vois toujours pas de réponses complètes. Je publie donc cette solution en espérant qu'une personne aux prises avec ce problème le trouvera utile. La solution la plus simple et la plus efficace consiste à remplacer la méthode onDraw de la classe TextView. La plupart des implémentations que j'ai vues utilisent la méthode drawText pour dessiner le trait, mais cette approche ne tient pas compte de tout l'alignement de mise en forme et de l'habillage du texte. Le résultat est souvent que le trait et le texte se retrouvent à différents endroits. L'approche suivante utilise super.onDraw pour dessiner à la fois le trait et le remplissage du texte afin que vous n'ayez pas à vous soucier du reste. Voici les étapes

  1. Étendre la classe TextView 
  2. Remplacer la méthode onDraw 
  3. Définir le style de peinture sur REMPLIR 
  4. appelez la classe parente sur Draw pour rendre le texte en mode Remplissage
  5. enregistrer la couleur du texte actuel. 
  6. Définir la couleur de texte actuelle en fonction de la couleur de votre trait 
  7. Définir le style de peinture sur Stroke 
  8. Définir la largeur de trait 
  9. Et appelez à nouveau la classe parente onDraw pour tracer le trait sur le texte précédemment rendu.

    package com.example.widgets;
    
    import Android.content.Context;
    import Android.content.res.TypedArray;
    import Android.graphics.Canvas;
    import Android.graphics.Paint;
    import Android.graphics.Typeface;
    import Android.util.AttributeSet;
    import Android.widget.Button;
    
    public class StrokedTextView extends Button {
    
        private static final int DEFAULT_STROKE_WIDTH = 0;
    
        // fields
        private int _strokeColor;
        private float _strokeWidth;
    
        // constructors
        public StrokedTextView(Context context) {
            this(context, null, 0);
        }
    
        public StrokedTextView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public StrokedTextView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
    
            if(attrs != null) {
                TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.StrokedTextAttrs);
                _strokeColor = a.getColor(R.styleable.StrokedTextAttrs_textStrokeColor,
                        getCurrentTextColor());         
                _strokeWidth = a.getFloat(R.styleable.StrokedTextAttrs_textStrokeWidth,
                        DEFAULT_STROKE_WIDTH);
    
                a.recycle();
            }
            else {          
                _strokeColor = getCurrentTextColor();
                _strokeWidth = DEFAULT_STROKE_WIDTH;
            } 
            //convert values specified in dp in XML layout to
            //px, otherwise stroke width would appear different
            //on different screens
            _strokeWidth = dpToPx(context, _strokeWidth);           
        }    
    
        // getters + setters
        public void setStrokeColor(int color) {
            _strokeColor = color;        
        }
    
        public void setStrokeWidth(int width) {
            _strokeWidth = width;
        }
    
        // overridden methods
        @Override
        protected void onDraw(Canvas canvas) {
            if(_strokeWidth > 0) {
                //set Paint to fill mode
                Paint p = getPaint();
                p.setStyle(Paint.Style.FILL);        
                //draw the fill part of text
                super.onDraw(canvas);       
                //save the text color   
                int currentTextColor = getCurrentTextColor();    
                //set Paint to stroke mode and specify 
                //stroke color and width        
                p.setStyle(Paint.Style.STROKE);
                p.setStrokeWidth(_strokeWidth);
                setTextColor(_strokeColor);
                //draw text stroke
                super.onDraw(canvas);      
               //revert the color back to the one 
               //initially specified
               setTextColor(currentTextColor);
           } else {
               super.onDraw(canvas);
           }
       }
    
       /**
        * Convenience method to convert density independent pixel(dp) value
        * into device display specific pixel value.
        * @param context Context to access device specific display metrics 
        * @param dp density independent pixel value
        * @return device specific pixel value.
        */
       public static int dpToPx(Context context, float dp)
       {
           final float scale= context.getResources().getDisplayMetrics().density;
           return (int) (dp * scale + 0.5f);
       }            
    }
    

C'est tout. Cette classe utilise des attributs XML personnalisés pour permettre de spécifier la couleur et la largeur du trait à partir des fichiers de présentation XML. Par conséquent, vous devez ajouter ces attributs dans votre fichier attr.xml dans le sous-dossier 'valeurs' sous le dossier 'res'. Copiez et collez le texte suivant dans votre fichier attr.xml.

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="StrokedTextAttrs">
        <attr name="textStrokeColor" format="color"/>    
        <attr name="textStrokeWidth" format="float"/>
    </declare-styleable>                

</resources>

Une fois que vous avez terminé, vous pouvez utiliser la classe personnalisée StrokedTextView dans vos fichiers de présentation XML et spécifier la couleur et la largeur du trait. Voici un exemple

<com.example.widgets.StrokedTextView
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:text="Stroked text sample"
    Android:textColor="@Android:color/white"
    Android:textSize="25sp"
    strokeAttrs:textStrokeColor="@Android:color/black"
    strokeAttrs:textStrokeWidth="1.7" />

N'oubliez pas de remplacer le nom du paquet par le nom du paquet de votre projet. Ajoutez également l'espace de noms xmlns dans le fichier de disposition afin d'utiliser des attributs XML personnalisés. Vous pouvez ajouter la ligne suivante dans le nœud racine de votre fichier de mise en page.

xmlns:strokeAttrs="http://schemas.Android.com/apk/res-auto"
15
Nouman Hanif

Je viens juste d'essayer de comprendre comment faire cela et je ne pouvais pas trouver un bon guide en ligne mais je l'ai finalement compris. Comme Steve Pomeroy l'a suggéré, vous devez faire quelque chose de plus impliqué. Pour obtenir l'effet de texte souligné, vous dessinez le texte deux fois: une fois avec un contour épais, puis la deuxième fois, nous traçons le texte principal par dessus le contour. Toutefois, la tâche est facilitée car vous pouvez très facilement adapter l’un des exemples de code fournis avec le SDK, à savoir celui qui se trouve sous ce nom dans votre répertoire SDK: "/ samples/Android-/ApiDemos/src/com/exemple/Android. /apis/view/LabelView.Java ". Ce qui peut également être trouvé sur le site du développeur Android ici .

En fonction de ce que vous faites, il est très facile de voir qu'il vous suffira d'apporter des modifications mineures à ce code, par exemple de le changer pour qu'il s'étende de TextView, etc. Avant de découvrir cet exemple, j'avais oublié de remplacer onMeasure () (qui vous devez faire en plus de remplacer onDraw () comme indiqué dans le guide "Création de composants personnalisés" sur le site Web de développeur Android), ce qui explique en partie pourquoi j'ai eu des problèmes.

Une fois que vous avez fait cela, vous pouvez faire ce que j'ai fait:

public class TextViewOutline extends TextView {

private Paint mTextPaint;
private Paint mTextPaintOutline; //add another Paint attribute for your outline
...
//modify initTextViewOutline to setup the outline style
   private void initTextViewOutline() {
       mTextPaint = new Paint();
       mTextPaint.setAntiAlias(true);
       mTextPaint.setTextSize(16);
       mTextPaint.setColor(0xFF000000);
       mTextPaint.setStyle(Paint.Style.FILL);

       mTextPaintOutline = new Paint();
       mTextPaintOutline.setAntiAlias(true);
       mTextPaintOutline.setTextSize(16);
       mTextPaintOutline.setColor(0xFF000000);
       mTextPaintOutline.setStyle(Paint.Style.STROKE);
       mTextPaintOutline.setStrokeWidth(4);

       setPadding(3, 3, 3, 3);
}
...
//make sure to update other methods you've overridden to handle your new Paint object
...
//and finally draw the text, mAscent refers to a member attribute which had
//a value assigned to it in the measureHeight and Width methods
   @Override
   protected void onDraw(Canvas canvas) {
       super.onDraw(canvas);
       canvas.drawText(mText, getPaddingLeft(), getPaddingTop() - mAscent, 
           mTextPaintOutline);
       canvas.drawText(mText, getPaddingLeft(), getPaddingTop() - mAscent, mTextPaint);
   }

Ainsi, pour obtenir l'effet de texte souligné, vous dessinez le texte deux fois: une fois avec un contour épais et ensuite une seconde fois, nous traçons le texte principal par-dessus le contour.

14
sversch

Voici le truc que j'ai trouvé qui fonctionne mieux que le trait IMO de MagicTextView

@Override
protected void onDraw(Canvas pCanvas) {
    int textColor = getTextColors().getDefaultColor();
    setTextColor(mOutlineColor); // your stroke's color
    getPaint().setStrokeWidth(10);
    getPaint().setStyle(Paint.Style.STROKE);
    super.onDraw(pCanvas);
    setTextColor(textColor);
    getPaint().setStrokeWidth(0);
    getPaint().setStyle(Paint.Style.FILL);
    super.onDraw(pCanvas);
}
6
VinZen

J'ai écrit une classe pour effectuer du texte avec contour et prendre en charge tous les autres attributs et dessins d'une vue de texte normale.

il utilise essentiellement la super.onDraw(Canves canvas) sur la TextView mais dessine deux fois avec des styles différents.

j'espère que cela t'aides.

public class TextViewOutline extends TextView {

    // constants
    private static final int DEFAULT_OUTLINE_SIZE = 0;
    private static final int DEFAULT_OUTLINE_COLOR = Color.TRANSPARENT;

    // data
    private int mOutlineSize;
    private int mOutlineColor;
    private int mTextColor;
    private float mShadowRadius;
    private float mShadowDx;
    private float mShadowDy;
    private int mShadowColor;

    public TextViewOutline(Context context) {
        this(context, null);
    }

    public TextViewOutline(Context context, AttributeSet attrs) {
        super(context, attrs);
        setAttributes(attrs);
    }

    private void setAttributes(AttributeSet attrs){ 
        // set defaults
        mOutlineSize = DEFAULT_OUTLINE_SIZE;
        mOutlineColor = DEFAULT_OUTLINE_COLOR;   
        // text color   
        mTextColor = getCurrentTextColor();
        if(attrs != null) {
            TypedArray a = getContext().obtainStyledAttributes(attrs,R.styleable.TextViewOutline);
            // outline size
            if (a.hasValue(R.styleable.TextViewOutline_outlineSize)) {
                mOutlineSize = (int) a.getDimension(R.styleable.TextViewOutline_outlineSize, DEFAULT_OUTLINE_SIZE);
            }
            // outline color
            if (a.hasValue(R.styleable.TextViewOutline_outlineColor)) {
                mOutlineColor = a.getColor(R.styleable.TextViewOutline_outlineColor, DEFAULT_OUTLINE_COLOR);
            }
            // shadow (the reason we take shadow from attributes is because we use API level 15 and only from 16 we have the get methods for the shadow attributes)
            if (a.hasValue(R.styleable.TextViewOutline_Android_shadowRadius) 
                    || a.hasValue(R.styleable.TextViewOutline_Android_shadowDx)
                    || a.hasValue(R.styleable.TextViewOutline_Android_shadowDy) 
                    || a.hasValue(R.styleable.TextViewOutline_Android_shadowColor)) {
                mShadowRadius = a.getFloat(R.styleable.TextViewOutline_Android_shadowRadius, 0);
                mShadowDx = a.getFloat(R.styleable.TextViewOutline_Android_shadowDx, 0);
                mShadowDy = a.getFloat(R.styleable.TextViewOutline_Android_shadowDy, 0);
                mShadowColor = a.getColor(R.styleable.TextViewOutline_Android_shadowColor, Color.TRANSPARENT);
            }

            a.recycle();
        }

        PFLog.d("mOutlineSize = " + mOutlineSize);
        PFLog.d("mOutlineColor = " + mOutlineColor);
    }

    private void setPaintToOutline(){
        Paint paint = getPaint();
        Paint.setStyle(Paint.Style.STROKE);
        Paint.setStrokeWidth(mOutlineSize);
        super.setTextColor(mOutlineColor);
        super.setShadowLayer(mShadowRadius, mShadowDx, mShadowDy,  mShadowColor);
    }

    private void setPaintToRegular() {
        Paint paint = getPaint();
        Paint.setStyle(Paint.Style.FILL);
        Paint.setStrokeWidth(0);
        super.setTextColor(mTextColor);
        super.setShadowLayer(0, 0, 0, Color.TRANSPARENT);
    } 

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setPaintToOutline();
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    public void setTextColor(int color) {
        super.setTextColor(color);
        mTextColor = color;
    } 

    @Override
    public void setShadowLayer(float radius, float dx, float dy, int color) {
        super.setShadowLayer(radius, dx, dy, color);
        mShadowRadius = radius;
        mShadowDx = dx;
        mShadowDy = dy;
        mShadowColor = color;
    }

    public void setOutlineSize(int size){
        mOutlineSize = size;
    }

    public void setOutlineColor(int color){
       mOutlineColor = color;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        setPaintToOutline();
        super.onDraw(canvas);
        setPaintToRegular();
        super.onDraw(canvas);
    }

}

attr.xml

<declare-styleable name="TextViewOutline">
    <attr name="outlineSize" format="dimension"/>
    <attr name="outlineColor" format="color|reference"/>
    <attr name="Android:shadowRadius"/>
    <attr name="Android:shadowDx"/>
    <attr name="Android:shadowDy"/>
    <attr name="Android:shadowColor"/>
</declare-styleable>
6
YGHM

Vous pouvez le faire par programme avec l'extrait ci-dessous . Cela fournit des lettres blanches sur fond noir:

textView.setTextColor(Color.WHITE);            
textView.setShadowLayer(1.6f,1.5f,1.3f,Color.BLACK);

Les paramètres de la méthode sont radius, dx, dy, color. Vous pouvez les changer pour vos besoins spécifiques.

J'espère que j'aiderai quelqu'un qui crée TextView par programme sans l'avoir dans XML.

Bravo à la communauté stackOverflow!

2
Farmaker

Donc, vous voulez un trait autour de la vue texte? Malheureusement, il n'y a pas de moyen simple de le faire avec le style. Vous devrez créer une autre vue et placer votre vue de texte par-dessus, ce qui fera que la vue parent (celle au-dessus de celle-ci) sera plus grande de quelques pixels - cela devrait créer un contour.

0
xil3

Je veux ajouter une solution afin de résoudre le problème de performances. Par exemple, la réponse de @YGHM et de quelques autres effectue le travail, mais elle provoque un appel infini de onDraw car setTextColor appelle invalidate(). Donc, pour le résoudre, vous devez également redéfinir invalidate() et ajouter une variable isDrawing que vous définissez sur true, lorsque onDraw() est en cours et dessiné d'un trait. invalidate retournera si la variable est true.

override fun invalidate() {
    if (isDrawing) return
    super.invalidate()
  }

Votre onDraw ressemblera à ceci:

override fun onDraw(canvas: Canvas) {
    if (strokeWidth > 0) {
      isDrawing = true
      val textColor = textColors.defaultColor
      setTextColor(strokeColor)
      Paint.strokeWidth = strokeWidth
      Paint.style = Paint.Style.STROKE
      super.onDraw(canvas)
      setTextColor(textColor)
      Paint.strokeWidth = 0f
      Paint.style = Paint.Style.FILL
      isDrawing = false
      super.onDraw(canvas)
    } else {
      super.onDraw(canvas)
    }
  }
0
Sermilion

J'ai créé une bibliothèque basée sur la réponse de Nouman Hanif avec quelques ajouts. Par exemple, résoudre un problème qui provoquait une boucle infinie indirecte sur les appels View.invalidate ().

OTOH, la bibliothèque prend également en charge le texte décrit dans les widgets EditText, car c’était mon objectif principal et qu’il fallait un peu plus de travail que TextView.

Voici le lien vers ma bibliothèque: https://github.com/biomorgoth/Android-outline-textview

Merci à Nouman Hanif pour l’idée initiale sur la solution!

0
biomorgoth

J'ai trouvé un moyen simple de contourner la vue sans héritage de TextView . J'avais écrit une bibliothèque simple qui utilise Spannable d'Android pour dessiner le texte . Cette solution permet de ne dessiner qu'une partie du texte.

J'ai déjà répondu à la même question ( réponse )

Classe:

class OutlineSpan(
        @ColorInt private val strokeColor: Int,
        @Dimension private val strokeWidth: Float
): ReplacementSpan() {

    override fun getSize(
            Paint: Paint,
            text: CharSequence,
            start: Int,
            end: Int,
            fm: Paint.FontMetricsInt?
    ): Int {
        return Paint.measureText(text.toString().substring(start until end)).toInt()
    }


    override fun draw(
            canvas: Canvas,
            text: CharSequence,
            start: Int,
            end: Int,
            x: Float,
            top: Int,
            y: Int,
            bottom: Int,
            Paint: Paint
    ) {
        val originTextColor = Paint.color

        Paint.apply {
            color = strokeColor
            style = Paint.Style.STROKE
            this.strokeWidth = [email protected]
        }
        canvas.drawText(text, start, end, x, y.toFloat(), Paint)

        Paint.apply {
            color = originTextColor
            style = Paint.Style.FILL
        }
        canvas.drawText(text, start, end, x, y.toFloat(), Paint)
    }

}

Bibliothèque: OutlineSpan

0
Pavel Santaev

crédit à @YGHM ajouter un support shadow  enter image description here 

package com.megvii.demo;
import Android.content.Context;
import Android.content.res.TypedArray;
import Android.graphics.Canvas;
import Android.graphics.Color;
import Android.graphics.Paint;
import Android.util.AttributeSet;

public class TextViewOutline extends Android.support.v7.widget.AppCompatTextView {

// constants
private static final int DEFAULT_OUTLINE_SIZE = 0;
private static final int DEFAULT_OUTLINE_COLOR = Color.TRANSPARENT;

// data
private int mOutlineSize;
private int mOutlineColor;
private int mTextColor;
private float mShadowRadius;
private float mShadowDx;
private float mShadowDy;
private int mShadowColor;

public TextViewOutline(Context context) {
    this(context, null);
}

public TextViewOutline(Context context, AttributeSet attrs) {
    super(context, attrs);
    setAttributes(attrs);
}

private void setAttributes(AttributeSet attrs) {
    // set defaults
    mOutlineSize = DEFAULT_OUTLINE_SIZE;
    mOutlineColor = DEFAULT_OUTLINE_COLOR;
    // text color   
    mTextColor = getCurrentTextColor();
    if (attrs != null) {
        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.TextViewOutline);
        // outline size
        if (a.hasValue(R.styleable.TextViewOutline_outlineSize)) {
            mOutlineSize = (int) a.getDimension(R.styleable.TextViewOutline_outlineSize, DEFAULT_OUTLINE_SIZE);
        }
        // outline color
        if (a.hasValue(R.styleable.TextViewOutline_outlineColor)) {
            mOutlineColor = a.getColor(R.styleable.TextViewOutline_outlineColor, DEFAULT_OUTLINE_COLOR);
        }
        // shadow (the reason we take shadow from attributes is because we use API level 15 and only from 16 we have the get methods for the shadow attributes)
        if (a.hasValue(R.styleable.TextViewOutline_Android_shadowRadius)
                || a.hasValue(R.styleable.TextViewOutline_Android_shadowDx)
                || a.hasValue(R.styleable.TextViewOutline_Android_shadowDy)
                || a.hasValue(R.styleable.TextViewOutline_Android_shadowColor)) {
            mShadowRadius = a.getFloat(R.styleable.TextViewOutline_Android_shadowRadius, 0);
            mShadowDx = a.getFloat(R.styleable.TextViewOutline_Android_shadowDx, 0);
            mShadowDy = a.getFloat(R.styleable.TextViewOutline_Android_shadowDy, 0);
            mShadowColor = a.getColor(R.styleable.TextViewOutline_Android_shadowColor, Color.TRANSPARENT);
        }

        a.recycle();
    }

}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    setPaintToOutline();
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

private void setPaintToOutline() {
    Paint paint = getPaint();
    Paint.setStyle(Paint.Style.STROKE);
    Paint.setStrokeWidth(mOutlineSize);
    super.setTextColor(mOutlineColor);
    super.setShadowLayer(0, 0, 0, Color.TRANSPARENT);

}

private void setPaintToRegular() {
    Paint paint = getPaint();
    Paint.setStyle(Paint.Style.FILL);
    Paint.setStrokeWidth(0);
    super.setTextColor(mTextColor);
    super.setShadowLayer(mShadowRadius, mShadowDx, mShadowDy, mShadowColor);
}


@Override
public void setTextColor(int color) {
    super.setTextColor(color);
    mTextColor = color;
}


public void setOutlineSize(int size) {
    mOutlineSize = size;
}

public void setOutlineColor(int color) {
    mOutlineColor = color;
}

@Override
protected void onDraw(Canvas canvas) {
    setPaintToOutline();
    super.onDraw(canvas);

    setPaintToRegular();
    super.onDraw(canvas);
}

}

attr définit

<declare-styleable name="TextViewOutline">
    <attr name="outlineSize" format="dimension"/>
    <attr name="outlineColor" format="color|reference"/>
    <attr name="Android:shadowRadius"/>
    <attr name="Android:shadowDx"/>
    <attr name="Android:shadowDy"/>
    <attr name="Android:shadowColor"/>
</declare-styleable>

code XML ci-dessous

<com.megvii.demo.TextViewOutline
    Android:id="@+id/product_name"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:layout_gravity="center_horizontal"
    Android:layout_marginTop="110dp"
    Android:background="#f4b222"
    Android:fontFamily="@font/kidsmagazine"
    Android:padding="10dp"
    Android:shadowColor="#d7713200"
    Android:shadowDx="0"
    Android:shadowDy="8"
    Android:shadowRadius="1"
    Android:text="LIPSTICK SET"
    Android:textColor="@Android:color/white"
    Android:textSize="30sp"
    app:outlineColor="#cb7800"
    app:outlineSize="3dp" />
0
Arthur

MagicTextView est très utile pour créer une police de trait, mais dans mon cas, cela provoque une erreur comme this Cette erreur est causée par des attributs d'arrière-plan de duplication définis par MagicTextView.

il faut donc éditer attrs.xml et MagicTextView.Java

attrs.xml

<attr name="background" format="reference|color" />
 ↓
<attr name="mBackground" format="reference|color" />

MagicTextView.Java 88:95

if (a.hasValue(R.styleable.MagicTextView_mBackground)) {
Drawable background = a.getDrawable(R.styleable.MagicTextView_mBackground);
if (background != null) {
    this.setBackgroundDrawable(background);
} else {
    this.setBackgroundColor(a.getColor(R.styleable.MagicTextView_mBackground, 0xff000000));
}
}
0
Matsumoto Kazuya