Android ImageSpan没有出现在TextView中

时间:2016-06-23 14:43:00

标签: c# android xamarin

我正在尝试使用Xamarin / Android项目在TextView中显示ImageSpan,但图像未显示。相反,TextView中有一个大的空白区域,应该出现图像(在TextView中的文本下方)。

TextView具有从strings.xml填充的HTML,我使用自定义ImageSpanResize类根据容器调整图像大小。

以下是自定义ImageSpanResize类:

  public class ImageSpanResize : ImageSpan
    {

        private static readonly int MIN_SCALE_WIDTH = 240;

        // TextView's width.
        private int mContainerWidth;

        public ImageSpanResize(Drawable d, string source, int containerWidth) : base(d, source)
        {
            mContainerWidth = containerWidth;
        }

        public override int GetSize(Paint paint, ICharSequence text, int start, int end, Paint.FontMetricsInt fm)
        {
            Drawable d = GetCachedDrawable();
            Rect rect = GetResizedDrawableBounds(d);

            if (fm != null)
            {
                fm.Ascent = -rect.Bottom;
                fm.Descent = 0;

                fm.Top = fm.Ascent;
                fm.Bottom = 0;
            }
            return rect.Right;
        }

        private Rect GetResizedDrawableBounds(Drawable d)
        {
            if (d == null || d.IntrinsicWidth == 0)
            {
                return new Rect(0, 0, d.IntrinsicWidth, d.IntrinsicHeight);
            }
            int scaledHeight;

            if (d.IntrinsicWidth < mContainerWidth)
            {
                // Image smaller than container's width.
                if (d.IntrinsicWidth > MIN_SCALE_WIDTH &&
                        d.IntrinsicWidth >= d.IntrinsicHeight)
                {
                    // But larger than the minimum scale size, we need to scale the image to fit
                    // the width of the container.
                    int scaledWidth = mContainerWidth;
                    scaledHeight = d.IntrinsicHeight * scaledWidth / d.IntrinsicWidth;
                    d.SetBounds(0, 0, scaledWidth, scaledHeight);
                }
                else
                {
                    // Smaller than the minimum scale size, leave it as is.
                    d.SetBounds(0, 0, d.IntrinsicWidth, d.IntrinsicHeight);
                }
            }
            else
            {
                // Image is larger than the container's width, scale down to fit the container.
                int scaledWidth = mContainerWidth;
                scaledHeight = d.IntrinsicHeight * scaledWidth / d.IntrinsicWidth;
                d.SetBounds(0, 0, scaledWidth, scaledHeight);
            }

            return d.Bounds;
        }

        private Drawable GetCachedDrawable()
        {
            WeakReference<Drawable> wr = mDrawableRef;
            Drawable d = null;

            if (wr != null)
            {
                wr.TryGetTarget(out d);
            }

            if (d == null)
            {
                d = Drawable;
                mDrawableRef = new WeakReference<Drawable>(d);
            }

            return d;
        }

        private WeakReference<Drawable> mDrawableRef;
    }

这是我用来显示ImageSpan的代码:

  public class MyActivity : Activity
    {
        private bool _textSet = false;
        private TextView _textView;
        private ImageView _textViewBackground;

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            SetContentView(Resource.Layout.MyActivity);
            InitControls();

            var layout = (RelativeLayout)FindViewById(Resource.Id.myLayout);
            var vto = layout.ViewTreeObserver;
            vto.GlobalLayout += Vto_GlobalLayout;
        }

        private void Vto_GlobalLayout(object sender, EventArgs e)
        {
            if (!_textSet)
            {
                DisplayText();
            }
        }

        private void InitControls()
        {
            _textView = (TextView)FindViewById(Resource.Id.myTextView);
            _textViewBackground = (ImageView)FindViewById(Resource.Id.myTextViewBackground);
        }

        private void DisplayText()
        {

            var imageSpan = new ImageSpanResize(Resources.GetDrawable(Resource.Drawable.img), "Yosemite", _textView.MeasuredWidth); //Find your drawable.

            var html = Html.FromHtml(GetString(Resource.String.html));
            var spannableString = new SpannableString(html); //Set text of SpannableString from TextView
            spannableString.SetSpan(imageSpan, html.Length() - 1, html.Length(), 0); //Add image at end of string

            _textView.TextFormatted = spannableString;
            _textView.MovementMethod = LinkMovementMethod.Instance;
            _textSet = true;
        }

    }

这是布局:

<?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:id="@+id/myLayout">
    <ImageView
        android:id="@+id/myTextViewBackground"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerInParent="true"
        android:adjustViewBounds="true"
        android:src="@drawable/parchment_scroll_background"
        android:scaleType="fitXY" />
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
                    android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:paddingLeft="20dp"
            android:paddingRight="20dp"
            android:paddingTop="100dp"
            android:paddingBottom="100dp">
        <TextView
            android:id="@+id/myTextView"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:lineSpacingMultiplier="1.2"
            android:textColor="#000000"
            android:bufferType="spannable"/>
    </RelativeLayout>
</RelativeLayout>

1 个答案:

答案 0 :(得分:0)

我最终使用的是WebView而不是TextView和ImageSpan。更少的痛苦。现在我可以使用HTML在任何地方定位图像和文本。