cómo hacer un texto específico en TextView BOLD

No sé cómo convertir un texto específico en TextView en BOLD.

Es como esto

txtResult.setText(id+" "+name); 

Quiero que la salida sea así:

1111 neil

id y name son variables que he recuperado el valor de la base de datos, y quiero hacer que el id esté en negrita, pero solo la id para que el name no se vea afectado, no tengo ni idea de cómo hacerlo.

Simplemente crea tu String en HTML y configúralo:

 String sourceString = "" + id + " " + name; mytextview.setText(Html.fromHtml(sourceString)); 

Si bien puedes usar Html.fromHtml () puedes usar un enfoque más nativo que sea SpannableStringBuilder , esta publicación puede ser útil.

 SpannableStringBuilder str = new SpannableStringBuilder("Your awesome text"); str.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.BOLD), INT_START, INT_END, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); TextView tv=new TextView(context); tv.setText(str); 

Pensé que la respuesta elegida no proporcionaba un resultado satisfactorio. He escrito mi propia función que requiere 2 cadenas; El texto completo y la parte del texto que desea resaltar.

Devuelve un SpannableStringBuilder con ‘textToBold’ de ‘texto’ en negrita.

Encuentro la capacidad de hacer una subcadena negrita sin envolverla en tags útiles.

  /** * Makes a substring of a string bold. * @param text Full text * @param textToBold Text you want to make bold * @return String with bold substring */ public static SpannableStringBuilder makeSectionOfTextBold(String text, String textToBold){ SpannableStringBuilder builder=new SpannableStringBuilder(); if(textToBold.length() > 0 && !textToBold.trim().equals("")){ //for counting start/end indexes String testText = text.toLowerCase(Locale.US); String testTextToBold = textToBold.toLowerCase(Locale.US); int startingIndex = testText.indexOf(testTextToBold); int endingIndex = startingIndex + testTextToBold.length(); //for counting start/end indexes if(startingIndex < 0 || endingIndex <0){ return builder.append(text); } else if(startingIndex >= 0 && endingIndex >=0){ builder.append(text); builder.setSpan(new StyleSpan(Typeface.BOLD), startingIndex, endingIndex, 0); } }else{ return builder.append(text); } return builder; } 

Como dijo wtsang02, usar HTML es una costosa sobrecarga. Solo usa la solución nativa. Si no tiene que modificar la cadena, solo use SpannableString, no SpannableStringBuilder.

 String boldText = "id"; String normalText = "name"; SpannableString str = new SpannableString(boldText + normalText); str.setSpan(new StyleSpan(Typeface.BOLD), 0, boldText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); textView.setText(str); 

Primero: no necesita preocuparse por usar el código de rendimiento lento de la respuesta de Raghav Sood .

Segundo: no necesita escribir una función de extensión proporcionada por la respuesta de w3bshark cuando usa Kotlin.

Finnaly: Todo lo que necesita hacer es usar la biblioteca Kotlin android-ktx de Google:

 // Suppose id = 1111 and name = neil (just what you want). val s = SpannableStringBuilder() .bold { append(id) } .append(name) txtResult.setText(s) 

Produce: 1111 neil


ACTUALIZAR:

Porque creo que puede ayudar a alguien más y demostrar cuán lejos puedes llegar hasta aquí son más casos de uso.

  • Cuando necesite mostrar un texto con algunas partes en azul y cursiva:

     val myCustomizedString = SpannableStringBuilder() .color(blueColor, { append("A blue text ") }) .append("showing that ") .italic{ append("it is painless") } 
  • Cuando necesite mostrar un texto en negrita y cursiva:

      bold { italic { append("Bold and italic") } } 

En resumen, bold , append , color y italic son funciones de extensión para SpannableStringBuilder . Puede ver otras funciones de extensión en la documentación oficial , desde donde puede pensar en otras posibilidades.

Aquí hay una mejor solución si quiere hacer que el texto en negrita sea múltiple. He mejorado el código de Eitan. gracias Eitan.

 public static SpannableStringBuilder makeSectionOfTextBold(String text, String... textToBold) { SpannableStringBuilder builder = new SpannableStringBuilder(text); for (String textItem : textToBold) { if (textItem.length() > 0 && !textItem.trim().equals("")) { //for counting start/end indexes String testText = text.toLowerCase(Locale.US); String testTextToBold = textItem.toLowerCase(Locale.US); int startingIndex = testText.indexOf(testTextToBold); int endingIndex = startingIndex + testTextToBold.length(); if (startingIndex >= 0 && endingIndex >= 0) { builder.setSpan(new StyleSpan(Typeface.BOLD), startingIndex, endingIndex, 0); } } } return builder; } 

En caso de que quiera usar la cadena de XML, puede hacer algo como esto:

strings.xml

  bold! normal ]]>  

Código:

 textView.setText(Html.fromHtml(getString(R.string.test))); 

Basado en la respuesta de @mladj0ni, obtuve el siguiente código para que funcione. El problema es que si utiliza String.format , elimina el marcado HTML, por lo que debe escapar de los símbolos del paréntesis en strings.xml:

strings.xml:

Hello, %1$s! You have <b>%2$d new messages</b>.

code.java:

 String unspanned = String.format(Locale.US, "%s%s", getResources().getString(R.string. welcome_messages), 99); Spanned spanned; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { spanned = Html.fromHtml(unspanned, Html.FROM_HTML_MODE_LEGACY); } else { spanned = Html.fromHtml(unspanned); } textView.setText(spanned); 

Es más simple que SpannableStringBuilder. En cuanto al rendimiento, si solo muestra una cadena, el usuario no notará el milisegundo extra para analizarla.

Vea la documentación aquí .

Es simple cerrar el texto especificado como este por ejemplo "your text here:"

 ""Headquarters:"" Mooresville, North Carolina, US 

resultado: Sede: Mooresville, Carolina del Norte, EE. UU.

Vine aquí para ofrecer una solución más actualizada, porque no estaba satisfecho con las respuestas existentes. Necesitaba algo que funcionara para textos traducidos y no tiene el impacto en el rendimiento de usar Html.fromHtml() . Si está usando Kotlin, aquí hay una función de extensión que establecerá fácilmente varias partes de su texto en negrita . Esto funciona igual que Markdown, y podría ampliarse para admitir otras tags Markdown, si fuera necesario.

 val yourString = "**This** is your **string**.".makePartialTextsBold() val anotherString = getString(R.string.something).makePartialTextsBold() /** * This function requires that the parts of the string that need * to be bolded are wrapped in ** and ** tags */ fun String.makePartialTextsBold(): SpannableStringBuilder { var copy = this return SpannableStringBuilder().apply { var setSpan = true var next: String do { setSpan = !setSpan next = if (length == 0) copy.substringBefore("**", "") else copy.substringBefore("**") val start = length append(next) if (setSpan) { setSpan(StyleSpan(Typeface.BOLD), start, length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) } copy = copy.removePrefix(next).removePrefix("**") } while (copy.isNotEmpty()) } } 

Creé un método estático para configurar una parte del texto Bold para TextView y EditText

 public static void boldPartOfText(View mView, String contentData, int startIndex, int endIndex){ if(!contentData.isEmpty() && contentData.length() > endIndex) { final SpannableStringBuilder sb = new SpannableStringBuilder(contentData); final StyleSpan bss = new StyleSpan(Typeface.BOLD); // Span to make text bold final StyleSpan iss = new StyleSpan(Typeface.NORMAL); //Span to make text normal sb.setSpan(iss, 0, startIndex, Spanned.SPAN_INCLUSIVE_INCLUSIVE); sb.setSpan(bss, startIndex, endIndex, Spannable.SPAN_INCLUSIVE_INCLUSIVE); // make first 4 characters Bold sb.setSpan(iss,endIndex, contentData.length()-1, Spanned.SPAN_INCLUSIVE_INCLUSIVE); if(mView instanceof TextView) ((TextView) mView).setText(sb); else if(mView instanceof EditText) ((EditText) mView).setText(sb); } } 

Otro código más personalizado

  /*typeFaceStyle can be passed as Typeface.NORMAL = 0; Typeface.BOLD = 1; Typeface.ITALIC = 2; Typeface.BOLD_ITALIC = 3;*/ public static void boldPartOfText(View mView, String contentData, int startIndex, int endIndex,int typeFaceStyle){ if(!contentData.isEmpty() && contentData.length() > endIndex) { final SpannableStringBuilder sb = new SpannableStringBuilder(contentData); final StyleSpan bss = new StyleSpan(typeFaceStyle); // Span to make text bold final StyleSpan iss = new StyleSpan(Typeface.NORMAL); //Span to make text italic sb.setSpan(iss, 0, startIndex, Spanned.SPAN_INCLUSIVE_INCLUSIVE); sb.setSpan(bss, startIndex, endIndex, Spannable.SPAN_INCLUSIVE_INCLUSIVE); // make first 4 characters Bold sb.setSpan(iss,endIndex,contentData.length()-1,Spanned.SPAN_INCLUSIVE_INCLUSIVE); if(mView instanceof TextView) ((TextView) mView).setText(sb); else if(mView instanceof EditText) ((EditText) mView).setText(sb); } } 

Haga que el primer carácter de cadena se pueda abrir mientras busca un objeto en la lista / reciclador como

r a vi y ajay

anteriormente destacando así, pero yo quería ser como a continuación

ravi y ajay o ravi y jay

para esto busqué la longitud de la palabra si es igual a 1, separé la cuerda principal en palabras y la posición de inicio de la palabra se calculó, luego busqué una palabra que comenzara con char.

  public static SpannableString colorString(int color, String text, String... wordsToColor) { SpannableString coloredString = new SpannableString(text); for (String word : wordsToColor) { Log.e("tokentoken", "-wrd len-" + word.length()); if (word.length() !=1) { int startColorIndex = text.toLowerCase().indexOf(word.toLowerCase()); int endColorIndex = startColorIndex + word.length(); try { coloredString.setSpan(new ForegroundColorSpan(color), startColorIndex, endColorIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } catch (Exception e) { e.getMessage(); } } else { int start = 0; for (String token : text.split("[\u00A0 \n]")) { if (token.length() > 0) { start = text.indexOf(token, start); // Log.e("tokentoken", "-token-" + token + " --start--" + start); char x = token.toLowerCase().charAt(0); char w = word.toLowerCase().charAt(0); // Log.e("tokentoken", "-w-" + w + " --x--" + x); if (x == w) { // int startColorIndex = text.toLowerCase().indexOf(word.toLowerCase()); int endColorIndex = start + word.length(); try { coloredString.setSpan(new ForegroundColorSpan(color), start, endColorIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } catch (Exception e) { e.getMessage(); } } } } } } return coloredString; } 
 public static Spanned getBoldString(String textNotBoldFirst, String textToBold, String textNotBoldLast) { String resultant = null; resultant = textNotBoldFirst + " " + "" + textToBold + "" + " " + textNotBoldLast; return Html.fromHtml(resultant); } 

Prueba esto. Puede ayudar definitivamente

Puede agregar las dos cadenas por separado en el generador, una de ellas es spannedString, la otra es una regular. De esta forma, no tiene que calcular los índices.

 val instructionPress = resources?.getString(R.string.settings_press) val okText = resources?.getString(R.string.ok) val spannableString = SpannableString(okText) val spannableBuilder = SpannableStringBuilder() spannableBuilder.append(instructionPress) spannableBuilder.append(spannableString, StyleSpan(Typeface.BOLD), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) instructionText.setText(spannableBuilder,TextView.BufferType.SPANNABLE) 

Aquí está mi solución completa para valores dynamics de cadenas con verificación de casos.

 /** * Makes a portion of String formatted in BOLD. * * @param completeString String from which a portion needs to be extracted and formatted.
eg. I am BOLD. * @param targetStringToFormat Target String value to format.
eg. BOLD * @param matchCase Match by target character case or not. If true, BOLD != bold * @return A string with a portion formatted in BOLD.
I am BOLD. */ public static SpannableStringBuilder formatAStringPortionInBold(String completeString, String targetStringToFormat, boolean matchCase) { //Null complete string return empty if (TextUtils.isEmpty(completeString)) { return new SpannableStringBuilder(""); } SpannableStringBuilder str = new SpannableStringBuilder(completeString); int start_index = 0; //if matchCase is true, match exact string if (matchCase) { if (TextUtils.isEmpty(targetStringToFormat) || !completeString.contains(targetStringToFormat)) { return str; } start_index = str.toString().indexOf(targetStringToFormat); } else { //else find in lower cases if (TextUtils.isEmpty(targetStringToFormat) || !completeString.toLowerCase().contains(targetStringToFormat.toLowerCase())) { return str; } start_index = str.toString().toLowerCase().indexOf(targetStringToFormat.toLowerCase()); } int end_index = start_index + targetStringToFormat.length(); str.setSpan(new StyleSpan(BOLD), start_index, end_index, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return str; }

P.ej. completeString = “Estoy ENOJADO”

CASO I si *targetStringToFormat* = "bold" y *matchCase* = true

devuelve “Soy INMENSO” (¡desde negrita! = NEGRITA)

CASO II si *targetStringToFormat* = "bold" y *matchCase* = false

devuelve “Estoy ENAMORADO

Aplicar:

 myTextView.setText(formatAStringPortionInBold("I am BOLD", "bold", false)) 

¡Espero que ayude!

si la posición del texto en negrita es fija (por ejemplo, si está al inicio de la vista de texto), utilice dos textView diferentes con el mismo fondo. Luego puede hacer que el textStyle de textView sea negrita.

Esto requerirá el doble de memoria en comparación con un solo textView pero la velocidad boostá.

Puede usar este código para configurar parte de su texto en negrita. Para lo que esté entre las tags html en negrita, lo hará en negrita.

 String myText = "make this bold and this too"; textView.setText(makeSpannable(myText, "(.+?)", "", "")); public SpannableStringBuilder makeSpannable(String text, String regex, String startTag, String endTag) { StringBuffer sb = new StringBuffer(); SpannableStringBuilder spannable = new SpannableStringBuilder(); Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(text); while (matcher.find()) { sb.setLength(0); String group = matcher.group(); String spanText = group.substring(startTag.length(), group.length() - endTag.length()); matcher.appendReplacement(sb, spanText); spannable.append(sb.toString()); int start = spannable.length() - spanText.length(); spannable.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.BOLD), start, spannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } sb.setLength(0); matcher.appendTail(sb); spannable.append(sb.toString()); return spannable; }