热门标签 | 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 九宫格布局详解及实现:人人网应用示例
    本文深入探讨了人人网Android应用中独特的九宫格布局设计,解析其背后的GridView实现原理,并提供详细的代码示例。这种布局方式不仅美观大方,而且在现代Android应用中较为少见,值得开发者借鉴。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • Android LED 数字字体的应用与实现
    本文介绍了一种适用于 Android 应用的 LED 数字字体(digital font),并详细描述了其在 UI 设计中的应用场景及其实现方法。这种字体常用于视频、广告倒计时等场景,能够增强视觉效果。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • 本文介绍了如何利用JavaScript或jQuery来判断网页中的文本框是否处于焦点状态,以及如何检测鼠标是否悬停在指定的HTML元素上。 ... [详细]
  • 本文详细介绍了如何使用PHP检测AJAX请求,通过分析预定义服务器变量来判断请求是否来自XMLHttpRequest。此方法简单实用,适用于各种Web开发场景。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 本文探讨了 RESTful API 和传统接口之间的关键差异,解释了为什么 RESTful API 在设计和实现上具有独特的优势。 ... [详细]
  • 本文详细介绍了如何使用Spring Boot进行高效开发,涵盖了配置、实例化容器以及核心注解的使用方法。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • Python自动化处理:从Word文档提取内容并生成带水印的PDF
    本文介绍如何利用Python实现从特定网站下载Word文档,去除水印并添加自定义水印,最终将文档转换为PDF格式。该方法适用于批量处理和自动化需求。 ... [详细]
  • 在当前众多持久层框架中,MyBatis(前身为iBatis)凭借其轻量级、易用性和对SQL的直接支持,成为许多开发者的首选。本文将详细探讨MyBatis的核心概念、设计理念及其优势。 ... [详细]
  • 将Web服务部署到Tomcat
    本文介绍了如何在JDeveloper 12c中创建一个Java项目,并将其打包为Web服务,然后部署到Tomcat服务器。内容涵盖从项目创建、编写Web服务代码、配置相关XML文件到最终的本地部署和验证。 ... [详细]
  • XNA 3.0 游戏编程:从 XML 文件加载数据
    本文介绍如何在 XNA 3.0 游戏项目中从 XML 文件加载数据。我们将探讨如何将 XML 数据序列化为二进制文件,并通过内容管道加载到游戏中。此外,还会涉及自定义类型读取器和写入器的实现。 ... [详细]
  • 本文介绍如何在 Unity 的 XML 配置文件中,将参数传递给自定义生命周期管理器的构造函数。我们将详细探讨 CustomLifetimeManager 类的实现及其配置方法。 ... [详细]
author-avatar
溪龙2012_753
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有