很多情况下,我们需要这样的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);}@Overrideprotected 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];// 左面的drawableif (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"?>            

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


很好,就是这样已经居中了。这里说一下实现原理。就是通过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);}@Overrideprotected 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];// 上面的drawableif(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"?>            
运行或者直接预览可以看到效果图如下:

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

关于自定义控件时重写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


更多相关文章

  1. android:fastScrollEnabled和android:drawSelectorOnTop
  2. Android(安卓)TextView
  3. 界面开发中布局属性全面剖析
  4. textview中加链接
  5. Android(安卓)TextView中文字通过SpannableString来设置超链接、
  6. android WebView总结
  7. Android(安卓)toolbar overflow菜单 文字显示不全
  8. Android(安卓)自定义View之MarqueeText,实现跑马灯效果
  9. Android之玩转View

随机推荐

  1. android 4.0 NetworkOnMainThreadExcepti
  2. android有用的知识
  3. Android(安卓)常见的几种加密方式RSA、CB
  4. Android ListView嵌套Button,Button事件
  5. Android 将activity设置成对话框样式
  6. Ionic新建项目(以Android为例)
  7. androidのMMS短信发送过程(二)
  8. android 获取手机信息(device ip,os versio
  9. 【android】解决设置ImageView的scaletyp
  10. 如何制作Jar包并在android中调用jar包