如何处理onClick事件上的imageSpan在editText



我正在一个应用程序中,用户从图库中选择一个图像,它将在editText中添加,现在我想如果用户点击editText中的图像,它应该在全屏打开,我使用下面的代码:-

public void addToEdt(Bitmap bitmap){
    SpannableString ss = new SpannableString("abc");
    Drawable d = new BitmapDrawable(getResources(), bitmap);
    d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
    ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
    ss.setSpan(span, 0, 3, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
    edt_note.setTransformationMethod(null);
    edt_note.getText().insert(edt_note.getSelectionStart(), ss);
    final int start = ss.getSpanStart(span);
    final int end = ss.getSpanEnd(span);
    ClickableSpan click_span = new ClickableSpan() {
        @Override
        public void onClick(View widget) {
                   Toast.makeText(getApplicationContext(),"Clicked",Toast.LENGTH_LONG).show();
        }
    };
    ClickableSpan[] click_spans = ss.getSpans(start, end,  ClickableSpan.class);
    if(click_spans.length != 0) {
        // remove all click spans
        for (ClickableSpan c_span : click_spans) {
            ss.removeSpan(c_span);
        }
    }
    ss.setSpan(click_span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}

尝试上面的代码,但它没有监听onClick事件,现在,我如何侦听该图像上的click事件并执行进一步的任务?

与editText的起始和结束位置相同的可点击Span。

sb.setSpan(cs, imageStartSpan,imageEndSpan , Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

editText.setMovementMethod(LinkMovementMethod.getInstance());

我不能为你写完整的代码。试试下面的例子:-

public void addToEdt(Bitmap bitmap){
    SpannableString ss = new SpannableString();
    Drawable d = new BitmapDrawable(getResources(), bitmap);
    d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
    ss.append("abc"); // Append the text here
    ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
    ss.setSpan(span, 0, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // start(0) and end (2) will create an image span over abc text
    ss.setSpan(new ClickableSpan() {
                @Override
                public void onClick(View widget) {
                    ss.delete(0, 2);
                    editText.setText(ss);
                }
            },0, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // this will add a clickable span and on click will delete the span and text
    editText.setText(ss); // this will show your image/clickable span in edittext
}

editText.setMovementMethod(LinkMovementMethod.getInstance());

考虑到ClickableSpansetMovementMethod引起的问题,我不认为使用它们是可以接受的。我不相信这些是打算在EditText控件中使用的。

另外,我需要知道用户在span中单击的位置。我的imagespan的右侧有一个X关闭按钮,我想知道用户是否点击了X,而不是仅仅点击了标签。

所以我找到了另一种方法:

  • 子类ImageSpan和覆盖draw方法只是调用super,但也存储在成员变量的x/y/left/top -所以,现在你知道在哪里span是定位在EditText。
  • 子类EditText和处理onTouchEvent只是调用super,但也得到你的跨度和点击测试每一个,以找出如果用户点击跨度(或跨度的一部分)。

Try

final int start = ss.getSpanStart(span);
final int end = ss.getSpanEnd(span);
ClickableSpan click_span = new ClickableSpan() {
    @Override
    public void onClick(View widget) {
    }
};
ClickableSpan[] click_spans = ss.getSpans(start, end, ClickableSpan.class);
if(click_spans.length != 0) {
    // remove all click spans
    for (ClickableSpan c_span : click_spans) {
        ss.removeSpan(c_span);
    }
}
ss.setSpan(click_span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

还要加上:

yourEditText.setMovementMethod(LinkMovementMethod.getInstance());

我找到了另一个比使用LinkMovementMethod更具侵入性的解决方案。相反,我只是扩展了ArrowKeyMovementMethod (EditText的默认移动方法),并添加了LinkMovementMethod中的一些代码,这些代码用于确定单击的跨度。在我的例子中,我寻找了一个ImageSpan,然后删除了span覆盖的文本(所以点击删除图像):

private class SpanDeletingMovementMethod : ArrowKeyMovementMethod() {
    override fun onTouchEvent(
        widget: TextView,
        buffer: Spannable,
        event: MotionEvent
    ): Boolean {
        if (event.action == MotionEvent.ACTION_DOWN) {
            var x = event.x.toInt()
            var y = event.y.toInt()
            x -= widget.totalPaddingLeft
            y -= widget.totalPaddingTop
            x += widget.scrollX
            y += widget.scrollY
            val layout = widget.layout
            val line = layout.getLineForVertical(y)
            val off = layout.getOffsetForHorizontal(line, x.toFloat())
            val committedTags = buffer.getSpans<ImageSpan>(off, off)
            if (committedTags.isNotEmpty()) {
                val tag = committedTags[0]
                (buffer as Editable).replace(buffer.getSpanStart(tag), buffer.getSpanEnd(tag), "")
                return true
            }
        }
        return super.onTouchEvent(widget, buffer, event)
    }
}

只需在EditText上设置此移动方法(或覆盖getDefaultMovementMethod),就可以处理span单击。

相关内容

  • 没有找到相关文章

最新更新