2014-04-02 11 views
12

Sto cercando aggiungere funzionalità di copia incolla sul testo view.I hanno aggiunto nel codice registerForContextMenu(detailedText); e anche android:textIsSelectable="true" in xml. Quando cerco di copiarlo funziona bene, ma quando si punta sulla prima posizione della vista del testo, e di quando proviamo a selezionare il testo, genera un errore. Che ho mostrato di seguito. Come posso risolverlo ? mi aiuti per favore.errore quando si seleziona il testo da TextView (java.lang.IndexOutOfBoundsException: setSpan (-1 ... -1) inizia prima 0)

XML

<TextView 
      android:id="@+id/datailtext" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:textIsSelectable="true" 
      android:layout_below="@+id/EMPTY" 
      android:text="@string/detailed_text"  
      /> 

errore

04-02 16:54:03.367: E/AndroidRuntime(10977): FATAL EXCEPTION: main 
    04-02 16:54:03.367: E/AndroidRuntime(10977): Process: com.example.app, PID: 10977 
    04-02 16:54:03.367: E/AndroidRuntime(10977): java.lang.IndexOutOfBoundsException: setSpan (-1 ... -1) starts before 0 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.text.SpannableStringInternal.checkRange(SpannableStringInternal.java:355) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.text.SpannableStringInternal.setSpan(SpannableStringInternal.java:77) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.text.SpannableString.setSpan(SpannableString.java:46) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.text.Selection.setSelection(Selection.java:76) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.widget.Editor$SelectionEndHandleView.updateSelection(Editor.java:3479) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.widget.Editor$HandleView.positionAtCursorOffset(Editor.java:3167) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.widget.Editor$SelectionEndHandleView.updatePosition(Editor.java:3494) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.widget.Editor$HandleView.onTouchEvent(Editor.java:3260) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.View.dispatchTouchEvent(View.java:7690) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.View.dispatchPointerEvent(View.java:7870) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3919) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3808) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3406) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3456) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3425) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3510) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3433) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3567) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3406) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3456) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3425) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3433) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3406) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5520) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5500) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5471) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5594) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:182) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:174) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:5573) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:5613) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.Choreographer.doCallbacks(Choreographer.java:562) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.Choreographer.doFrame(Choreographer.java:530) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.os.Handler.handleCallback(Handler.java:733) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.os.Handler.dispatchMessage(Handler.java:95) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.os.Looper.loop(Looper.java:137) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at android.app.ActivityThread.main(ActivityThread.java:4998) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at java.lang.reflect.Method.invokeNative(Native Method) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at java.lang.reflect.Method.invoke(Method.java:515) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:777) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:593) 
    04-02 16:54:03.367: E/AndroidRuntime(10977): at dalvik.system.NativeStart.main(Native Method) 

Codice Aggiornamento

bene, voglio implementare la funzionalità di copia incolla in mostra il testo Android 2.3, l'ho fatto lontano nel codice, ho dettagliato di seguito. Any migliore su ggestion per l'implementazione in Android 2.3, per favore aiutatemi.

detailedText.setOnLongClickListener(new OnLongClickListener() { 

     @SuppressLint("NewApi") 
     @Override 
     public boolean onLongClick(View v) { 
      // TODO Auto-generated method stub 

      Log.d("LOG", "Detail text long pressed"); 

      int startIndex = detailedText.getSelectionStart(); 
      int endIndex = detailedText.getSelectionEnd(); 

      Log.d("LOG","startIndex "+ startIndex + "endIndex " + endIndex);///here get index -1 ,-1 for startIndex and endIndex in less than android 4.4 i dont know why? 


      String YouExtracted = stringYouExtracted.substring(startIndex,endIndex); 

      int sdk = android.os.Build.VERSION.SDK_INT; 
      if (sdk < android.os.Build.VERSION_CODES.HONEYCOMB) { 
       android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); 
       clipboard.setText(detailedText.getText().toString()); 
      } else { 
       android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); 
       android.content.ClipData clip = android.content.ClipData 
         .newPlainText("COPYTEXT", detailedText.getText().toString()); 
       clipboard.setPrimaryClip(clip); 
      } 
      return true; 
     } 
    }); 

    setupSocialNetworkingLinks(); 
} 

/*@Override 
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 
    //user has long pressed your TextView 
    menu.add(0, v.getId(), 0, "COPYTEXT"); 

    //cast the received View to TextView so that you can get its text 
    TextView yourTextView = (TextView) detailedText; 

    int startIndex = detailedText.getSelectionStart(); 
    int endIndex = detailedText.getSelectionEnd(); 
    String YouExtracted = detailedText.getText().toString(); 

    //place your TextView's text in clipboard 
    if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB) { 
     android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); 
     clipboard.setText(YouExtracted); 
    } else { 
     android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); 
     android.content.ClipData clip = android.content.ClipData.newPlainText("COPYING", YouExtracted); 
     clipboard.setPrimaryClip(clip); 
    } 
} 
*/ 
+0

dalla documentazione: 'Restituisce l'offset del ancoraggio selezione o il cursore, oppure -1 se non v'è alcuna selezione o il cursore. ' – donfuxx

+0

Ho provato su Android 4.4' getSelectionStart(); 'e' getSelectionEnd(); 'restituisce valori, ma altri dispositivi come dispositivo Android 4.1.1 lo restituiscono -1 –

+0

hai mai risolto questo? – AndroidEnthusiast

risposta

3

È un po 'tardi, ma stai usando un LinkMovementMethod personalizzato? Ho scoperto la stessa eccezione, ma non appena commento il setCustomMovementMethod, l'eccezione scompare.

Non so perché questo accade ancora.

+0

Qualcuno ha qualche idea sul perché questo si verifica? Non riesco a riprodurlo su un Nexus 5 ma i crash report mostrano che ciò accade su 2 dispositivi Sony (4.4.4 e 4.4.2) – darnmason

+1

Ho risolto questo problema restituendo "true" invece di restituire "return super.onTouchEvent (widget, buffer , evento); " Ma non so ancora perché questo succede ... – freg

+0

Grazie mille @freg, funziona per me. Cambiamento molto piccolo ma efficace. –

2

Ho avuto lo stesso problema con la selezione del testo in TextView. È eventuno, poiché TextView usa SpannableString, ma il metodo statico Selected.getSelectionStart (testo CharSequence) restituisce -1 se il testo non è l'istanza di Spanning. Risolvo (e https://code.google.com/p/android/issues/detail?id=191430 per Android 6) ovveride dispatchTouchEvent come questo:

public class HackyTextView extends TextView { 

    ... 

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