热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android编程中TextView宽度过大导致Drawable无法居中问题解决方法

这篇文章主要介绍了Android编程中TextView宽度过大导致Drawable无法居中问题解决方法,以实例形式较为详细的分析了TextView设置及xml布局与调用技巧,具有一定参考借鉴价值,需要的朋友可以参考下

本文实例讲述了Android编程中TextView宽度过大导致Drawable无法居中问题解决方法。分享给大家供大家参考,具体如下:

在做项目的时候,很多时候我们都要用到文字和图片一起显示,一般设置TextView的DrawableLeft、DrawableRight、DrawableTop、DrawableBottom就行了。但是有一种情况是当TextView的熟悉是fill_parent或者使用权重的时候并且设置了起Gravity的ceter的时候,Drawable图片是无法一起居中的,为了解决其,我们一般再套一层布局,然后设置TextView的熟悉是wrap_content,但是有时候嵌套过多的布局的时候,有可能发生StackOverFlow,所以必须要优化,下面说一下其中的一个解决方案。先上图

这个解决方案很粗糙,局限性很大,文字不能换行,换行之后就不准了,下面是源码:

package com.example.testandroid; 
import java.lang.ref.WeakReference; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Rect; 
import android.util.AttributeSet; 
import android.view.MotionEvent; 
import android.widget.TextView; 
public class DrawableTextView extends TextView { 
 private WeakReference normalReference; 
 private WeakReference pressReference; 
 private WeakReference showReference; 
 private int normalColor = Color.WHITE, pressColor = Color.WHITE; 
 private String text; 
 private int textWidth = 0; 
 private int textHeight = 0; 
 public DrawableTextView(Context context) { 
  super(context); 
 } 
 public DrawableTextView(Context context, AttributeSet attrs) { 
  super(context, attrs); 
 } 
 public DrawableTextView(Context context, AttributeSet attrs, int defStyle) { 
  super(context, attrs, defStyle); 
 } 
 @Override 
 protected void onFinishInflate() { 
  super.onFinishInflate(); 
  initText(); 
 } 
 private void initText() { 
  text = super.getText().toString(); 
  initVariable(); 
 } 
 /** 
  * 初始化,测量Textview内容的长度,高度 
  */ 
 private void initVariable() { 
  textWidth = (int) (getPaint().measureText(text)); 
  final Rect rect = new Rect(); 
  getPaint().getTextBounds(text, 0, 1, rect); 
  textHeight = rect.height(); 
 } 
 /** 
  * 设置TextView的内容 
  * @param text 
  */ 
 public void setText(String text) { 
  this.text = text; 
  initVariable(); 
  invalidate(); 
 } 
 /** 
  * 获取TextView内容 
  */ 
 public String getText() { 
  return text; 
 } 
 /** 
  * 设置TextView的Drawable内容,目前仅支持DrawableLeft 
  * @param normalDrawableId 
  *    DrawableLeft的normal状态Id 
  * @param pressDrawableId 
  *    DrawableLeft的press状态的Id(没有press状态,请传-1) 
  */ 
 public void setDrawableLeftId(final int normalDrawableId, final int pressDrawableId) { 
  normalReference = new WeakReference(BitmapFactory.decodeResource(getResources(), normalDrawableId)); 
  if (pressDrawableId != -1) { 
   pressReference = new WeakReference(BitmapFactory.decodeResource(getResources(), pressDrawableId)); 
  } 
  showReference = normalReference; 
  invalidate(); 
 } 
 /** 
  * 设置TextView的Color 
  * @param normalColor 
  *    TextView normal状态的Color值 
  * @param pressDrawableId 
  *    TextView press状态的Color值(如果没有press状态,请传与normal状态的值) 
  */ 
 public void setTextColor(final int normalColor, final int pressColor) { 
  this.normalColor = normalColor; 
  this.pressColor = pressColor; 
  getPaint().setColor(normalColor); 
  initVariable(); 
 } 
 @Override 
 protected void onDraw(Canvas canvas) { 
  if (showReference != null && showReference.get() != null) { 
   final int bitmapWidth = showReference.get().getWidth(); 
   final int bitmapHeight = showReference.get().getHeight(); 
   final int viewHeight = getHeight(); 
   final int drawablePadding = getCompoundDrawablePadding(); 
   final int start = (getWidth() - (bitmapWidth + drawablePadding + textWidth)) >> 1; 
   canvas.drawBitmap(showReference.get(), start, (viewHeight >> 1) - (bitmapHeight >> 1), getPaint()); 
   /** 
    * 注意改方法,第三个参数y,本人也被误导了好久,原来在画文字的时候,y表示文字最后的位置(不是下笔点的起始位置) 
    * 所以为什么 是TextView高度的一半(中间位置) + 文字高度的一半 = 文字居中 
    */ 
   canvas.drawText(text, start + drawablePadding + bitmapWidth, (viewHeight >> 1) + (textHeight >> 1), getPaint()); 
  } 
 } 
 @Override 
 public boolean onTouchEvent(MotionEvent event) { 
  if (event.getAction() == MotionEvent.ACTION_DOWN) { 
   if (pressReference != null && pressReference.get() != null) { 
    showReference = pressReference; 
   } 
   getPaint().setColor(pressColor); 
  } else if (event.getAction() == MotionEvent.ACTION_UP) { 
   if (normalReference != null && normalReference.get() != null) { 
    showReference = normalReference; 
   } 
   getPaint().setColor(normalColor); 
  } 
  invalidate(); 
  return super.onTouchEvent(event); 
 } 
}

