web-dev-qa-db-de.com

Android Textview-Gliederungstext

Gibt es eine einfache Möglichkeit, Text schwarz umrissen zu lassen? Ich habe Textansichten, die unterschiedliche Farben haben werden, aber einige der Farben erscheinen nicht so gut auf meinem Hintergrund. Daher habe ich mich gefragt, ob es einen einfachen Weg gibt, eine schwarze Kontur oder etwas anderes zu erhalten, das die Aufgabe erfüllt. Ich möchte lieber keine benutzerdefinierte Ansicht erstellen und eine Leinwand oder ähnliches erstellen.

68
Falmarri

Sie können einen Schatten hinter den Text setzen, was oft zur besseren Lesbarkeit beiträgt. Versuchen Sie, mit 50% durchscheinenden schwarzen Schatten auf Ihrem grünen Text zu experimentieren. Details dazu finden Sie hier: Android - Schatten auf Text?

Um dem Text wirklich einen Strich hinzuzufügen, müssen Sie etwas mehr tun: Wie zeichnet man in Android eine MapView mit einem Rand?

49
Steve Pomeroy

Also etwas spät, aber MagicTextView führt unter anderem Textkonturen durch.

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

Hinweis: Ich habe das gemacht und poste mehr für zukünftige Reisende als für das OP. Es ist Borderline-Spam, aber ein Thema, vielleicht akzeptabel?

49
ABentSpoon

umrisseffekt kann mit Schatten in TextView erzielt werden:

    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ł

Das Framework unterstützt Textschatten, jedoch keine Textgliederung. Aber es gibt einen Trick: Schatten ist etwas, das durchscheinend ist und verblasst. Zeichne ein paar Mal einen Schatten auf, und das gesamte Alpha wird summiert. 

Eine sehr einfache Implementierung erweitert TextView und überschreibt die Draw-Methode. Jedes Mal, wenn eine Auslosung angefordert wird, erstellt unsere Unterklasse 5-10 Zeichnungen.

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

Es ist eine ziemlich alte Frage, aber trotzdem sehe ich keine vollständigen Antworten. Ich poste diese Lösung und hoffe, dass jemand, der mit diesem Problem zu kämpfen hat, es für nützlich hält. Die einfachste und effektivste Lösung ist das Überschreiben der onDraw-Methode der TextView-Klasse. Die meisten Implementierungen, die ich gesehen habe, verwenden die drawText-Methode zum Zeichnen des Strichs, aber dieser Ansatz berücksichtigt nicht die gesamte Formatierungsausrichtung und den Textumbruch, die in den Vordergrund treten. Der folgende Ansatz verwendet super.onDraw, um sowohl den Strich als auch den Teil des Textes zu zeichnen, sodass Sie sich nicht um den Rest des Materials kümmern müssen. Hier sind die Schritte

  1. Erweitern Sie die TextView-Klasse 
  2. Überschreiben Sie die onDraw-Methode 
  3. Setzen Sie den Malstil auf FILL 
  4. rufen Sie die übergeordnete Klasse in Draw auf, um den Text im Füllung-Modus zu erstellen. 
  5. aktuelle Textfarbe speichern. 
  6. Setzen Sie die aktuelle Textfarbe auf Ihre Strichfarbe 
  7. Legen Sie den Malstil auf Kontur fest 
  8. Hubbreite einstellen 
  9. Rufen Sie die übergeordnete Klasse erneut onDraw auf, um den Strich über den zuvor gerenderten Text zu zeichnen.

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

Das ist alles. Diese Klasse verwendet benutzerdefinierte XML-Attribute, um die Angabe der Strichfarbe und -breite aus den XML-Layoutdateien zu ermöglichen. Daher müssen Sie diese Attribute in Ihrer Datei attr.xml im Unterordner 'values' im Ordner 'res' hinzufügen. Kopieren Sie das Folgende und fügen Sie es in Ihre Datei attr.xml ein.

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

Wenn Sie damit fertig sind, können Sie die benutzerdefinierte StrokedTextView-Klasse in Ihren XML-Layoutdateien verwenden und auch die Farbe und Breite des Strichs angeben. Hier ist ein Beispiel

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

Vergessen Sie nicht, den Paketnamen durch den Paketnamen Ihres Projekts zu ersetzen. Fügen Sie auch den xmlns-Namespace in die Layoutdatei ein, um benutzerdefinierte XML-Attribute zu verwenden. Sie können die folgende Zeile im Stammknoten Ihrer Layoutdatei hinzufügen.

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

