Android自定义TextView实现文字图片居中显示的方法

 更新时间:2018年01月22日 10:33:16   作者:布丁西西  
下面小编就为大家分享一篇Android自定义TextView实现文字图片居中显示的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

最近有个需求是这样的,人民币的符号“¥”因为安卓手机系统的不一致导致符号不是完全一样,所以用美工的给的图片代替,考虑到用的地方比较多,所以想着写一个继承于线性布局的组合控件,后来一想,安卓中不是有TextView吗,这个自带图片的控件,后来写了个demo,因为我是用的MatchParent,导致问题出现,人民币符号不是和文字一样的居中,因此才有了这篇博文,让我们来自定义TextView吧,这个场景用的比较多。

分析下TextView的源码

我们先来分析下TextView的源码,因为TextView有上下左右四个方向的图片,上下咱就先不考虑了,因为一般来说图片垂直居中是没有问题的,我们就只处理这个left,和right方向上的图片, 我们直接看TextView的ondraw方法,因为TextView 也是继承自View,所有的绘制都将会在这里操作

<span style="font-size:18px;">int vspace = bottom - top - compoundPaddingBottom - compoundPaddingTop;
int hspace = right - left - compoundPaddingRight - compoundPaddingLeft;
// IMPORTANT: The coordinates computed are also used in invalidateDrawable()
// Make sure to update invalidateDrawable() when changing this code.
if (dr.mShowing[Drawables.LEFT] != null) {
  canvas.save();
  canvas.translate(scrollX + mPaddingLeft + leftOffset,
           scrollY + compoundPaddingTop +
           (vspace - dr.mDrawableHeightLeft) / 2);
  dr.mShowing[Drawables.LEFT].draw(canvas);
  canvas.restore();
}
// IMPORTANT: The coordinates computed are also used in invalidateDrawable()
// Make sure to update invalidateDrawable() when changing this code.
if (dr.mShowing[Drawables.RIGHT] != null) {
  canvas.save();
  canvas.translate(scrollX + right - left - mPaddingRight
      - dr.mDrawableSizeRight - rightOffset,
       scrollY + compoundPaddingTop + (vspace - dr.mDrawableHeightRight) / 2);
  dr.mShowing[Drawables.RIGHT].draw(canvas);
  canvas.restore();
}</span>

从上面可以看到有个canvas.translate方法,大概意思是,save后,将画布向X轴和Y轴分别平移了scrollX ..和scrollY,平移后,将left方向的图片绘制上去,最后restore还原到上个画布中,Right同理。

那这样,咱基本上就明白原理,TextView的四个方向都是通过Canvas的translate来绘制到文字的上下左右了,那咱们就只改这个scrollX 和 scrollY就可以实现咱的需求了吧。

具体实现

1.下面写有注释,不是特别麻烦,适配drawableLeft 和 drawableRight图片,PS,xml中不要设置Gravity,这样就可以居中了,代码如下:

<span style="font-size:18px;">package com.chaoxing.email.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.widget.TextView;
/**
 * use in xml
 * use in code
 */
public class EmailCenterTextView extends TextView {
  public EmailCenterTextView(Context context) {
    super(context);
  }
  public EmailCenterTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
  }
  public EmailCenterTextView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
  }
  @Override
  protected void onDraw(Canvas canvas) {
    Drawable[] drawables = getCompoundDrawables();
    if (null != drawables) {
      Drawable drawableLeft = drawables[0];
      Drawable drawableRight = drawables[2];
      float textWidth = getPaint().measureText(getText().toString());
      if (null != drawableLeft) {
        setGravity(Gravity.START | Gravity.CENTER_VERTICAL);
        float contentWidth = textWidth + getCompoundDrawablePadding() + drawableLeft.getIntrinsicWidth();
        if (getWidth() - contentWidth > 0) {
          canvas.translate((getWidth() - contentWidth - getPaddingRight() - getPaddingLeft()) / 2, 0);
        }
      }
      if (null != drawableRight) {
        setGravity(Gravity.END | Gravity.CENTER_VERTICAL);
        float contentWidth = textWidth + getCompoundDrawablePadding() + drawableRight.getIntrinsicWidth();
        if (getWidth() - contentWidth > 0) {
          canvas.translate(-(getWidth() - contentWidth - getPaddingRight() - getPaddingLeft()) / 2, 0);
        }
      }
      if (null == drawableRight && null == drawableLeft) {
        setGravity(Gravity.CENTER);
      }
    }
    super.onDraw(canvas);
  }
}</span>

