Pytanie Błąd podczas wybierania tekstu z widoku tekstowego (java.lang.IndexOutOfBoundsException: setSpan (-1 ... -1) rozpoczyna się przed 0)


Próbuję dodać funkcję wklejania kopii na widok tekstu. Dodałem w kodzie registerForContextMenu(detailedText); i również android:textIsSelectable="true" w xml. Kiedy próbuję skopiować, działa dobrze, ale kiedy wskazywał na pierwszą pozycję w widoku tekstowym, a następnie próbujemy wybrać tekst, który powoduje błąd, co pokazano poniżej. jak mogę to rozwiązać? proszę pomóż mi.

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"      
            />

Błąd

    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)

Zaktualizuj kod

Cóż, chcę zaimplementować funkcję kopiowania wklejania w widoku tekstowym Android 2.3, zrobiłem do tej pory w kodzie, szczegółowo poniżej. Jakieś lepsze sugestie do wdrożenia w Androidzie 2.3? Pomóżcie mi.

  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);
    }
}
*/

13
2018-04-02 11:35


pochodzenie


z dokumentacji: Return the offset of the selection anchor or cursor, or -1 if there is no selection or cursor. - donfuxx
Testowałem w systemie Android 4.4 getSelectionStart(); i getSelectionEnd(); zwraca wartości, ale inne urządzenie, takie jak urządzenie z Androidem 4.1.1, zwraca je -1 - Mayur Raval
Czy kiedykolwiek rozwiązałeś to? - AndroidEnthusiast
@AndroidEnthusiast, Przepraszam, jeszcze nie - Mayur Raval
Związane z: Czy można wybrać TextView I zawierać linki? - blahdiblah


Odpowiedzi:


Trochę za późno, ale czy używasz niestandardowego LinkMovementMethod? Odkryłem ten sam wyjątek, ale gdy tylko skomentuję metodę setCustomMovementMethod, wyjątek zniknie.

Nie wiem, dlaczego tak się dzieje.


3
2017-07-29 13:08



Ktoś ma jakiś wgląd w to, dlaczego tak się dzieje? Nie mogę go odtworzyć na nexusie 5, ale raporty o awariach pokazują, że dzieje się to na 2 urządzeniach Sony (4.4.4 i 4.4.2) - darnmason
Rozwiązałem to, zwracając "true" zamiast zwracając "return super.onTouchEvent (widget, buffer, event);" Ale nadal nie wiem, dlaczego tak się dzieje ... - freg
Wielkie dzięki @freg, to działa dla mnie. Bardzo mała, ale skuteczna zmiana. - Kuldeep Sakhiya


Miałem ten sam problem z wyborem tekstu w TextView. Jest to eventuate, ponieważ TextView używa SpannableString, ale statyczna metoda Selected.getSelectionStart (tekst CharSequence) zwraca -1, jeśli tekst nie jest instancją Spanned. Ja to rozwiązuję (i https://code.google.com/p/android/issues/detail?id=191430 dla Androida 6) ovveride dispatchTouchEvent w ten sposób:

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);
    }
}

3
2018-04-20 09:59