iconos iconic icon font java android design icons

java - iconic - material icons font download



Contenido de Android Spannable con esquinas redondeadas (6)

Aquí está mi versión basada en la respuesta de @mvandillen. También necesité un margen al comienzo del lapso.

import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.RectF; import android.support.annotation.NonNull; import android.text.style.ReplacementSpan; public class CoolBackgroundColorSpan extends ReplacementSpan { private final int mBackgroundColor; private final int mTextColor; private final float mCornerRadius; private final float mPaddingStart; private final float mPaddingEnd; private final float mMarginStart; public CoolBackgroundColorSpan(int backgroundColor, int textColor, float cornerRadius, float paddingStart, float paddingEnd, float marginStart) { super(); mBackgroundColor = backgroundColor; mTextColor = textColor; mCornerRadius = cornerRadius; mPaddingStart = paddingStart; mPaddingEnd = paddingEnd; mMarginStart = marginStart; } @Override public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { return (int) (mPaddingStart + paint.measureText(text.subSequence(start, end).toString()) + mPaddingEnd); } @Override public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) { float width = paint.measureText(text.subSequence(start, end).toString()); RectF rect = new RectF(x - mPaddingStart + mMarginStart, top, x + width + mPaddingEnd + mMarginStart, bottom); paint.setColor(mBackgroundColor); canvas.drawRoundRect(rect, mCornerRadius, mCornerRadius, paint); paint.setColor(mTextColor); canvas.drawText(text, start, end, x + mMarginStart, y, paint); } }

Cómo utilizar:

int flag = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE; SpannableString staffTitleSpan = new SpannableString("staff: "); SpannableString staffNameSpan = new SpannableString("John Smith"); staffNameSpan.setSpan(new StyleSpan(Typeface.BOLD), 0, staffNameSpan.length(), flag); staffNameSpan.setSpan(new CoolBackgroundColorSpan(mStaffNameSpanBgColor, mStaffNameSpanTextColor, mStaffNameSpanBgRadius, mStaffNameSpanBgPaddingStart, mStaffNameSpanBgPaddingEnd, mStaffNameSpanMarginStart), 0, staffNameSpan.length(), flag); SpannableStringBuilder builder = new SpannableStringBuilder(); builder.append(staffTitleSpan); builder.append(staffNameSpan); staffTextView.setText(builder);

Avance:

Estoy tratando de cambiar mi cadena para hacer una insignia con un número en el medio usando Spannable String. Puedo resaltar la letra / número apropiado configurando BackGroundColorSpan, pero necesito ayuda para hacerlo un poco más bonito. Esperaba tener esquinas redondeadas con un poco de relleno alrededor de la forma completa.

Este artículo está muy cerca de lo que trato de hacer: Android SpannableString establece el fondo detrás de una parte del texto

Realmente necesito mantener el recurso como un TextView debido a la forma en que interactúa con mi aplicación.

¿Alguna idea de cómo utilizar ReplacementSpan para mi situación particular?

Aquí está mi fragmento de código:

if (menuItem.getMenuItemType() == SlidingMenuItem.MenuItemType.NOTIFICATIONS) { myMenuRow.setTypeface(null, Typeface.NORMAL); myMenuRow.setTextColor(getContext().getResources().getColor(R.color.BLACK)); myMenuRow.setActivated(false); SpannableString spannablecontent = new SpannableString(myMenuRow.getText()); spannablecontent.setSpan(new BackgroundColorSpan(Color.argb(150,0,0,0)), 18, myMenuRow.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); myMenuRow.setText(spannablecontent);


Aquí hay una versión mejorada basada en la respuesta de @ericlokness, con fondo personalizado y colores de texto. También funciona con múltiples tramos en el mismo TextView.

public class RoundedBackgroundSpan extends ReplacementSpan { private final int _padding = 20; private int _backgroundColor; private int _textColor; public RoundedBackgroundSpan(int backgroundColor, int textColor) { super(); _backgroundColor = backgroundColor; _textColor = textColor; } @Override public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { return (int) (_padding + paint.measureText(text.subSequence(start, end).toString()) + _padding); } @Override public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) { float width = paint.measureText(text.subSequence(start, end).toString()); RectF rect = new RectF(x - _padding, top, x + width + _padding, bottom); paint.setColor(_backgroundColor); canvas.drawRoundRect(rect, 20, 20, paint); paint.setColor(_textColor); canvas.drawText(text, start, end, x, y, paint); } }


De hecho, encontré grandes problemas con todas esas respuestas al mostrar varias líneas de insignias. Después de muchas pruebas y ajustes. Finalmente obtuve la mejor versión de la anterior.

La idea básica es engañar al TextView estableciendo un tamaño de texto mucho más grande y estableciendo el tamaño deseado dentro del lapso. Además, puede ver que dibujo el fondo y el texto de la insignia de manera diferente.

Entonces, este es mi RoundedBackgroundSpan:

