Estilo EditarTexto de contenido 'sobre la marcha'?

Estoy trabajando en un editor de texto enriquecido en Android. Básicamente tiene negrita, cursiva y botones de enlace que están vinculados a un EditText para cambiar el estilo del contenido. Lo hago funcionar muy bien si selecciona el texto que desea diseñar primero y, a continuación, seleccione el botón que utiliza este método: http://developer.android.com/guide/appendix/faq/commontasks.html#selectingtext .

Lo que estoy tratando de hacer es hacer que funcione como un editor de texto enriquecido, donde puede utilizar los botones como un toggle para el estilo del texto durante el tiempo que desee, a continuación, haga clic en el alternar de nuevo para dejar de usar el estilo. Así que si yo quería escribir ' Preste atención a esto! 'En negrita, hago clic en el botón' B ', luego empiezo a escribir el texto y todo lo que escribo estará en negrita hasta que vuelva a hacer clic en el botón' B '.

¿Ideas sobre cómo sacar esto? Espero haber sido lo suficientemente claro 🙂

Podría actualizar el estilo después de cada carácter que escriba usando un TextWatcher y el método addTextChangedListener() .

Ok, este es sólo el código de ejemplo de huesos desnudos.

 int mStart = -1; // Bold onClickListener public void onClick(View view) { if(mStart == -1) mStart = mEditText.getText().length(); else mStart = -1; } // TextWatcher onTextChanged(CharSequence s, int start, int before, int count) { if(mStart > 0) { int end = mEditText.getText().length(); mEditText.getText().setSpan(new StyleSpan(android.graphics.Typeface.BOLD), mStart, end - mStart, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } 

Para ésos interesados, conseguí esto para trabajar ahorrando la localización del cursor ('styleStart' variable abajo) cuando el ToggleButton fue presionado, y entonces como el usuario mecanografía más caracteres, realmente quito el StyleSpan que hace juego con removeSpan () Agregue de nuevo con setSpan () utilizando la ubicación original del cursor guardada + la longitud de los caracteres que se escriben actualmente.

También debe realizar un seguimiento si el usuario cambia la posición del cursor para que no estilice el texto que no desea. Aquí está el código de TextWatcher:

 final EditText contentEdit = (EditText) findViewById(R.id.content); contentEdit.addTextChangedListener(new TextWatcher() { public void afterTextChanged(Editable s) { //add style as the user types if a toggle button is enabled ToggleButton boldButton = (ToggleButton) findViewById(R.id.bold); ToggleButton emButton = (ToggleButton) findViewById(R.id.em); ToggleButton bquoteButton = (ToggleButton) findViewById(R.id.bquote); ToggleButton underlineButton = (ToggleButton) findViewById(R.id.underline); ToggleButton strikeButton = (ToggleButton) findViewById(R.id.strike); int position = Selection.getSelectionStart(contentEdit.getText()); if (position < 0){ position = 0; } if (position > 0){ if (styleStart > position || position > (cursorLoc + 1)){ //user changed cursor location, reset styleStart = position - 1; } cursorLoc = position; if (boldButton.isChecked()){ StyleSpan[] ss = s.getSpans(styleStart, position, StyleSpan.class); for (int i = 0; i < ss.length; i++) { if (ss[i].getStyle() == android.graphics.Typeface.BOLD){ s.removeSpan(ss[i]); } } s.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), styleStart, position, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } if (emButton.isChecked()){ StyleSpan[] ss = s.getSpans(styleStart, position, StyleSpan.class); boolean exists = false; for (int i = 0; i < ss.length; i++) { if (ss[i].getStyle() == android.graphics.Typeface.ITALIC){ s.removeSpan(ss[i]); } } s.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), styleStart, position, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } if (bquoteButton.isChecked()){ QuoteSpan[] ss = s.getSpans(styleStart, position, QuoteSpan.class); for (int i = 0; i < ss.length; i++) { s.removeSpan(ss[i]); } s.setSpan(new QuoteSpan(), styleStart, position, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } if (underlineButton.isChecked()){ UnderlineSpan[] ss = s.getSpans(styleStart, position, UnderlineSpan.class); for (int i = 0; i < ss.length; i++) { s.removeSpan(ss[i]); } s.setSpan(new UnderlineSpan(), styleStart, position, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } if (strikeButton.isChecked()){ StrikethroughSpan[] ss = s.getSpans(styleStart, position, StrikethroughSpan.class); for (int i = 0; i < ss.length; i++) { s.removeSpan(ss[i]); } s.setSpan(new StrikethroughSpan(), styleStart, position, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } } public void beforeTextChanged(CharSequence s, int start, int count, int after) { //unused } public void onTextChanged(CharSequence s, int start, int before, int count) { //unused } }); 

Y aquí está una de las acciones de clic ToggleButton:

 final ToggleButton boldButton = (ToggleButton) findViewById(R.id.bold); boldButton.setOnClickListener(new Button.OnClickListener() { public void onClick(View v) { EditText contentText = (EditText) findViewById(R.id.content); int selectionStart = contentText.getSelectionStart(); styleStart = selectionStart; int selectionEnd = contentText.getSelectionEnd(); if (selectionStart > selectionEnd){ int temp = selectionEnd; selectionEnd = selectionStart; selectionStart = temp; } if (selectionEnd > selectionStart) { Spannable str = contentText.getText(); StyleSpan[] ss = str.getSpans(selectionStart, selectionEnd, StyleSpan.class); boolean exists = false; for (int i = 0; i < ss.length; i++) { if (ss[i].getStyle() == android.graphics.Typeface.BOLD){ str.removeSpan(ss[i]); exists = true; } } if (!exists){ str.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), selectionStart, selectionEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } boldButton.setChecked(false); } } }); 

Puede haber una mejor solución, feliz de oír si usted tiene uno!

Sólo una posibilidad, no está seguro de que es la mejor solución, pero es lo que viene a la mente, y quién sabe, pero que le inspirará a una solución más elegante:

Tal vez usted podría considerar internamente el seguimiento de una estructura de estilo jerárquico del "documento", con todas sus etiquetas de estilo, y reconstruir / reemplazar la salida final con cada carácter escrito? Por supuesto usted tendrá que seguir la posición del cursor también.

Hay un editor de texto de código abierto EditText llamado android-richtexteditor pero el código fue inexplicablemente eliminado en r5. El código todavía está allí en versiones anteriores; Solo usa svn para salir r4 o antes para acceder a ella. El código aparece para dar soporte a cursivas, subrayado, selector de color, tamaño de texto y más.

También respondió en estas preguntas: 1 , 2

Sé que esto es un hilo viejo, pero mi compañero de trabajo vio DroidWriter en la web. He jugado con él un poco y es bastante auto explicativo y muy fácil de usar y modificar. Espero que esto ayude a cualquiera que esté buscando crear un editor de texto enriquecido.

  • Variables de miembro vs setArguments en Fragments
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.