source

TextView텍스트에 이미지를 추가하는 방법

goodcode 2022. 9. 19. 23:36
반응형

TextView텍스트에 이미지를 추가하는 방법

구글에서 검색해 본 결과, 제 것과 유사한 질문을 발견했습니다. 어떻게 하면 이미지를 포함할 수 있을까요?TextView텍스트(예: "hello my name is [image] )는 다음과 같습니다.

ImageSpan is = new ImageSpan(context, resId);
text.setSpan(is, index, index + strLength, 0);

이 코드로 알고 싶어요

  1. 문맥에서 무엇을 타이핑하거나 수행해야 합니까?
  2. 내가 어떻게 해야 돼?text.setSpan()Import, reference, leask it text?와 같은 것.

누군가 이것을 분해해 주시면 감사하겠습니다.

이거 드셔보세요.

    txtview.setCompoundDrawablesWithIntrinsicBounds(
                    R.drawable.image, 0, 0, 0);

이것 좀 보세요.http://developer.android.com/reference/android/widget/TextView.html

xml 파일에서 시도합니다.

    <TextView
        android:id="@+id/txtStatus"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:drawableLeft="@drawable/image"
        android:drawablePadding="5dp"
        android:maxLines="1"
        android:text="@string/name"/>

com/xyz/customandroid/TextView이미지.java 사용 시:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.content.Context;
import android.text.Spannable;
import android.text.style.ImageSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextView;

public class TextViewWithImages extends TextView {

    public TextViewWithImages(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    public TextViewWithImages(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public TextViewWithImages(Context context) {
        super(context);
    }
    @Override
    public void setText(CharSequence text, BufferType type) {
        Spannable s = getTextWithImages(getContext(), text);
        super.setText(s, BufferType.SPANNABLE);
    }

    private static final Spannable.Factory spannableFactory = Spannable.Factory.getInstance();

    private static boolean addImages(Context context, Spannable spannable) {
        Pattern refImg = Pattern.compile("\\Q[img src=\\E([a-zA-Z0-9_]+?)\\Q/]\\E");
        boolean hasChanges = false;

        Matcher matcher = refImg.matcher(spannable);
    while (matcher.find()) {
        boolean set = true;
        for (ImageSpan span : spannable.getSpans(matcher.start(), matcher.end(), ImageSpan.class)) {
            if (spannable.getSpanStart(span) >= matcher.start()
             && spannable.getSpanEnd(span) <= matcher.end()
               ) {
                spannable.removeSpan(span);
            } else {
                set = false;
                break;
            }
        }
        String resname = spannable.subSequence(matcher.start(1), matcher.end(1)).toString().trim();
        int id = context.getResources().getIdentifier(resname, "drawable", context.getPackageName());
        if (set) {
            hasChanges = true;
            spannable.setSpan(  new ImageSpan(context, id),
                                matcher.start(),
                                matcher.end(),
                                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                             );
        }
    }

        return hasChanges;
    }
    private static Spannable getTextWithImages(Context context, CharSequence text) {
        Spannable spannable = spannableFactory.newSpannable(text);
        addImages(context, spannable);
        return spannable;
    }
}

용도:

res/syslog/mylayout.xml:

            <com.xyz.customandroid.TextViewWithImages
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="#FFFFFF00"
                android:text="@string/can_try_again"
                android:textSize="12dip"
                style=...
                />

TextView를 배치하면com/xyz/customandroid/ 이외의 장소에 Images.java를 사용하면 패키지 이름도 변경해야 합니다.com.xyz.customandroid위에.

res/values/values.xml:

<string name="can_try_again">Press [img src=ok16/] to accept or [img src=retry16/] to retry</string>

여기서 ok16.pngretry16.pngres/drawable/폴더 아이콘입니다.

저는 여러 가지 솔루션을 시도했습니다.제게는 이 방법이 가장 좋았습니다.

SpannableStringBuilder ssb = new SpannableStringBuilder(" Hello world!");
ssb.setSpan(new ImageSpan(context, R.drawable.image), 0, 1, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
tv_text.setText(ssb, TextView.BufferType.SPANNABLE);

이 코드는 최소한의 메모리를 사용합니다.

fun TextView.addImage(atText: String, @DrawableRes imgSrc: Int, imgWidth: Int, imgHeight: Int) {
    val ssb = SpannableStringBuilder(this.text)

    val drawable = ContextCompat.getDrawable(this.context, imgSrc) ?: return
    drawable.mutate()
    drawable.setBounds(0, 0,
            imgWidth,
            imgHeight)
    val start = text.indexOf(atText)
    ssb.setSpan(VerticalImageSpan(drawable), start, start + atText.length, Spannable.SPAN_INCLUSIVE_EXCLUSIVE)
    this.setText(ssb, TextView.BufferType.SPANNABLE)
}

VerticalImageSpan https://stackoverflow.com/a/38788432/5381331에서 수업을 들을 수 있습니다.

사용.

val textView = findViewById<TextView>(R.id.textview)
textView.setText("Send an [email-icon] to example@email.com.")
textView.addImage("[email-icon]", R.drawable.ic_email,
        resources.getDimensionPixelOffset(R.dimen.dp_30),
        resources.getDimensionPixelOffset(R.dimen.dp_30))

결과

메모
왜죠VerticalImageSpan수업?
ImageSpan.ALIGN_CENTER속성에는 API 29가 필요합니다.
그리고 시험이 끝나고 보니ImageSpan.ALIGN_CENTER이미지가 텍스트보다 작은 경우에만 작동하며, 이미지가 텍스트보다 큰 경우 이미지가 가운데에 있고 텍스트가 가운데에 있지 않은 경우에만 이미지 하단에 정렬됩니다.

이 답변은 18446744073709551615훌륭한 답변에 기초하고 있습니다.이러한 솔루션은 도움이 되지만 이미지 아이콘의 크기를 주변 텍스트와 함께 조정하지는 않습니다.또한 아이콘 색상을 주변 텍스트 색상으로 설정하지 않습니다.

다음 솔루션에서는 흰색의 정사각형 아이콘을 사용하여 주변 텍스트의 크기와 색상에 맞게 만듭니다.

public class TextViewWithImages extends TextView {

    private static final String DRAWABLE = "drawable";
    /**
     * Regex pattern that looks for embedded images of the format: [img src=imageName/]
     */
    public static final String PATTERN = "\\Q[img src=\\E([a-zA-Z0-9_]+?)\\Q/]\\E";

    public TextViewWithImages(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public TextViewWithImages(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public TextViewWithImages(Context context) {
        super(context);
    }

    @Override
    public void setText(CharSequence text, BufferType type) {
        final Spannable spannable = getTextWithImages(getContext(), text, getLineHeight(), getCurrentTextColor());
        super.setText(spannable, BufferType.SPANNABLE);
    }

    private static Spannable getTextWithImages(Context context, CharSequence text, int lineHeight, int colour) {
        final Spannable spannable = Spannable.Factory.getInstance().newSpannable(text);
        addImages(context, spannable, lineHeight, colour);
        return spannable;
    }

    private static boolean addImages(Context context, Spannable spannable, int lineHeight, int colour) {
        final Pattern refImg = Pattern.compile(PATTERN);
        boolean hasChanges = false;

        final Matcher matcher = refImg.matcher(spannable);
        while (matcher.find()) {
            boolean set = true;
            for (ImageSpan span : spannable.getSpans(matcher.start(), matcher.end(), ImageSpan.class)) {
                if (spannable.getSpanStart(span) >= matcher.start()
                        && spannable.getSpanEnd(span) <= matcher.end()) {
                    spannable.removeSpan(span);
                } else {
                    set = false;
                    break;
                }
            }
            final String resName = spannable.subSequence(matcher.start(1), matcher.end(1)).toString().trim();
            final int id = context.getResources().getIdentifier(resName, DRAWABLE, context.getPackageName());
            if (set) {
                hasChanges = true;
                spannable.setSpan(makeImageSpan(context, id, lineHeight, colour),
                        matcher.start(),
                        matcher.end(),
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                );
            }
        }
        return hasChanges;
    }

    /**
     * Create an ImageSpan for the given icon drawable. This also sets the image size and colour.
     * Works best with a white, square icon because of the colouring and resizing.
     *
     * @param context       The Android Context.
     * @param drawableResId A drawable resource Id.
     * @param size          The desired size (i.e. width and height) of the image icon in pixels.
     *                      Use the lineHeight of the TextView to make the image inline with the
     *                      surrounding text.
     * @param colour        The colour (careful: NOT a resource Id) to apply to the image.
     * @return An ImageSpan, aligned with the bottom of the text.
     */
    private static ImageSpan makeImageSpan(Context context, int drawableResId, int size, int colour) {
        final Drawable drawable = context.getResources().getDrawable(drawableResId);
        drawable.mutate();
        drawable.setColorFilter(colour, PorterDuff.Mode.MULTIPLY);
        drawable.setBounds(0, 0, size, size);
        return new ImageSpan(drawable, ImageSpan.ALIGN_BOTTOM);
    }

}

사용방법:

원하는 아이콘에 대한 참조를 텍스트에 삽입하기만 하면 됩니다.텍스트가 프로그래밍 방식으로 설정되었는지 여부는 중요하지 않습니다.textView.setText(R.string.string_resource);또는 xml로 설정되어 있는지 확인합니다.

example.png라는 이름의 그리기 가능 아이콘을 포함하려면 텍스트에 다음 문자열을 포함합니다.[img src=example/].

예를 들어 문자열 리소스는 다음과 같습니다.

<string name="string_resource">This [img src=example/] is an icon.</string>

이는 부분적으로 위의 @A Boschman의 답변에 기초하고 있습니다.그 솔루션에서, 나는 이미지의 입력 크기가 큰 영향을 미친다는 것을 알았다.makeImageSpan()이치노또한 불필요한 행간격을 만들어 텍스트 간격에 영향을 미치는 솔루션을 발견했습니다.

Facebook의 Presco 라이브러리에서 Base Image Span을 발견하면 특히 작업이 잘 됩니다.

 /**
 * Create an ImageSpan for the given icon drawable. This also sets the image size. Works best
 * with a square icon because of the sizing
 *
 * @param context       The Android Context.
 * @param drawableResId A drawable resource Id.
 * @param size          The desired size (i.e. width and height) of the image icon in pixels.
 *                      Use the lineHeight of the TextView to make the image inline with the
 *                      surrounding text.
 * @return An ImageSpan, aligned with the bottom of the text.
 */
private static BetterImageSpan makeImageSpan(Context context, int drawableResId, int size) {
    final Drawable drawable = context.getResources().getDrawable(drawableResId);
    drawable.mutate();
    drawable.setBounds(0, 0, size, size);
    return new BetterImageSpan(drawable, BetterImageSpan.ALIGN_CENTER);
}

다음 betterImageSpan 를 betterImageSpan으로 합니다.spannable.setSpan() 때처럼

TextView라고 칩시다.

<TextView
    android:id="@+id/title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:drawablePadding="4dp"
    android:drawableRight="@drawable/edit"
    android:text="Hello world"
    android:textSize="18dp" />

이제 요건에 따라 다음 행 중 하나를 추가할 수 있습니다.

android:drawableLeft="@drawable/filename"
android:drawableRight="@drawable/filename"
android:drawableTop="@drawable/filename"
android:drawableBottom="@drawable/filename"

도움이 될 수 있습니다.

  SpannableStringBuilder ssBuilder;

        ssBuilder = new SpannableStringBuilder(" ");
        // working code ImageSpan image = new ImageSpan(textView.getContext(), R.drawable.image);
        Drawable image = ContextCompat.getDrawable(textView.getContext(), R.drawable.image);
        float scale = textView.getContext().getResources().getDisplayMetrics().density;
        int width = (int) (12 * scale + 0.5f);
        int height = (int) (18 * scale + 0.5f);
        image.setBounds(0, 0, width, height);
        ImageSpan imageSpan = new ImageSpan(image, ImageSpan.ALIGN_BASELINE);
        ssBuilder.setSpan(
                imageSpan, // Span to add
                0, // Start of the span (inclusive)
                1, // End of the span (exclusive)
                Spanned.SPAN_INCLUSIVE_EXCLUSIVE);// Do not extend the span when text add later

        ssBuilder.append(" " + text);
        ssBuilder = new SpannableStringBuilder(text);
        textView.setText(ssBuilder);

이미지를 텍스트에 인라인으로 추가하기 위한 컴포넌트를 실행.임의의 위치를 지원하며 이미지를 클릭합니다.https://github.com/myDario/DarioInlineImageTextView

언급URL : https://stackoverflow.com/questions/15352496/how-to-add-image-in-a-textview-text

반응형