2012-04-21 17 views
8

Quiero implementar una interfaz de texto personalizada, con tocar y arrastrar seleccionar texto y no subir el teclado, en contraste con el comportamiento predeterminado de un clic largo que aparece el menú CCP y el teclado. Mi comprensión sugiere que necesito este enfoque:android: Cómo obtener la posición de texto desde el evento táctil

onTouchEvent(event){ 
    case touch_down: 
    get START text position 

    case drag 
    get END text position 
    set selection range from START to END 
} 

he descubierto todo sobre getSelectStart() y diversos métodos para establecer un rango y tal, pero no puedo encontrar la manera de obtener la posición del texto basado en un evento de toque getX() y getY(). ¿Hay alguna manera de hacer esto? He visto el comportamiento que quiero en otras aplicaciones de oficina.

Además, ¿cómo podría detener el teclado que aparece hasta que se solicite manualmente?

Respuesta

12

"mText.setInputType (InputType.TYPE_NULL)" suprimirá el teclado virtual, pero también deshabilita el cursor parpadeante en un cuadro Editar texto en Android 3.0 y superior. Codifiqué unTouchListener y devolví verdadero para deshabilitar el teclado y luego tuve que obtener la posición táctil del evento de movimiento para establecer el cursor en el lugar correcto. Es posible que pueda usar esto en un evento de movimiento ACTION_MOVE para seleccionar texto para arrastrar.

Aquí está el código que utilicé:

mText = (EditText) findViewById(R.id.editText1); 
    OnTouchListener otl = new OnTouchListener() { 
    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      Layout layout = ((EditText) v).getLayout(); 
      float x = event.getX() + mText.getScrollX(); 
      int offset = layout.getOffsetForHorizontal(0, x); 
      if(offset>0) 
       if(x>layout.getLineMax(0)) 
        mText.setSelection(offset);  // touch was at end of text 
       else 
        mText.setSelection(offset - 1); 
      break; 
      } 
     return true; 
     } 
    }; 
    mText.setOnTouchListener(otl); 
+2

i tiene Excepción de puntero nulo en la línea ::: "int desplazamiento = layout.getOffsetForHorizontal (0, x);" –

10

Gracias Waine Kail para compartir el código de inicio, pero sólo maneja el eje "x" del evento. Para multilínea EditarTexto, también debe:

1- Calcular la posición vertical (y):
2- Obtener la línea compensada por la posición vertical
3- Obtener el desplazamiento de texto usando la línea y la posición horizontal

EditText et = (EditText) findViewById(R.id.editText1); 

long offset = -1; //text position will be corrected when touching. 

et.setOnTouchListener(new OnTouchListener() { 

@Override 
public boolean onTouch(View v, MotionEvent event) { 
    switch (event.getAction()) { 
     case MotionEvent.ACTION_UP: 
      Layout layout = ((EditText) v).getLayout(); 
      float x = event.getX() + et.getScrollX(); 
      float y = event.getY() + et.getScrollY();    
      int line = layout.getLineForVertical((int) y);      

// Here is what you wanted: 

      offset = layout.getOffsetForHorizontal(line, x); 

      break; 
     } 
    return false; 
} 
}); 
+0

Gracias, ayúdenme ... :) – ADT

+0

Estoy obteniendo puntero nulo Excepción para el diseño, ¿por qué? no lo sé. – Dharmishtha

+0

para el diseño. He hecho algo como esto. ViewTreeObserver vto = edittext.getViewTreeObserver(); vto.addOnGlobalLayoutListener (nueva ViewTreeObserver.OnGlobalLayoutListener() {@ Override public void onGlobalLayout() { layout = edittext.getLayout();} }); – Dharmishtha

2

Para mi aplicación necesitaba posicionarme en un touchlistener pero la solución anterior parece no dar una ubicación precisa. Para mí, la mayoría de las veces estaba fuera de 1-2 caracteres en relación con el cursor de texto. El siguiente código resuelve esto. La clave para hacer que esto funcione es usar post() para posponer el código hasta después de que se haya actualizado la posición del cursor. Por lo tanto, la posición que obtengo está garantizada para estar de acuerdo con la de EditText, y el código también es más simple.

setOnTouchListener(new OnTouchListener() 
    { 
    @Override 
    public boolean onTouch(View view, MotionEvent event) 
     { 
     if(event.getAction()==MotionEvent.ACTION_UP) 
      { 
      //At this point the selection has not been updated. So post an 
      //event at the end of the event queue to check where cursor 
      //has been moved 
      post(new Runnable() 
       { 
       public void run() 
        { 
        Editable sb=getText(); 
        int currentPos=getSelectionStart(); 
        //TODO 
        } 
       }); 
      } 
     return false; 
     } 
    }); 
4

Estoy enfrentando el mismo problema también. Y cuando traté de usar "int offset = layout.getOffsetForHorizontal (0, x);" como Wayne Kail dijo, también consiguió NPE en esta línea. Así que he intentado y al final escribo de esta manera:

mText = (EditText) findViewById(R.id.editText1); 
OnTouchListener otl = new OnTouchListener() { 
    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     EditText editText = (EditText) v; 
     float x = event.getX(); 
     float y = event.getY(); 
     int touchPosition = editText.getOffsetForPosition(x, y); 
     if (touchPosition>0){ 
      editText.setSelection(touchPosition); 
     } 
     return true; 
    } 
}; 
mText.setOnTouchListener(otl); 
+0

no funcionó para mí. – Dharmishtha

Cuestiones relacionadas