重写Button实现图片drawableTop和文字一起居中

很多情况下,我们需要这样的Button。

当然是可以通过建立一个LinearLayout来摆放一个ImageView和TextView来实现。这里就不说这种方法了。

还有一个实现方法是通过下面标签实现:

android:drawableLeft,

android:drawableRight,

android:drawableTop,

android:drawableBottom;

可是通过上面的标签来实现的话,图片会被贴着边缘摆放,如下图,这样没办法跟文字一起居中。

这里我们可以通过重写Button的onDraw(Canvas canvas) 方法,把图片和文字一起居中。

public class DrawableHorizontalButton extends Button {

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

	@Override
	protected void onDraw(Canvas canvas) {
		canvas = getTopCanvas(canvas);
		super.onDraw(canvas);
	}

	private Canvas getTopCanvas(Canvas canvas) {
		Drawable[] drawables = getCompoundDrawables();
		if (drawables == null) {
			return canvas;
		}
		Drawable drawable = drawables[0];// 左面的drawable
		if (drawable == null) {
			drawable = drawables[2];// 右面的drawable
		}

		// float textSize = getPaint().getTextSize(); // 使用这个会导致文字竖向排下来
		float textSize = getPaint().measureText(getText().toString());
		int drawWidth = drawable.getIntrinsicWidth();
		int drawPadding = getCompoundDrawablePadding();
		float contentWidth = textSize + drawWidth + drawPadding;
		int leftPadding = (int) (getWidth() - contentWidth);
		setPadding(0, 0, leftPadding, 0); // 直接贴到左边
		float dx = (getWidth() - contentWidth) / 2;
		canvas.translate(dx, 0);// 往右移动
		return canvas;
	}
}

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <com.example.view.DrawableHorizontalButton
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:drawableLeft="@drawable/ic_android_small"
        android:includeFontPadding="false"
        android:text="@string/hello_world"
        android:textSize="20sp" />

    <com.example.view.DrawableHorizontalButton
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:drawableRight="@drawable/ic_android_small"
        android:includeFontPadding="false"
        android:text="@string/hello_world"
        android:textSize="20sp" />

</LinearLayout>

运行上面的代码可以看到效果图:

很好,就是这样已经居中了。这里说一下实现原理。就是通过setPadding(int left, int top, int right, int bottom)方法把文字移动到边缘与图片挨起来,然后使用canvas.translate(float dx, float dy)把图片和文字一同移动到控件的中间。实现一起居中效果;

同理我们可以在实现上下型的居中:

代码如下:

public class DrawableVerticalButton extends Button {

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

	@Override
	protected void onDraw(Canvas canvas) {
		canvas = getTopCanvas(canvas);
		super.onDraw(canvas);
	}

	private Canvas getTopCanvas(Canvas canvas) {
		Drawable[] drawables = getCompoundDrawables();
		if (drawables == null) {
			return canvas;
		}
		Drawable drawable = drawables[1];// 上面的drawable
		if(drawable == null){
			drawable = drawables[3];// 下面的drawable
		}

		float textSize = getPaint().getTextSize();
		int drawHeight = drawable.getIntrinsicHeight();
		int drawPadding = getCompoundDrawablePadding();
		float contentHeight = textSize + drawHeight + drawPadding;
		int topPadding = (int) (getHeight() - contentHeight);
		setPadding(0, topPadding , 0, 0);
		float dy = (contentHeight - getHeight())/2;
		canvas.translate(0, dy);
		Log.i("DrawableTopButton", "setPadding(0,"+topPadding+",0,0");
		Log.i("DrawableTopButton", "translate(0,"+dy+")");
		return canvas;
	}

}

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <com.example.view.DrawableVerticalButton
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:drawableBottom="@drawable/ic_android_small"
        android:includeFontPadding="false"
        android:text="@string/hello_world"
        android:textSize="20sp" />

    <com.example.view.DrawableVerticalButton
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:drawableTop="@drawable/ic_android_small"
        android:includeFontPadding="false"
        android:text="@string/hello_world"
        android:textSize="20sp" />

</LinearLayout>

运行或者直接预览可以看到效果图如下:

上下和左右方向的实现原理都是一样的,都是把文字移动到边缘,然后文字和图片一同移动到中间,所以上下方向的代码是一样的。左右的方法是一样的。于是就是分开来写。大部分情况下我们都是使用上下方向的。

关于自定义控件时重写draw还是重写onDraw呢,Android官方推荐重写的话使用onDraw接口。

