Android : 通过 ImageSpan 在 textview 的末尾添加一个 imageview 并使图像可点击

Android : Adding an imageview right at the end of a textview via ImageSpan and make the image clickable

我想实现如上图所示的设计。该图像是从 URL 中获取的,我只想在图像中添加一个点击监听器。尝试使用 Image span 但没有成功。有人可以帮我解决这个问题吗?

谢谢

您可以在 ImageSpan 的相同位置设置另一个跨度调用 ClickableSpan。这里有一个示例代码:

builder.setSpan(new ClickableSpan() {
                            @Override
                            public void onClick(@NonNull View widget) {
                                Toast.makeText(context, "icon clicked", Toast.LENGTH_SHORT).show();
                            }
                        },
                builder.length() - 1,
                builder.length(),
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        holder.tvTitle.setText(builder);
        holder.tvTitle.setMovementMethod(LinkMovementMethod.getInstance());

设置 MovementMethod 以使点击生效很重要。

我不知道你的限制,但你可以使用如下布局:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:padding="5dp">

<TextView
    android:id="@+id/top_tv"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Papaya (Around)"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    />

<TextView
    android:id="@+id/bottom_tv"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text=",(2kg)"
    app:layout_constraintTop_toBottomOf="@id/top_tv"
    app:layout_constraintStart_toStartOf="@id/top_tv"/>

<ImageView
    android:id="@+id/iv"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_launcher_help"
    app:layout_constraintTop_toTopOf="@id/bottom_tv"
    app:layout_constraintBottom_toBottomOf="@id/bottom_tv"
    app:layout_constraintStart_toEndOf="@id/bottom_tv"/>

</androidx.constraintlayout.widget.ConstraintLayout>

并对 ImageView 使用 setOnClickListener。结果:

这里有一个更完整的问题答案。我使用可绘制资源,但您可以从位图中创建可绘制资源。有关说明,请参见以下代码。可以将此代码放入主 activity 的 onCreate()(或其他地方。)

// Get a string that can be spanned with an ImageSpan and a ClickableSpan.
SpannableString ss = new SpannableString("Some text ");
// This will be the image. I use a resource here, but there are constructors that can
// accept a Drawable. See BitmapDrawable at https://developer.android.com/reference/android/graphics/drawable/BitmapDrawable#BitmapDrawable(android.content.res.Resources,%20android.graphics.Bitmap)

ImageSpan imgSpan = new ImageSpan(this, R.drawable.ic_baseline_airplanemode_active_24, ImageSpan.ALIGN_CENTER);
ClickableSpan cs = new ClickableSpan() {
    @Override
    public void onClick(@NonNull View widget) {
        Toast.makeText(MainActivity.this, "Clicked!", Toast.LENGTH_SHORT).show();
    }
};

// The image will overlay the last blank in the text.
ss.setSpan(imgSpan, ss.length() - 1, ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// The clickable span will overlay the image from the ImageSpan.
ss.setSpan(cs, ss.length() - 1, ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// Just a TextView.
TextView myView = findViewById(R.id.myView);
myView.setText(ss);
// Prevent the ImageSpan from showing a highlight on click.
myView.setHighlightColor(getResources().getColor(android.R.color.transparent));
// Make sure the TextView can be clicked.
myView.setMovementMethod(LinkMovementMethod.getInstance());