美文网首页
Android SpannableString图片和文字居中对齐

Android SpannableString图片和文字居中对齐

作者: __素颜__ | 来源:发表于2019-10-10 19:00 被阅读0次

    一. 概述

    众所周知,Android图文混排可以通过SpannableString来实现,通过在相应位置使用ImageSpan替换即可,但是使用过的人会发现,imageSpan只提供了两种对齐方式,如下所示:

        /**
         底部对齐
         */
        public static final int ALIGN_BOTTOM = 0;
    
        /**
         基线对齐
         */
        public static final int ALIGN_BASELINE = 1;
    
    

    但是在大多数时候,我们希望实现图片的中点和文字的中点对齐(视觉设计师肯定会给到这样的要求),那么该怎么办呢?

    二. 图文混排,图片居中对齐方案

    方案1:

    一个比较简单解决方案就是让图片和文字的高度保持一致,这样就变相居中对齐了,那么有一些朋友为难了,视觉给的图片的高度比字体的高度小,这肿么办? 这个问题很好解决,让视觉给你切大一点的图片,即在原来的图片上多切一些透明的白边。(是不是恍然大悟?哈哈)

    plus:图片比文字高的情况根本不需要居中对齐。

    方案2:

    程序员肯定有程序员的方案,那就是扩展继承ImageSpan,重写它的onDraw()方法。这个方案本人参考了网上的一些解决方案,但是都有局限性,有些方案只要设置的TextView行间距或者padding就不能正常工作了。

    比如,这篇博客:Android ImageSpan使TextView的图文居中对齐

    这篇博客的方案,在设置了行间距的时候,就出现问题了。但是这篇博客把字体绘制的原理说的很清楚了,建议大家先读这篇博客,再来理解本人的做法。

    代码展示

    好了,直接上代码,这是自定义ImageSpan的代码,非常少。主要的原理是把图片绘制在字体的descent线和ascent的中点位置。还是那句话,先看上面那篇博客。

    public class CenterAlignImageSpan extends ImageSpan {
    
        public CenterAlignImageSpan(Drawable drawable) {
            super(drawable);
    
        }
    
        public CenterAlignImageSpan(Bitmap b) {
            super(b);
        }
    
        @Override
        public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom,
                @NonNull Paint paint) {
    
            Drawable b = getDrawable();
            Paint.FontMetricsInt fm = paint.getFontMetricsInt();
            int transY = (y + fm.descent + y + fm.ascent) / 2 - b.getBounds().bottom / 2;//计算y方向的位移
            canvas.save();
            canvas.translate(x, transY);//绘制图片位移一段距离
            b.draw(canvas);
            canvas.restore();
        }
    }
    
    

    使用和运行效果

    在布局文件里放置一个TextView,设置其行间距。

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        tools:context="com.example.hzwangqinwei.test.MainActivity"
        >
    
        <TextView
            android:id="@+id/test"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#aeae34"
            android:gravity="center"
            android:lineSpacingExtra="40dp"
            android:textSize="70dp"
            />
    
    </LinearLayout>
    
    

    activity里的代码如下展示:

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            TextView tv = (TextView) findViewById(R.id.test);
    
            SpannableString sp = new SpannableString("图文混排测排测试图文混排测试图文混排测试图文混排测试图");
    
            //获取一张图片
            Drawable drawable = getDrawable(R.drawable.star);
            drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
    
            //居中对齐imageSpan
            CenterAlignImageSpan imageSpan = new CenterAlignImageSpan(drawable);
            sp.setSpan(imageSpan, 0, 1, ImageSpan.ALIGN_BASELINE);
    
            //普通imageSpan 做对比
            ImageSpan imageSpan2 = new ImageSpan(drawable);
            sp.setSpan(imageSpan2, 3, 4, ImageSpan.ALIGN_BASELINE);
    
            tv.setText(sp);
        }
    }
    
    

    运行效果,第二张图片是普通的ImageSpan的效果,这里加入进来是做一个对比。

    image

    相关文章

      网友评论

          本文标题:Android SpannableString图片和文字居中对齐

          本文链接:https://www.haomeiwen.com/subject/jgujuctx.html