“When implementing a view, do not override this method; instead, you should implement onDraw”

来自CSDN博客:http://blog.csdn.net/dreamintheworld/article/details/45243663

时间: 2024-11-06 08:00:01

重写Button实现图片drawableTop和文字一起居中的相关文章

PHP合成图片、生成文字、居中对齐、画线、矩形、三角形、多边形、图片抗锯齿、不失真 高性能源码示例

function generateImg($source, $text1, $text2, $text3, $font = './msyhbd.ttf') { $date = '' . date ( 'Ymd' ) . '/'; $img = $date . md5 ( $source . $text1 . $text2 . $text3 ) . '.jpg'; if (file_exists ( './' . $img )) { return $img; } $main = imagecrea

Button的单击变色+button上面图片下边文字+圆角

简单来说就是自定义一个drawable. 有两种情况. 第一种: 单击时变色,不单击则原色:(pressed是单击,focused是获取焦点,根据需要更改) <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable

RadioButton的drawableTop图片文字不居中

在安卓应用的开发中,一般普通应用用到最多的就是底部放一个RadioGroup实现切换的布局,今天在实现的时候,却出现了底部RadiButton的drawableTop图片及文字无法居中的情况,经过对比实验发现RadioButton在不加background属性时,只能靠右对齐,加了layout_gravity和gravity属性也无效.如下图:加了一个background就马上看到效果,style属性定义如下所示:之前做的时候没有在意,遇到问题就浪费时间,小小的问题让我又是百度又是google了

UIButton图片文字控件位置自定义(图片居右文字居左、图片居中文字居中、图片居左文字消失等)

在开发中经常会碰到需要对按钮中的图片文字位置做调整的需求.第一种方式是通过设置按钮中图片文字的偏移量.通过方法setTitleEdgeInsets和setImageEdgeInsets实现 代码如下: /*!**方式一***/ - (void)updateBtnStyle_rightImage:(UIButton *)btn { CGFloat btnImageWidth = btn.imageView.bounds.size.width; CGFloat btnLabelWidth = btn

如何去除图片上的文字(PS使用教程)

很多时候由于工作的需要,需要对我们的图片进行修改,修改的同时还想要保存我们的图片背景,所以很多人就不知道怎么弄了,小编跟大家分享一下使用PS如何简单的去掉图片上的文字,希望对大家有所帮助! 方法/步骤 1.打开PS软件,进入主界面,点击左上角[文件],在弹出的菜单栏点击[打开] 2.在本地列表中找到需要添加的图片,将其添加到PS画板中 3.点击左侧[选框工具],在弹出菜单栏点击[矩形选框] 4.利用选框工具,选择图片上的文字,然后右键点击 5.在弹出的菜单栏中,选择[填充]选项, 点击打开 6.

Thinkphp图片水印和文字水印

1.Thinkphp图像处理 在TP框架中,我们经常用到图片上传,我最近写了很多关于图片上传的文章,thinkphp图片上传+validate表单验证+图片木马检测+缩略图生成等文章,今天写一下关于图片上传成功后给图片加水印文字或者加图片水印, 1.1图片处理类和库 首先,在Thinkphp\Think\Image类中有图像处理功能,支持Gd库和Imagick库,包括对GIf图像处理的支持. 1.2实例化类库 $image = new \Think\Image(); 实例化image后,默认使用

PS去掉图片上的文字的6种基本方法,动态教程

1.使用仿制图章工具去除文字这是比较常用的方法.具体的操作是,选取仿制图章工具,按住Alt键,在无文字区域点击相似的色彩或图案采样,然后在文字区域拖动鼠标复制以复盖文字.要注意的是,采样点即为复制的起始点.选择不同的笔刷直径会影响绘制的范围,而不同的笔刷硬度会影响绘制区域的边缘融合效果. 2.使用修补工具去除文字如果图片的背景色彩或图案比较一致,使用修补工具就比较方便.具体的操作是,选取修补工具,在公共栏中选择修补项为“源”,关闭“透明”选项.然后用修补工具框选文字,拖动到无文字区域中色彩或图案

python 图片上添加文字

1 import PIL 2 from PIL import ImageFont 3 from PIL import Image 4 from PIL import ImageDraw 5 6 #设置字体,如果没有,也可以不设置 7 font = ImageFont.truetype("/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf",13) 8 9 #打开底版图片 10 imageFile = "base.png&qu

图片工具类, 图片水印,文字水印,缩放,补白等

import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.Image; import java.awt.geom.AffineTransform; import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; import