xml布局:

调用代码:

DrawableTextView drawableTextView = (DrawableTextView) getView().findViewById(R.id.my_textview);
drawableTextView.setDrawableLeftId(R.drawable.bg_btn_delete_normal, R.drawable.bg_btn_delete_pressed);
drawableTextView.setTextColor(getResources().getColor(R.color.standard_orange), getResources().getColor(R.color.standard_white));
drawableTextView.setText("我在动态修改Text啦");

其实还有更加方便的方法,下面朋友借鉴某个网友的代码(地址我就不知道了):

@Override 
protected void onDraw(Canvas canvas) { 
 Drawable[] drawables = getCompoundDrawables(); 
 if (drawables != null) { 
  Drawable drawableLeft = drawables[0]; 
  if (drawableLeft != null) { 
   final float textWidth = getPaint().measureText(getText().toString()); 
   final int drawablePadding = getCompoundDrawablePadding(); 
   final int drawableWidth = drawableLeft.getIntrinsicWidth(); 
   final float bodyWidth = textWidth + drawableWidth + drawablePadding; 
   canvas.translate((getWidth() - bodyWidth) / 2, 0); 
  } 
 } 
 super.onDraw(canvas); 
}

xml布局:



嗯,自己写这个东西,也学到了一些东西,大家有什么更好的方法,大家可以讨论一下。

希望本文所述对大家Android程序设计有所帮助。


