2015-11-20 27 views
9

Si è verificato un arresto anomalo durante la deselezione del testo in un TextView Android selezionabile. Questo accade quando creo una TextView selezionabile e setto LinkMovementMethod.IllegalArgumentException durante la selezione del testo in Android TextView

IllegalArgumentException in TextView

Sembra che sia un bug all'interno di Android.

java.lang.IllegalArgumentException: Invalid offset: -1. Valid range is [0, 10562] 
    at android.text.method.WordIterator.checkOffsetIsValid(WordIterator.java:380) 
    at android.text.method.WordIterator.isBoundary(WordIterator.java:101) 
    at android.widget.Editor$SelectionStartHandleView.positionAtCursorOffset(Editor.java:4260) 
    at android.widget.Editor$HandleView.updatePosition(Editor.java:3708) 
    at android.widget.Editor$PositionListener.onPreDraw(Editor.java:2507) 
    at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:944) 
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2055) 
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107) 
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013) 
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858) 
    at android.view.Choreographer.doCallbacks(Choreographer.java:670) 
    at android.view.Choreographer.doFrame(Choreographer.java:606) 
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844) 
    at android.os.Handler.handleCallback(Handler.java:739) 
    at android.os.Handler.dispatchMessage(Handler.java:95) 
    at android.os.Looper.loop(Looper.java:148) 
    at android.app.ActivityThread.main(ActivityThread.java:5417) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

risposta

10

Grazie mariotaku per la risposta. Per qualche motivo, non sono io che seleziono il testo nel mio TextView. L'ho ottimizzato un po 'per attivare il lavoro solo quando alcuni personaggi sono selezionati. Sembra che funzioni alla grande ora!

@Override 
public boolean dispatchTouchEvent(MotionEvent event) { 
    // FIXME simple workaround to https://code.google.com/p/android/issues/detail?id=191430 
    int startSelection = getSelectionStart(); 
    int endSelection = getSelectionEnd(); 
    if (startSelection != endSelection) { 
     if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { 
      final CharSequence text = getText(); 
      setText(null); 
      setText(text); 
     } 
    } 
    return super.dispatchTouchEvent(event); 
} 
+0

Questo mi ha salvato la vita! Molte grazie! – Arreis

+0

Anche io sto affrontando il problema simile, dove devo mantenere questo metodo. – vijaypalod

+1

hey @mVJ. È necessario estendere TextView come risposta di mariotaku qui sotto. Basicamente guarda la sua risposta ma sostituisce il metodo dispatchTouchEvent al suo interno. Quello sarebbe un nuovo file nel tuo progetto chiamato FixedTextView (o qualsiasi altra cosa tu voglia chiamare) e tu faresti riferimento invece del TextView predefinito – TrevorSStone

3

ho trovato Android sarà chiaro selezione TextView quando si chiama setText, quindi ecco una semplice soluzione a questo problema.

public class FixedTextView extends TextView { 

    public FixedTextView(final Context context) { 
     super(context); 
    } 

    public FixedTextView(final Context context, final AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public FixedTextView(final Context context, final AttributeSet attrs, final int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    @Override 
    public boolean dispatchTouchEvent(MotionEvent event) { 
     // FIXME simple workaround to https://code.google.com/p/android/issues/detail?id=191430 
     if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { 
      final CharSequence text = getText(); 
      setText(null); 
      setText(text); 
     } 
     return super.dispatchTouchEvent(event); 
    } 

} 
0

Ecco una semplice soluzione perfettamente funzionante. Dovresti metterlo nella tua classe di attività:

@Override 
public void onActionModeStarted(ActionMode mode) { 
    super.onActionModeStarted(mode); 
    yourTextView.setMovementMethod(ArrowKeyMovementMethod.getInstance()); 
} 

@Override 
public void onActionModeFinished(ActionMode mode) { 
    super.onActionModeFinished(mode); 
    yourTextView.setMovementMethod(LinkMovementMethod.getInstance()); 
} 
Problemi correlati