studio para moviles herramientas desarrollo con avanzado app aplicaciones android colors textview

para - Texto de esquema de vista de texto de Android



herramientas de android studio pdf (13)

El marco es compatible con text-shadow, pero no es compatible con text-outline. Pero hay un truco: la sombra es algo que es translúcido y se desvanece. Redibuja una sombra un par de veces y todas las alfa se sumarán y el resultado será un contorno.

Una implementación muy simple extiende TextView y anula el método de dibujo. Cada vez que se solicita un sorteo, nuestra subclase realiza 5-10 sorteos.

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

¿Hay alguna manera simple de que el texto tenga un contorno negro? Tengo textviews que serán de diferentes colores, pero algunos de los colores no aparecen tan bien en mi fondo, así que me preguntaba si hay una forma fácil de obtener un contorno negro u otra cosa que haga el trabajo. Preferiría no tener que crear una vista personalizada y hacer un lienzo y tal.


Encontré una manera simple de delinear la vista sin herencia de TextView . Escribí una biblioteca simple que usa el Spannable de Android para delinear texto. Esta solución brinda la posibilidad de delinear solo una parte del texto.

Ya había respondido la misma pregunta ( answer )

Clase:

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

Biblioteca: OutlineSpan


Entonces, ¿quieres un derrame cerebral en la vista de texto? Lamentablemente, no hay una manera simple de hacerlo con el estilo. Tendrá que crear otra vista y colocar su vista de texto en la parte superior, haciendo que la vista principal (la que está encima) solo unos pocos píxeles más grande, esto debería crear un contorno.


Es una pregunta bastante antigua, pero aún no veo respuestas completas. Así que estoy publicando esta solución, con la esperanza de que alguien que esté luchando con este problema pueda encontrarla útil. La solución más simple y efectiva es anular el método onDraw de la clase TextView. La mayoría de las implementaciones que he visto usan el método drawText para dibujar el trazo, pero ese enfoque no tiene en cuenta toda la alineación de formato y el ajuste del texto. Y como resultado, a menudo el trazo y el texto terminan en diferentes lugares. El siguiente enfoque utiliza super.onDraw para dibujar el trazo y rellenar partes del texto para que no tenga que preocuparse por el resto del material. Aquí están los pasos

  1. Extender clase TextView
  2. Anular el método onDraw
  3. Establecer el estilo de pintura en FILL
  4. llama a la clase padre en Draw para mostrar texto en modo de relleno.
  5. guardar el color del texto actual.
  6. Establecer el color del texto actual a su color de trazo
  7. Establecer el estilo de pintura para el trazo
  8. Establecer el ancho de trazo
  9. Y llame de nuevo a la clase padre onDraw para dibujar el trazo sobre el texto previamente presentado.

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

Eso es todo. Esta clase utiliza atributos XML personalizados para permitir especificar el color y el ancho del trazo desde los archivos de diseño XML. Por lo tanto, debe agregar estos atributos en su archivo attr.xml en la subcarpeta ''valores'' en la carpeta ''res''. Copie y pegue lo siguiente en su archivo 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>

Una vez que haya terminado con eso, puede usar la clase personalizada StrokedTextView en sus archivos de diseño XML y especificar el color y el ancho del trazo también. Aquí hay un ejemplo

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

Recuerde reemplazar el nombre del paquete con el nombre del paquete de su proyecto. También agregue el espacio de nombres xmlns en el archivo de diseño para usar atributos XML personalizados. Puede agregar la siguiente línea en el nodo raíz del archivo de diseño.

xmlns:strokeAttrs="http://schemas.android.com/apk/res-auto"


Este es el truco que encontré que funciona mejor que el trazo 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); }


He escrito una clase para realizar un texto con el contorno y todavía apoyo todos los demás atributos y el dibujo de una vista de texto normal.

básicamente utiliza el super.onDraw(Canves canvas) en el TextView pero dibuja dos veces con diferentes estilos.

espero que esto ayude.

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>


He estado tratando de descubrir cómo hacer esto y no pude encontrar una buena guía en línea, pero finalmente lo descubrí. Como sugirió Steve Pomeroy, tienes que hacer algo más complicado. Para obtener el efecto de texto delineado, dibuje el texto dos veces: una vez con un contorno grueso y luego la segunda vez dibujamos el texto principal sobre el contorno. Pero la tarea es más fácil porque puede adaptar fácilmente uno de los ejemplos de código proporcionados con el SDK, es decir, el que se encuentra bajo este nombre en su directorio SDK: "/ samples / android- / ApiDemos / src / com / example / android /apis/view/LabelView.java ". Que también se puede encontrar en el sitio web de desarrolladores de Android here .

Dependiendo de lo que esté haciendo, es muy fácil ver que solo necesitará hacer modificaciones menores a ese código, como cambiarlo para extenderlo desde TextView, etc. Antes de descubrir esta muestra, olvidé anular onMeasure () (que debe hacer además de anular onDraw () como se menciona en la guía "Creación de componentes personalizados" en el sitio web de Android Developer), que es parte de por qué estaba teniendo problemas.

Una vez que hayas hecho eso, puedes hacer lo que hice:

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

Entonces, para obtener el efecto de texto delineado, dibuja el texto dos veces: una con un contorno grueso y luego la segunda vez dibujamos el texto principal sobre el contorno.


MagicTextView es muy útil para hacer una fuente de trazo, pero en mi caso, causa un error como this este error causado por los atributos de fondo de duplicación que establece MagicTextView

entonces necesitas editar attrs.xml y 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)); } }


Por lo tanto, un poco tarde, pero MagicTextView hará contornos de texto, entre otras cosas.

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

Nota: Hice esto, y estoy publicando más por el bien de los futuros viajeros que por el OP. Es el límite de spam, pero estar en el tema, tal vez sea aceptable?


Puede hacerlo mediante programación con el siguiente fragmento. Eso proporciona letras blancas con fondo negro:

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

Los parámetros del método son radius, dx, dy, color. Puede cambiarlos para sus necesidades específicas.

Espero ayudar a alguien que crea TextView programmatically y no tenerlo dentro de xml.

Saludos a la comunidad !



el efecto de contorno se puede lograr usando la sombra en 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"


Creé una biblioteca basada en la respuesta de Nouman Hanif con algunas adiciones. Por ejemplo, corregir un error que causaba un bucle infinito indirecto en las llamadas a View.invalidate ().

OTOH, la biblioteca también admite texto resumido en widgets EditText, ya que era mi objetivo real y necesitaba un poco más de trabajo que TextView.

Aquí está el enlace a mi biblioteca: https://github.com/biomorgoth/android-outline-textview

¡Gracias a Nouman Hanif por la idea inicial de la solución!