style - textappearance android
Estilo Editar el contenido de texto ''sobre la marcha''? (5)
Hay un editor de texto enriquecido EditText de código abierto llamado android-richtexteditor, pero el código fue inexplicablemente eliminado en r5. El código todavía está allí en revisiones antiguas; simplemente use svn para verificar r4 o anterior para acceder a él. El código parece ser compatible con cursiva, subrayado, selector de color, tamaño de texto y más.
También respondió en estas preguntas: 1 , 2
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 primero selecciona el texto que desea diseñar y luego selecciona el botón con este método: http://developer.android.com/guide/appendix/faq/commontasks.html#selectingtext .
Lo que intento hacer es hacer que funcione como un editor de texto enriquecido, donde puede usar los botones para alternar el estilo del texto durante el tiempo que desee, luego haga clic en el botón de alternar para dejar de usar el estilo. Entonces, si quisiera escribir ''¡ Pon atención a esto! ''en negrita, haría clic en el botón'' B '', luego comenzaría a escribir el texto y todo lo que escriba estará en negrita hasta que vuelva a hacer clic en el botón'' B ''.
¿Alguna idea sobre cómo llevarlo a cabo? Espero haber sido lo suficientemente claro :)
Para los interesados, conseguí que esto funcione al guardar la ubicación del cursor (variable ''styleStart'' a continuación) cuando se presionó ToggleButton, y luego, a medida que el usuario escribe más caracteres, en realidad elimino el StyleSpan coincidente con removeSpan (), luego agréguelo de nuevo con setSpan () utilizando la ubicación del cursor original guardada + la longitud de los caracteres actualmente escritos.
También necesita rastrear si el usuario cambia la posición del cursor para no darle un estilo al 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 esta es una de las acciones de clic de 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 solución mejor, feliz de escucharla si tienes una!
Sé que este es un hilo viejo, pero mi compañero de trabajo detectó DroidWriter en la web. He jugado un poco con esto y es bastante explicativo y muy fácil de usar y modificar. Espero que esto ayude a cualquiera que busque crear un editor de texto enriquecido.
Solo una posibilidad, no estoy seguro de que sea la mejor solución, pero es lo que viene a la mente, y quién sabe, pero que te inspirará a una solución más elegante:
¿Tal vez podría considerar realizar un seguimiento interno de una estructura de estilo jerárquica del "documento", con todas sus etiquetas de estilo, y reconstruir / reemplazar el resultado final con cada carácter escrito? Por supuesto, también tendrá que seguir la posición del cursor.
Podrías simplemente actualizar el estilo después de cada personaje que TextWatcher
usando un TextWatcher
y el método addTextChangedListener()
.
Ok, este es solo el código de ejemplo básico.
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);
}
}