2

enter image description here

I want to achieve a design as shown above in the screenshot. The image is fetched from a URL and I want to add a click listener in the image only. Tried using Image span but with no success. Could somebody help me through this?

Thank you

viper
  • 1,836
  • 4
  • 25
  • 41
  • You have an image downloaded but need to incorporate it into the text and then make just the image clickable. Is that right or are you looking for help getting the image from the URL? Can you share you code to get the image? – Cheticamp Jul 28 '21 at 12:54
  • Yes sir, I can download the image and place it in an imageview using Picasso library. But need to add that image just at the end of the text – viper Jul 28 '21 at 15:46
  • Can you add the _ImageSpan_ so it shows up in the text? It would be helpful to show some of your code. – Cheticamp Jul 28 '21 at 15:55

3 Answers3

1

You can set another span call ClickableSpan at the same place of the ImageSpan. Here an example code:

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());

It is important to setMovementMethod for the click to work.

Dennis Nguyen
  • 278
  • 2
  • 9
1

Here is a more complete answer to your question. I use a drawable resource, but you can create a drawable from your bitmap. See the following code for a description. This code can be placed into the onCreate() of your main activity (or elsewhere.)

enter image description here

// 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());
Cheticamp
  • 61,413
  • 10
  • 78
  • 131
  • Thank you great example. But I would have to set the image from a URL. How would I do that? – viper Aug 02 '21 at 04:19
  • 1
    @viper If you are using Picasso [here](https://stackoverflow.com/a/25154748/6287910) is an example of how to go about it. In `onBitMapLoaded()` you will create a _BitmapDrawable_ from the bitmap and set the _Drawable_ where you need it. You will need Internet permission in the manifest and make sure that you update the UI on the main thread. You may need to do some additional manipulation to the bitmap to change size, etc. depending on your needs. – Cheticamp Aug 02 '21 at 11:51
  • @viper Also, make sure your _Target_ is not garbage collected before you need it. This seems to be an issue that some have with Picasso. – Cheticamp Aug 02 '21 at 14:03
-1

I don't know your limitation, but you can using a layout like bellow:

<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>

and using setOnClickListener for ImageView. The result:

enter image description here

Alireza Barakati
  • 1,016
  • 2
  • 9
  • 23