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());
我想实现如上图所示的设计。该图像是从 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());