I'm trying to detect if a user clicked on an ImageSpan. I use Layout.getPrimaryHorizontal(offset) to get the position of ImageSpan within the TextView but get a value which is off by approximately -28 pixels.
Here is the simplified code:
SpannableStringBuilder result = new SpannableStringBuilder();
// Insert Play icon
Drawable play = AppCompatResources.getDrawable(ctx, R.drawable.ic_play);
ImageSpan span = new ImageSpan(play, ImageSpan.ALIGN_BOTTOM);
final Rect bounds = span.getDrawable().getBounds();
result.append(" ", span, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
result.append(" x "); // The "x" is just for illustrative purposes.
// Insert waveform.
WaveDrawable dw = new WaveDrawable(new Rect(0, 0, (int) width, (int) (bounds.height() * 0.9f)));
ImageSpan wave = new ImageSpan(dw, ImageSpan.ALIGN_BASELINE);
result.append(new SpannableStringBuilder().append(" ", wave, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE), new ClickableSpan() {
@Override
public void onClick(@NonNull View widget) {
TextView tv = (TextView) widget;
Layout tvl = tv.getLayout();
Spanned fullText = (Spanned) tv.getText();
float startX = tvl.getPrimaryHorizontal(fullText.getSpanStart(wave));
float endX = tvl.getPrimaryHorizontal(fullText.getSpanEnd(wave));
Log.i(TAG, "Waveform clicked! start=" + startX +
"; end=" + endX +
"; width=" + (endX - startX) +
"; TextView width=" + widget.getWidth() +
"; drawable width=" + dw.getBounds().width());
}
}, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
The logcat output is
Waveform clicked! start=138.0; end=567.0; width=429.0; TextView width=601; drawable width=429
The values start=138.0; end=567.0 are definitely wrong, they should be around start=166.0; end=595.0;
Here is what it looks like:
The thin red box is the boundary of the drawable. The white background is the TextView. It's very obvious from the picture that the space between the right edges of the drawable and the TextView is around 6 pixels, not 601-567 = 34 pixels like getPrimaryHorizontal returns. For scale: the size of the Play button is 99 pixels.
If I use the same approach to get the position of the Play ImageSpan I get correct result.
Is this an Android bug or my bug?
