मैं एक संपादन टेक्स्ट में प्रत्येक वर्ण के लिए क्लिक करने योग्य स्पैन सेट करना चाहता हूं, लेकिन उनकी स्थिति प्रत्येक पंक्ति के अंत में वर्ण से मेल नहीं खाती है।

ब्रेकइटरेटर का उपयोग करके प्रत्येक अक्षर में एक क्लिक करने योग्य स्पैन सेट होता है। प्रत्येक क्लिक करने योग्य क्लिक किए गए अक्षर को दिखाते हुए एक अलर्टडिअलॉग खोलता है। यदि पत्र पंक्ति के अंत में नहीं है तो यह ठीक काम करता है। एक रेड क्रॉस क्लिक स्थिति दिखाता है:

लाइन के बीच में क्लिक किया गया 'एस' ठीक काम करता है:

लेकिन, किसी पंक्ति के अंत में अक्षरों पर क्लिक करने से पिछले अक्षर का ClickableSpan सक्रिय हो जाता है:

'Y' पर क्लिक किया गया था लेकिन 'X' क्लिक करने योग्य स्पैन सक्रिय था:

और अगली पंक्ति के पहले अक्षर के ठीक पहले वाले क्षेत्र में क्लिक करने से पिछली पंक्ति का अंतिम अक्षर सक्रिय हो जाएगा:

'Z' क्लिक के ठीक पहले का क्षेत्र, और पिछली लाइन का 'X' सक्रिय:

मैं क्लिक करने योग्य स्पैन को लाइनों के अंत में सही स्थिति में कैसे प्राप्त कर सकता हूं?

जावा कोड:

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);
    EditText et = findViewById(R.id.editText);
    et.setText("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abc");

    String text = et.getText().toString();
    et.setMovementMethod(LinkMovementMethod.getInstance());
    Spannable spannable = et.getText();

    BreakIterator iterator = BreakIterator.getCharacterInstance();
    iterator.setText(text);
    int iteratorStart = iterator.first();
    for (int iteratorEnd = iterator.next(); iteratorEnd != BreakIterator.DONE;
         iteratorStart = iteratorEnd, iteratorEnd = iterator.next()) {
        String letter = text.substring(iteratorStart, iteratorEnd);
        ClickableSpan cs = generateClickableSpan(letter);
        spannable.setSpan(cs, iteratorStart, iteratorEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
}


private ClickableSpan generateClickableSpan(final String letter) {
    return new ClickableSpan() {
        final String currentLetter;

        {
            currentLetter = letter;
        }

        @Override
        public void onClick(View widget) {
            AlertDialog.Builder adBuilder = new AlertDialog.Builder(MainActivity.this);
            AlertDialog ad = adBuilder.create();
            ad.setMessage(letter);
            ad.show();
            TextView tv = ad.findViewById(android.R.id.message);
            tv.setTextSize(24);
            ad.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
        }

        public void updateDrawState(TextPaint ds) {
            ds.setUnderlineText(false);
        }
    };
}

संपादित टेक्स्ट एक्सएमएल:

<EditText
            android:id="@+id/editText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:background="#00000000"
            android:inputType="none"
            android:textIsSelectable="true"
            android:layout_gravity="top"
            android:textSize="42sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

मैंने कस्टम LinkMovementMethod क्लास बनाने सहित निम्नलिखित उत्तरों में समाधान और सुझावों का प्रयास किया है लेकिन कुछ भी काम नहीं किया है:

टेक्स्ट कॉल के अंत तक संपादन टेक्स्ट में क्लिक करने योग्य अवधि क्लिक करें () लाइन के अंत तक

क्लिक करने योग्य स्पैन अजीब व्यवहार: खाली स्थान पर क्लिक करते समय ऑनक्लिक () कहा जाता है

धन्यवाद!!

1
guess who's got a new shovel 29 नवम्बर 2019, 21:52

1 उत्तर

मैं इसे दूसरे लिंक का उपयोग करके हल करता हूं, क्योंकि बफर को एक ही ऑफसेट के साथ दो लिंक मिल सकते हैं।

public static class MySpanMovementMethod extends LinkMovementMethod {

        @Override
        public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
            int action = event.getAction();

            if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
                int x = (int) event.getX();
                int y = (int) event.getY();

                x -= widget.getTotalPaddingLeft();
                y -= widget.getTotalPaddingTop();

                x += widget.getScrollX();
                y += widget.getScrollY();

                Layout layout = widget.getLayout();
                int line = layout.getLineForVertical(y);
                int off = layout.getOffsetForHorizontal(line, x);
                int end = layout.getLineEnd(line);

                Log.i(TAG, "tts span " + line + "=" + off + "=" + end);

                if (off >= widget.getText().length()) {
                    // Return true so click won't be triggered in the leftover empty space
                    return true;
                }
                TtsClickSpan[] links = buffer.getSpans(off, off, TtsClickSpan.class);

                if (links != null && links.length > 1) {

                    if (action == MotionEvent.ACTION_UP) {
                        links[1].onClick(widget);
                    }
                    return true;
                }

            }

            return super.onTouchEvent(widget, buffer, event);
        }
    }
0
hyand 26 फरवरी 2020, 06:29