如何将TextView与ImageView对齐?

19

图片描述

我正在尝试对TextView进行与ImageView的对齐。我正在使用以下代码:

 private void createSpannableText(){
        TextView myTextView = (TextView) findViewById(R.id.textView);
        SpannableStringBuilder builder = new SpannableStringBuilder();
        builder.append(this.getText(R.string.loren__ipsum__max));
        int lengthOfPart1 = builder.length();
        builder.append(" ");
        builder.append(this.getText(R.string.lorem__ipsum));
        Drawable d = getResources().getDrawable(R.drawable.myImage);
        d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); // <---- Very important otherwise your image won't appear
        ImageSpan myImage = new ImageSpan(d);
        builder.setSpan(myImage, 0, lengthOfPart1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        myTextView.setText(builder);
    }

但是我无法得到精确的结果。我该怎么办?在这种情况下,我需要使用SpannableStringBuilder还是有其他方法。请帮忙。我使用了这篇文章-http://majaxandroidtips.blogspot.in/2009/06/how-to-have-few-layout-elements-wrap_17.html来解决问题。
附注:我还想在ImageView周围有6dp的边距。

很好的提问方式 :) - sunil
@Debopam,你是否成功修复了以下代码中图片放在右侧的问题? - Ramona
1个回答

18
您可以使用API 8中可用的android.text.style.LeadingMarginSpan.LeadingMarginSpan2接口实现此目标。这是一篇文章,您可以使用浏览器将其翻译成中文。这里提供了该文章,但它不是英文的。此外,您还可以直接从这里下载示例的源代码。
您的布局:
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="5dp">
    <TextView
        android:textSize="18.0sp"
        android:id="@+id/message_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/text" />
    <ImageView
        android:src="@drawable/icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/icon" />
</RelativeLayout>

助手类实现LeadingMarginSpan.LeadingMarginSpan2

class MyLeadingMarginSpan2 implements LeadingMarginSpan.LeadingMarginSpan2 {
    private int margin;
    private int lines;

    MyLeadingMarginSpan2(int lines, int margin) {
        this.margin = margin;
        this.lines = lines;
    }

    /* Возвращает значение, на которе должен быть добавлен отступ */
    @Override
    public int getLeadingMargin(boolean first) {
        if (first) {
            /*
             * Данный отступ будет применен к количеству строк
             * возвращаемых getLeadingMarginLineCount()
             */
            return margin;
        } else {
            // Отступ для всех остальных строк
            return 0;
        }
    }

    @Override
    public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, 
            int top, int baseline, int bottom, CharSequence text, 
            int start, int end, boolean first, Layout layout) {}

    /*
     * Возвращает количество строк, к которым должен быть 
     * применен отступ возвращаемый методом getLeadingMargin(true)
     * Замечание:
     * Отступ применяется только к N строкам первого параграфа.
     */
    @Override
    public int getLeadingMarginLineCount() {
        return lines;
    }
};

您的活动代码:

 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        String text = getString(R.string.text);

        // Получаем иконку и ее ширину
        Drawable dIcon = getResources().getDrawable(R.drawable.icon);
        int leftMargin = dIcon.getIntrinsicWidth() + 10;

        // Устанавливаем иконку в R.id.icon
        ImageView icon = (ImageView) findViewById(R.id.icon);
        icon.setBackgroundDrawable(dIcon);

        SpannableString ss = new SpannableString(text);
        // Выставляем отступ для первых трех строк абазца
        ss.setSpan(new MyLeadingMarginSpan2(3, leftMargin), 0, ss.length(), 0);

        TextView messageView = (TextView) findViewById(R.id.message_view);
        messageView.setText(ss);
    }

最后,这里是一个演示结果:

在此输入图片描述


1
@Debopam 我认为你可以通过使用图像高度和textview的文本行高来获取数字,你可以查看vortex的答案https://dev59.com/uHE95IYBdhLWcg3wlu0g - K_Anas
1
@Debopam 他使用了 int lines = (int)Math.round(height / textLineHeight); - K_Anas
为什么不使用ImageSpan? - JPMagalhaes
这个工作得很好!需要注意的一点是,在函数getLeadingMargin(boolean first)中,"first"代表0到n-1行,其中n是getLeadingMarginLineCount()返回的值。 - Peri Hartman
@K_Anas:如果我在右侧有一个ImageView,文本必须使用右边距对齐,那么这段代码会如何更改?使用此自定义代码是可能的,对吧? - Wahib Ul Haq
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接