public class RoundedBackgroundSpan extends ReplacementSpan { private static final int CORNER_RADIUS = 12; private static final float PADDING_X = GeneralUtils.convertDpToPx(12); private static final float PADDING_Y = GeneralUtils.convertDpToPx(2); private static final float MAGIC_NUMBER = GeneralUtils.convertDpToPx(2); private int mBackgroundColor; private int mTextColor; private float mTextSize; /** * @param backgroundColor color value, not res id * @param textSize in pixels */ public RoundedBackgroundSpan(int backgroundColor, int textColor, float textSize) { mBackgroundColor = backgroundColor; mTextColor = textColor; mTextSize = textSize; } @Override public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) { paint = new Paint(paint); // make a copy for not editing the referenced paint paint.setTextSize(mTextSize); // Draw the rounded background paint.setColor(mBackgroundColor); float textHeightWrapping = GeneralUtils.convertDpToPx(4); float tagBottom = top + textHeightWrapping + PADDING_Y + mTextSize + PADDING_Y + textHeightWrapping; float tagRight = x + getTagWidth(text, start, end, paint); RectF rect = new RectF(x, top, tagRight, tagBottom); canvas.drawRoundRect(rect, CORNER_RADIUS, CORNER_RADIUS, paint); // Draw the text paint.setColor(mTextColor); canvas.drawText(text, start, end, x + PADDING_X, tagBottom - PADDING_Y - textHeightWrapping - MAGIC_NUMBER, paint); } private int getTagWidth(CharSequence text, int start, int end, Paint paint) { return Math.round(PADDING_X + paint.measureText(text.subSequence(start, end).toString()) + PADDING_X); } @Override public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { paint = new Paint(paint); // make a copy for not editing the referenced paint paint.setTextSize(mTextSize); return getTagWidth(text, start, end, paint); } }

Y así es como lo estoy usando:

public void setTags(ArrayList<String> tags) { if (tags == null) { return; } mTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 26); // Tricking the text view for getting a bigger line height SpannableStringBuilder stringBuilder = new SpannableStringBuilder(); String between = " "; int tagStart = 0; float textSize = 13 * getResources().getDisplayMetrics().scaledDensity; // sp to px for (String tag : tags) { // Append tag and space after stringBuilder.append(tag); stringBuilder.append(between); // Set span for tag RoundedBackgroundSpan tagSpan = new RoundedBackgroundSpan(bgColor, textColor, textSize); stringBuilder.setSpan(tagSpan, tagStart, tagStart + tag.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // Update to next tag start tagStart += tag.length() + between.length(); } mTextView.setText(stringBuilder); }


Nota:

  • Puede jugar con todos los tamaños y constantes para adaptarse a su estilo deseado
  • Si usas una fuente externa, asegúrate de configurar android: includeFontPadding = "false"; de lo contrario, puede estropear la altura de la línea

Disfruta :)


Después de leer, obtener un poco de ayuda con un convertidor para C #, se me ocurrió esto. Todavía tengo que hacer algunos ajustes, pero si alguien también está buscando una respuesta similar.

public class RoundedBackgroundSpan extends ReplacementSpan { @Override public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { return 0; } @Override public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) { RectF rect = new RectF(x, top, x + text.length(), bottom); paint.setColor(Color.CYAN); canvas.drawRoundRect(rect, 20, 20, paint); paint.setColor(Color.WHITE); canvas.drawText(text, start, end, x, y, paint); } }


Mejore aún más la clase mvandillen.

Esto parece funcionar muy bien:

public class RoundedBackgroundSpan extends ReplacementSpan { private final int mPadding = 10; private int mBackgroundColor; private int mTextColor; public RoundedBackgroundSpan(int backgroundColor, int textColor) { super(); mBackgroundColor = backgroundColor; mTextColor = textColor; } @Override public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { return (int) (mPadding + paint.measureText(text.subSequence(start, end).toString()) + mPadding); } @Override public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) { float width = paint.measureText(text.subSequence(start, end).toString()); RectF rect = new RectF(x, top+mPadding, x + width + 2*mPadding, bottom); paint.setColor(mBackgroundColor); canvas.drawRoundRect(rect, mPadding, mPadding, paint); paint.setColor(mTextColor); canvas.drawText(text, start, end, x+mPadding, y, paint); } }


Ok, entonces la pregunta es un poco desordenada, aquí está mi solución de DanieleB y mvandillen.

public class RoundedBackgroundSpan extends ReplacementSpan { private static final int CORNER_RADIUS = 8; private static final int PADDING_X = 12; private int mBackgroundColor; private int mTextColor; /** * @param backgroundColor background color * @param textColor text color */ public RoundedBackgroundSpan(int backgroundColor, int textColor) { mBackgroundColor = backgroundColor; mTextColor = textColor; } @Override public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { return (int) (PADDING_X + paint.measureText(text.subSequence(start, end).toString()) + PADDING_X); } @Override public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) { float width = paint.measureText(text.subSequence(start, end).toString()); RectF rect = new RectF(x, top, x + width + 2 * PADDING_X, bottom); paint.setColor(mBackgroundColor); canvas.drawRoundRect(rect, CORNER_RADIUS, CORNER_RADIUS, paint); paint.setColor(mTextColor); canvas.drawText(text, start, end, x + PADDING_X, y, paint); } }

Consejo: puede eliminar el textColor y el usuario el color predeterminado de TextView:

@Override public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) { Paint paint1 = new Paint(paint); float width = paint1.measureText(text.subSequence(start, end).toString()); RectF rect = new RectF(x, top, x + width + 2 * PADDING_X, bottom); paint1.setColor(mBackgroundColor); canvas.drawRoundRect(rect, CORNER_RADIUS, CORNER_RADIUS, paint1); canvas.drawText(text, start, end, x + PADDING_X, y, paint); }