更新效果图(因为之前有看到网友回复,最近又用到了再更新下这个博客)

title是用的就是EmailCenterTextView,那个箭头上下的就是设置的drawableRight,演示的未读和垃圾箱EmailCenterTextView没有设置图片

以上这篇Android自定义TextView实现文字图片居中显示的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Android应用内调用第三方应用的方法

    Android应用内调用第三方应用的方法

    这篇文章主要介绍了Android应用内调用第三方应用的方法,有需要的朋友可以参考一下
    2014-01-01
  • Android中一种巧妙的drawable.xml替代方案分享

    Android中一种巧妙的drawable.xml替代方案分享

    这篇文章主要给大家介绍了关于Android中一种巧妙的drawable.xml替代方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-09-09
  • Android自定义VIew实现卫星菜单效果浅析

    Android自定义VIew实现卫星菜单效果浅析

    这篇文章主要介绍了Android自定义VIew实现卫星菜单效果浅析,非常不错具有参考借鉴价值,需要的朋友可以参考下
    2016-11-11
  • 解决Android 沉浸式状态栏和华为虚拟按键冲突问题

    解决Android 沉浸式状态栏和华为虚拟按键冲突问题

    对于现在的 App 来说,布局页面基本都会用到沉浸式状态栏,单纯的沉浸式状态栏很容易解决,但是在华为手机上存在一个底部虚拟按键的问题,会导致页面底部和顶部出现很大的问题,下面通过本文给大家分享Android 沉浸式状态栏和华为虚拟按键冲突问题,一起看看吧
    2017-07-07
  • RxJava2.x实现定时器的实例代码

    RxJava2.x实现定时器的实例代码

    本篇文章主要介绍了RxJava2.x实现定时器,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • 利用Flutter制作一个会飞的菜单

    利用Flutter制作一个会飞的菜单

    flutter中自带了drawer组件,可以实现通用的菜单功能,所以本文将尝试一下通过自定义动画来实现一个会飞的菜单,感兴趣的可以了解一下
    2023-06-06
  • android图像绘制(七)ClipRect局部绘图/切割原图绘制总结

    android图像绘制(七)ClipRect局部绘图/切割原图绘制总结

    这几天开始学游戏地图制作,今天小小的总结一下Canvas的clipRect()接口的使用,接下来介绍ClipRect局部绘图/切割原图绘制感兴趣的朋友可以了解下
    2013-01-01
  • Android手机显示多彩霓虹灯效果

    Android手机显示多彩霓虹灯效果

    这篇文章主要为大家详细介绍了Android手机显示多彩霓虹灯效果的小实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • Android 5.0及以上编程实现屏幕截图功能的方法

    Android 5.0及以上编程实现屏幕截图功能的方法

    这篇文章主要介绍了Android 5.0及以上编程实现屏幕截图功能的方法,结合实例形式分析了Android5.0以上实现截图功能的相关类、函数及权限控制等操作技巧,需要的朋友可以参考下
    2018-01-01
  • 详解Android ContentProvider的基本原理和使用

    详解Android ContentProvider的基本原理和使用

    ContentProvider(内容提供者)是 Android 的四大组件之一,管理 Android 以结构化方式存放的数据,以相对安全的方式封装数据(表)并且提供简易的处理机制和统一的访问接口供其他程序调用
    2021-06-06

最新评论