¿Cómo ampliaría TextView
para permitir el dibujo de texto con un efecto de degradado?Texto con degradado en Android
Respuesta
No parece posible extender TextView para dibujar texto con un degradado. Sin embargo, es posible lograr este efecto creando un lienzo y dibujando sobre él. Primero necesitamos declare our custom UI element. En la iniciación necesitamos crear una subclase de Layout. En este caso, usaremos BoringLayout que solo admite texto con una sola línea.
Shader textShader=new LinearGradient(0, 0, 0, 20,
new int[]{bottom,top},
new float[]{0, 1}, TileMode.CLAMP);//Assumes bottom and top are colors defined above
textPaint.setTextSize(textSize);
textPaint.setShader(textShader);
BoringLayout.Metrics boringMetrics=BoringLayout.isBoring(text, textPaint);
boringLayout=new BoringLayout(text, textPaint, 0, Layout.Alignment.ALIGN_CENTER,
0.0f, 0.0f, boringMetrics, false);
A continuación, sobrescribimos onMeasure
y onDraw
:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
setMeasuredDimension((int) textPaint.measureText(text), (int) textPaint.getFontSpacing());
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
boringLayout.draw(canvas);
}
Nuestra implementación de onDraw
Es en este punto bastante vago (que ignora completamente las especificaciones de medición !, pero siempre y cuando usted garantiza que la vista es dado espacio suficiente, debería funcionar bien.
Alternativamente, sería posible heredar de un Canvas
y anular el método onPaint
. Si esto es d uno, entonces desafortunadamente el ancla para el texto que se está dibujando siempre estará en la parte inferior, así que tenemos que agregar -textPaint.getFontMetricsInt().ascent()
a nuestra coordenada y.
Una solución simple pero algo limitado sería el uso de estos atributos:
android:fadingEdge="horizontal"
android:scrollHorizontally="true"
lo he utilizado en campos de texto en el que necesito que se desvanecen si se acercan demasiado larga.
Ese es un buen truco. Supongo que no puedes hacer que eso funcione verticalmente. No hay ningún android: propiedad scrollVertically por lo que puedo ver – Casebash
Lo siento, no sé cómo hacer eso :( – pgsandstrom
TextView secondTextView = new TextView(this);
Shader textShader=new LinearGradient(0, 0, 0, 20,
new int[]{Color.GREEN,Color.BLUE},
new float[]{0, 1}, TileMode.CLAMP);
secondTextView.getPaint().setShader(textShader);
+1 para hacerlo más simple y eficiente. –
Gracias por una solución muy simple :) –
En mi dispositivo ICS, esto no parece funcionar - - es completamente transparente.¿Alguien más está viendo lo mismo? La vista no está acelerada por hardware. –
He enrollado una biblioteca que abarca ambos métodos. Puede crear GradientTextView en XML o simplemente usar GradientTextView.setGradient (TextView textView ...) para hacerlo en un objeto TextView normal.
Aquí es un ejemplo para LinearLayout, puede utilizar este ejemplo para TextView también, y en el código fuente que no habrá codificación gradiente, se obtiene el código fuente y añadir el código de ese sitio en sí - http://android-codes-examples.blogspot.com/2011/07/design-linearlayout-or-textview-and-any.html
Aquí es una buena manera de hacerlo:
/**
* sets a vertical gradient on the textView's paint, so that on its onDraw method, it will use it.
*
* @param viewAlreadyHasSize
* set to true only if the textView already has a size
*/
public static void setVerticalGradientOnTextView(final TextView tv, final int positionsAndColorsResId,
final boolean viewAlreadyHasSize) {
final String[] positionsAndColors = tv.getContext().getResources().getStringArray(positionsAndColorsResId);
final int[] colors = new int[positionsAndColors.length];
float[] positions = new float[positionsAndColors.length];
for (int i = 0; i < positionsAndColors.length; ++i) {
final String positionAndColors = positionsAndColors[i];
final int delimeterPos = positionAndColors.lastIndexOf(':');
if (delimeterPos == -1 || positions == null) {
positions = null;
colors[i] = Color.parseColor(positionAndColors);
} else {
positions[i] = Float.parseFloat(positionAndColors.substring(0, delimeterPos));
String colorStr = positionAndColors.substring(delimeterPos + 1);
if (colorStr.startsWith("0x"))
colorStr = '#' + colorStr.substring(2);
else if (!colorStr.startsWith("#"))
colorStr = '#' + colorStr;
colors[i] = Color.parseColor(colorStr);
}
}
setVerticalGradientOnTextView(tv, colors, positions, viewAlreadyHasSize);
}
/**
* sets a vertical gradient on the textView's paint, so that on its onDraw method, it will use it. <br/>
*
* @param colors
* the colors to use. at least one should exist.
* @param tv
* the textView to set the gradient on it
* @param positions
* where to put each color (fraction, max is 1). if null, colors are spread evenly .
* @param viewAlreadyHasSize
* set to true only if the textView already has a size
*/
public static void setVerticalGradientOnTextView(final TextView tv, final int[] colors, final float[] positions,
final boolean viewAlreadyHasSize) {
final Runnable runnable = new Runnable() {
@Override
public void run() {
final TileMode tile_mode = TileMode.CLAMP;
final int height = tv.getHeight();
final LinearGradient lin_grad = new LinearGradient(0, 0, 0, height, colors, positions, tile_mode);
final Shader shader_gradient = lin_grad;
tv.getPaint().setShader(shader_gradient);
}
};
if (viewAlreadyHasSize)
runnable.run();
else
runJustBeforeBeingDrawn(tv, runnable);
}
public static void runJustBeforeBeingDrawn(final View view, final Runnable runnable) {
final OnPreDrawListener preDrawListener = new OnPreDrawListener() {
@Override
public boolean onPreDraw() {
view.getViewTreeObserver().removeOnPreDrawListener(this);
runnable.run();
return true;
}
};
view.getViewTreeObserver().addOnPreDrawListener(preDrawListener);
}
Además, si se desea utilizar un mapa de bits de la pendiente, lugar o uno real, utilice:
/**
* sets an image for the textView <br/>
* NOTE: this function must be called after you have the view have its height figured out <br/>
*/
public static void setBitmapOnTextView(final TextView tv, final Bitmap bitmap) {
final TileMode tile_mode = TileMode.CLAMP;
final int height = tv.getHeight();
final int width = tv.getWidth();
final Bitmap temp = Bitmap.createScaledBitmap(bitmap, width, height, true);
final BitmapShader bitmapShader = new BitmapShader(temp, tile_mode, tile_mode);
tv.getPaint().setShader(bitmapShader);
}
Aquí está con soporte multilínea como un trazador de líneas. Esto debería funcionar también para los botones.
textView.getPaint().setShader(new LinearGradient(0,0,0,textView.getLineHeight(), startColor, endColor, Shader.TileMode.REPEAT));
simple y funciona excelente !! –
Funciona, pero para la altura es posible que desee tener en cuenta las letras que van por debajo de la línea real (como y, g, j, etc.) y multiplicar la altura de línea por 1.10f, p. Ej. 'textView.getLineHeight() * 1.10f'. –
- 1. css texto degradado
- 2. degradado radial Android
- 3. Crear borde degradado en Android?
- 4. ¿Cómo llenar un camino en Android con un degradado lineal?
- 5. Fondo de Android con degradado y mosaico de imagen
- 6. Android WebView: Deshabilitar Desplazar borde amarillo Degradado
- 7. Cómo agregar relleno al degradado <shape> en Android?
- 8. Android - Cómo dibujar un degradado basado en arco
- 9. Crear un relleno de degradado para texto usando [UIColor colorWithPatternImage:]
- 10. Eliminar degradado en UINavigationBar
- 11. Cómo pintar un degradado de color en Android en un lienzo con el cambio de color?
- 12. Cómo agregar un atributo de tema a android: startColor en degradado dibujable en Android?
- 13. Estilo de UITableViewCells con fondos de degradado
- 14. CSS (quizás con brújula): degradado entre exploradores
- 15. Redondeado rect con color de degradado
- 16. ¿Cómo hacer un degradado transparente?
- 17. Cómo crear un objeto degradado con Raphael
- 18. Hacer triángulo CSS3 con degradado lineal
- 19. crear una flecha con color de degradado
- 20. Degradado rectangular con elemento de lienzo HTML5
- 21. Texto grande en Android
- 22. Crear un degradado radial programáticamente
- 23. Máscara de degradado en UIView
- 24. WPF degradado en 2 direcciones
- 25. Degradado lineal multicolor en WinForms
- 26. centro de texto se alinean con Android
- 27. Artículo de Android ActionBar con solo texto
- 28. Botón con texto Y una imagen (Android)
- 29. CSS validación fondo degradado
- 30. Rellenar un trazado con un degradado en iOS
Hola, ¿puedes agregar un poco más de código a esta respuesta? Específicamente, el resto del diseño que se extiende BoringLayout clase. gracias – ekatz
I enlace a BoringLayout que debe incluirse en el SDK – Casebash