Come estendere TextView
per consentire il disegno del testo con un effetto sfumato?Testo con gradiente in Android
risposta
Non sembra possibile estendere TextView per disegnare il testo con una sfumatura. Tuttavia, è possibile ottenere questo effetto creando una tela e disegnandoci sopra. Per prima cosa dobbiamo declare our custom UI element. All'inizio è necessario creare una sottoclasse di Layout. In questo caso, useremo BoringLayout che supporta solo il testo con una sola riga.
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);
Abbiamo poi sovrascrivere onMeasure
e 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);
}
La nostra implementazione di onDraw
è a questo punto piuttosto pigro (ignora completamente le specifiche di misura !, ma fino a quando si garantisce che la vista è dato spazio sufficiente, dovrebbe funzionare ok
In alternativa, sarebbe possibile ereditare da un Canvas
e sovrascrivere il metodo onPaint
. Se questo è d uno, quindi sfortunatamente l'ancoraggio per il testo disegnato sarà sempre sul fondo quindi dobbiamo aggiungere -textPaint.getFontMetricsInt().ascent()
alla nostra coordinata y.
Una soluzione semplice ma un po 'limitata sarebbe quella di utilizzare questi attributi:
android:fadingEdge="horizontal"
android:scrollHorizontally="true"
ho usato su campi di testo dove voglio loro di fade out se ottengono troppo a lungo.
Questo è un bel trucco. Non credo che tu possa fare quel lavoro in verticale? Non c'è nessun androide: scrollVertically proprietà per quanto posso vedere – Casebash
Spiacente, non so come farlo :( – 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 per semplificare ed efficace –
Grazie per una soluzione molto semplice :) –
Sul mio dispositivo ICS, questo non sembra funzionare - - è completamente trasparente.Qualcun altro vede la stessa cosa? La vista non è accelerata dall'hardware. –
Ho arrotolato una libreria che racchiude entrambi questi metodi. Puoi creare GradientTextView in XML o semplicemente usare GradientTextView.setGradient (TextView textView ...) per farlo su un normale oggetto TextView.
Ecco un esempio per LinearLayout, è possibile utilizzare questo esempio per TextView troppo, e nel codice sorgente non ci sarà la codifica di pendenza, si ottiene il codice sorgente e aggiungere il codice da quel sito stesso - http://android-codes-examples.blogspot.com/2011/07/design-linearlayout-or-textview-and-any.html
Ecco un bel modo per farlo:
/**
* 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);
}
Inoltre, se si desidera utilizzare una bitmap del gradiente, invece o uno vero, l'uso:
/**
* 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);
}
Eccolo con il supporto multilinea come un solo rivestimento. Questo dovrebbe funzionare anche per i pulsanti.
textView.getPaint().setShader(new LinearGradient(0,0,0,textView.getLineHeight(), startColor, endColor, Shader.TileMode.REPEAT));
semplice e funziona eccellente !! –
Funziona, ma per l'altezza si potrebbe voler prendere in considerazione le lettere che vanno al di sotto della linea attuale (come y, g, j, ecc.) E moltiplicare la altezza della linea per 1,10f, ad es. 'textView.getLineHeight() * 1.10f'. –
- 1. in gradiente Android
- 2. gradiente di testo css
- 3. Gradiente di testo con carattere impressionante
- 4. Android: sfondo gradiente AppBarLayout
- 5. Gradiente lucido con xml disegnabile Android
- 6. pulsante Android con doppio bordo e gradiente
- 7. android crea pie dount con gradiente
- 8. Android gradiente radiale
- 9. Gradiente con dissolvenza in CSS
- 10. Crea il bordo del gradiente in Android?
- 11. Maschera Alpha gradiente circolare Android
- 12. Gradiente radiale in XML con dimensione principale
- 13. Gradiente SVG con CSS
- 14. 9 patch convertita in gradiente
- 15. Riempi pannello con gradiente in tre colori
- 16. Android - Come disegnare un gradiente ad arco
- 17. effetto Sunburst con gradiente CSS3
- 18. Raphael.js percorso/linea con gradiente?
- 19. Genera un'immagine con testo personalizzato in Android
- 20. Discesa gradiente stocastica dall'implementazione della discesa del gradiente in R
- 21. Gradiente discesa in Java
- 22. Come visualizzare effetto gradiente dall'alto verso il basso in Android
- 23. Gradiente di colore del testo CSS3 puro - È possibile?
- 24. Testo Marquee in Android
- 25. UITableView con gradiente trasparente in alto e in basso
- 26. Android modalità testo testo in senso verticale
- 27. Gradiente di sfondo CSS con offset
- 28. Discesa gradiente batch con scikit learn (sklearn)
- 29. gradiente di sfondo con tinta unita
- 30. Crea triangolo CSS3 con gradiente lineare
Ciao, puoi aggiungere qualche altro codice a questa risposta? In particolare, il resto del layout di estensione di BoringLayout classe grazie! – ekatz
Collegamento a BoringLayout che dovrebbe essere incluso nell'SDK – Casebash