推荐阅读
  • 在探讨如何在Android的TextView中实现多彩文字与多样化字体效果时,本文提供了一种不依赖HTML技术的解决方案。通过使用SpannableString和相关的Span类,开发者可以轻松地为文本添加丰富的样式和颜色,从而提升用户体验。文章详细介绍了实现过程中的关键步骤和技术细节,帮助开发者快速掌握这一技巧。 ... [详细]
  • 在 Android 开发中,`android:exported` 属性用于控制组件(如 Activity、Service、BroadcastReceiver 和 ContentProvider)是否可以被其他应用组件访问或与其交互。若将此属性设为 `true`,则允许外部应用调用或与之交互;反之,若设为 `false`,则仅限于同一应用内的组件进行访问。这一属性对于确保应用的安全性和隐私保护至关重要。 ... [详细]
  • 本文介绍了一种自定义的Android圆形进度条视图,支持在进度条上显示数字,并在圆心位置展示文字内容。通过自定义绘图和组件组合的方式实现,详细展示了自定义View的开发流程和关键技术点。示例代码和效果展示将在文章末尾提供。 ... [详细]
  • 深入解析 SAP UI5 Page 控件的构造函数参数及其应用
    深入解析 SAP UI5 Page 控件的构造函数参数及其应用 ... [详细]
  • 使用 ListView 浏览安卓系统中的回收站文件 ... [详细]
  • 本文详细解析了Autofac在高级应用场景中的具体实现,特别是如何通过注册泛型接口的类来优化依赖注入。示例代码展示了如何使用 `builder.RegisterAssemblyTypes` 方法,结合 `typeof(IEventHandler).Assembly` 和 `Where` 过滤条件,动态注册所有符合条件的类,从而简化配置并提高代码的可维护性。此外,文章还探讨了这一方法在复杂系统中的实际应用及其优势。 ... [详细]
  • Parallels Desktop 10 是一款功能强大的虚拟化软件,专为 Mac 用户设计,使其能够无缝运行 Windows 应用程序。该软件不仅显著提升了图形应用的性能,还优化了演示效果。对于需要在 Mac 上高效运行 Windows 程序的用户来说,Parallels Desktop 10 是一个理想的选择。本文将介绍如何获取其激活码及免费下载渠道,帮助用户轻松激活并使用这一强大工具。 ... [详细]
  • 本文深入解析了通过JDBC实现ActiveMQ消息持久化的机制。JDBC能够将消息可靠地存储在多种关系型数据库中,如MySQL、SQL Server、Oracle和DB2等。采用JDBC持久化方式时,数据库会自动生成三个关键表:`activemq_msgs`、`activemq_lock`和`activemq_ACKS`,分别用于存储消息数据、锁定信息和确认状态。这种机制不仅提高了消息的可靠性,还增强了系统的可扩展性和容错能力。 ... [详细]
  • 本文深入探讨了Hibernate框架中乐观锁和悲观锁的机制及其多态特性。乐观锁假设数据在大多数情况下不会发生冲突,因此在读取数据时不加锁,而是在更新时检查版本号以确保数据未被修改。相比之下,悲观锁则认为数据在并发环境下容易产生冲突,因此在读取数据时立即加锁,以防止其他事务访问同一数据,从而避免潜在的数据不一致问题。文章还详细分析了这两种锁机制在实际应用中的优缺点,并介绍了Hibernate中的多态特性如何与锁机制结合,以实现更高效的数据管理和并发控制。 ... [详细]
  • 本文全面解析了 Python 中字符串处理的常用操作与技巧。首先介绍了如何通过 `s.strip()`, `s.lstrip()` 和 `s.rstrip()` 方法去除字符串中的空格和特殊符号。接着,详细讲解了字符串复制的方法,包括使用 `sStr1 = sStr2` 进行简单的赋值复制。此外,还探讨了字符串连接、分割、替换等高级操作,并提供了丰富的示例代码,帮助读者深入理解和掌握这些实用技巧。 ... [详细]
  • 如何使用 `org.apache.poi.openxml4j.opc.PackagePart` 类中的 `loadRelationships()` 方法及其代码示例详解 ... [详细]
  • 本文介绍了如何利用Struts1框架构建一个简易的四则运算计算器。通过采用DispatchAction来处理不同类型的计算请求,并使用动态Form来优化开发流程,确保代码的简洁性和可维护性。同时,系统提供了用户友好的错误提示,以增强用户体验。 ... [详细]
  • Hadoop平台警告解决:无法加载本机Hadoop库的全面应对方案
    本文探讨了在Hadoop平台上遇到“无法加载本机Hadoop库”警告的多种解决方案。首先,通过修改日志配置文件来忽略该警告,这一方法被证明是有效的。其次,尝试指定本地库的路径,但未能解决问题。接着,尝试不使用Hadoop本地库,同样没有效果。然后,通过替换现有的Hadoop本地库,成功解决了问题。最后,根据Hadoop的源代码自行编译本地库,也达到了预期的效果。以上方法适用于macOS系统。 ... [详细]
  • DevExpress v17.2新版本亮点深入解析:CodeRush功能详解(下篇)
    DevExpress v17.2 最新版本现已正式发布,我们将在系列文章中详细介绍其各项新特性。本文聚焦于 CodeRush v17.2 的最新功能,包括对 XAML 标准的全面支持。欢迎下载并体验这一强大工具的全新功能。 ... [详细]
  • 在本文中,我们将详细介绍如何构建一个用于自动回复消息的XML类。当微信服务器接收到用户消息时,该类将生成相应的自动回复消息。以下是具体的代码实现:```phpclass We_Xml { // 代码内容}```通过这个类,开发者可以轻松地处理各种消息类型,并实现高效的自动回复功能。我们将深入探讨类的各个方法和属性,帮助读者更好地理解和应用这一技术。 ... [详细]
author-avatar
浪费小创_512
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有