Ich habe gerade versucht herauszufinden, wie das geht, und ich konnte keinen guten Online-Führer finden, aber irgendwann habe ich es herausgefunden. Wie Steve Pomeroy vorschlug, müssen Sie etwas mehr unternehmen. Um den umrissenen Texteffekt zu erhalten, zeichnen Sie den Text zweimal: einmal mit einer dicken Kontur und dann beim zweiten Mal mit dem Haupttext über der Kontur. Die Aufgabe wird jedoch vereinfacht, da Sie eines der mit dem SDK gelieferten Codebeispiele, nämlich das unter diesem Namen, in Ihrem SDK-Verzeichnis sehr einfach anpassen können: "/ samples/Android-/ApiDemos/src/com/example/Android /apis/view/LabelView.Java ". Welches auch auf der Android-Entwicklerwebsite hier zu finden ist.

Je nachdem, was Sie tun, ist es sehr einfach zu sehen, dass Sie nur geringfügige Änderungen an diesem Code vornehmen müssen, z. B. durch Ändern, um ihn aus TextView zu erweitern usw. Bevor ich dieses Beispiel entdeckte, habe ich vergessen, onMeasure () zu überschreiben Sie müssen zusätzlich onDraw () überschreiben, wie in der Anleitung "Building Custom Components" auf der Android Developer-Website beschrieben. Dies ist ein Grund, warum ich Probleme hatte.

Sobald Sie das getan haben, können Sie tun, was ich getan habe:

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

Um den umrissenen Texteffekt zu erhalten, zeichnen Sie den Text zweimal: einmal mit einer dicken Umrandung und dann beim zweiten Mal den Haupttext über der Umrisslinie.

14
sversch

Hier ist der Trick, den ich gefunden habe und der besser funktioniert als MagicTextView IMO

@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

Ich habe eine Klasse geschrieben, um Text mit Gliederung auszuführen und trotzdem alle anderen Attribute und Zeichnungen einer normalen Textansicht zu unterstützen.

es verwendet grundsätzlich super.onDraw(Canves canvas) für die TextView, zeichnet jedoch zweimal mit verschiedenen Stilen.

hoffe das hilft.

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

Sie können dies programmgesteuert mit dem folgenden Snippet tun.

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

Die Parameter der Methode sind Radius, dx, dy, color. Sie können sie für Ihre speziellen Bedürfnisse ändern.

Ich hoffe, ich helfe jemandem, der TextView programmgesteuert erstellt und nicht in XML enthält.

Prost auf die stackOverflow Community!

2
Farmaker

Sie wollen also einen Strich um die Textansicht? Leider gibt es keine einfache Möglichkeit, mit dem Styling umzugehen. Sie müssen eine andere Ansicht erstellen und Ihre Textansicht darüber legen, wodurch die übergeordnete Ansicht (die Ansicht, auf der sie sich befindet) nur um einige Pixel vergrößert wird. Dies sollte eine Gliederung schaffen.

0
xil3

Ich möchte eine Lösung hinzufügen, um das Leistungsproblem zu lösen. Beispielsweise erledigt die Antwort von @YGHM und einigen anderen die Aufgabe, bewirkt jedoch einen unendlichen Aufruf von onDraw, da setTextColorinvalidate() aufruft. Um dies zu lösen, müssen Sie auch invalidate() überschreiben und eine Variable isDrawing hinzufügen, die Sie auf true setzen, wenn onDraw() gerade ausgeführt wird und mit einem Strich gezeichnet wird. invalidate wird zurückgegeben, wenn die Variable true ist.

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

Ihr onDraw wird so aussehen:

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

Ich habe eine Bibliothek basierend auf Nouman Hanifs Antwort mit einigen Ergänzungen erstellt. Beispielsweise das Beheben eines Fehlers, der eine indirekte Endlosschleife bei View.invalidate () - Aufrufen verursacht hat.

OTOH unterstützt die Bibliothek auch den umrissenen Text in EditText-Widgets, da dies mein eigentliches Ziel war und etwas mehr Arbeit als TextView benötigte.

Hier ist der Link zu meiner Bibliothek: https://github.com/biomorgoth/Android-outline-textview

Danke an Nouman Hanif für die erste Idee zur Lösung!

0
biomorgoth

Ich habe einen einfachen Weg gefunden, die Ansicht ohne Vererbung von TextView ..__ zu skizzieren. Ich hatte eine einfache Bibliothek geschrieben, die Android's Spannable für die Gliederung von Text verwendet.

Ich hatte bereits auf dieselbe Frage geantwortet ( Antwort )

Klasse:

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

}

Bibliothek: OutlineSpan

0
Pavel Santaev

gutschrift an @YGHM Schattenunterstützung hinzufügen  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 definieren

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

xML-Code unten

<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 ist sehr nützlich, um eine Strichschriftart zu erstellen. In meinem Fall verursacht dies jedoch einen Fehler wie this Dieser Fehler wird durch doppelte Hintergrundattribute verursacht, die von MagicTextView gesetzt werden

sie müssen also attrs.xml und MagicTextView.Java bearbeiten

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