安卓开发常见问题文字和图片排版问题

情景描述:在中展示一些数据,这些数据前面都小图标,要求:小图标和文字水平对齐。问题分析:对于图文横排的问题,有很多的解决办法,但是究其根本还是将和文字放在同一行上进行展示。实现方案:方案一:写法上很简单,但是这个的有很大问题。.m-icon{display:inline- vertical-align: padding-right:1 height:1 background-image:url(icon.png); background-size:1 background-repeat:no-}.m-icon.star{background-position:}.m-icon.like{background-position:}.m-icon.share{background-position:}.m-text{display:inline-vertical-align:font-size:1}&i class=&m-icon star&&&/i&&span&&/span&
&i class=&m-icon like&&&/i&&span&&/span&
&i class=&m-icon share&&&/i&&span&&/span&tip:这种写法非常简单,利用css3的inline-block属性便可以实现对齐,但是这个在手机显示比较好,手机则会有明显的对不齐的问题。方案二:Android重写TextView实现文字整齐排版
  TextView有时不能满足我们排版的需求,那么如何重新定义TextView以实现我们的想法呢,以下是实现的代码:
  //XRTextView类
  package rong.android.
  import org.json.JSONA
  import org.json.JSONE
  import android.content.C
  import android.graphics.C
  import android.graphics.C
  import android.graphics.P
  import android.util.AttributeS
  import android.view.V
  import android.widget.TextV
  public class XRTextView extends TextView{
  private final String namespace = &rong.android.TextView&;
  private S
  private float textS
  private float paddingL
  private float paddingR
  private float marginL
  private float marginR
  private int textC
  private JSONArray colorI
  private Paint paint1 = new Paint();
  private Paint paintColor = new Paint();
  private float textShowW
  private float Spacing = 0;
  private float LineSpacing = 1.3f;//行与行的间距
  public XRTextView(Context context, AttributeSet attrs) {
  super(context, attrs);
  text = attrs.getAttributeValue(
  &/apk/res/android&, &text&);
  textSize = attrs.getAttributeIntValue(namespace, &textSize&, 25);//字体大小
  textColor = attrs.getAttributeIntValue(namespace, &textColor&,Color.BLUE);//字体颜色
  paddingLeft = attrs.getAttributeIntValue(namespace, &paddingLeft&, 0);
  paddingRight = attrs.getAttributeIntValue(namespace, &paddingRight&, 0);
  marginLeft = attrs.getAttributeIntValue(namespace, &marginLeft&, 0);
  marginRight = attrs.getAttributeIntValue(namespace, &marginRight&, 0);
  paint1.setTextSize(textSize);
  paint1.setColor(textColor);
  paint1.setAntiAlias(true);
  paintColor.setAntiAlias(true);
  paintColor.setTextSize(textSize);
  paintColor.setColor(Color.BLUE);
  public XRTextView(Context context, float textSize, int textColor, float paddingLeft, float paddingRight, float marginLeft, float marginRight){
  super(context);
  this.textSize = textS
  this.textColor = textC
  this.paddingLeft = paddingL
  this.paddingRight = paddingR
  this.marginLeft = marginL
  this.marginRight = marginR
  paint1.setTextSize(textSize);
  paint1.setColor(textColor);
  paint1.setAntiAlias(true);
  paintColor.setAntiAlias(true);
  paintColor.setTextSize(textSize);
  paintColor.setColor(Color.BLUE);
  public JSONArray getColorIndex() {
  return colorI
  public void setColorIndex(JSONArray colorIndex) {
  this.colorIndex = colorI
  * 传入一个索引,判断当前字是否被高亮
  * @param index
  * @return
  * @throws JSONException
  public boolean isColor(int index) throws JSONException{
  if(colorIndex == null){
  for(int i = 0 ; i & colorIndex.length() ; i ++){
  JSONArray array = colorIndex.getJSONArray(i);
  int start = array.getInt(0);
  int end = array.getInt(1)-1;
  if(index &= start && index &= end){
  @Override
  protected void onDraw(Canvas canvas) {
  //& super.onDraw(canvas);
  View view=(View)this.getParent();
  textShowWidth=view.getMeasuredWidth()-paddingLeft - paddingRight - marginLeft - marginR
  int lineCount = 0;
  text = this.getText()。toString();//.replaceAll(&\n&, &\r\n&);
  if(text==null)
  char[] textCharArray = text.toCharArray();
  // 已绘的宽度
  float drawedWidth = 0;
  float charW
  for (int i = 0; i & textCharArray. i++) {
  charWidth = paint1.measureText(textCharArray, i, 1);
  if(textCharArray[i]=='\n&){
  lineCount++;
  drawedWidth = 0;
  if (textShowWidth - drawedWidth & charWidth) {
  lineCount++;
  drawedWidth = 0;
  boolean color =
  color = isColor(i);
  } catch (JSONException e1) {
  // TODO Auto-generated catch block
  e1.printStackTrace();
  if(color){
  canvas.drawText(textCharArray, i, 1, paddingLeft + drawedWidth,
  (lineCount + 1) * textSize * LineSpacing, paintColor);
  }else{
  canvas.drawText(textCharArray, i, 1, paddingLeft + drawedWidth,
  (lineCount + 1) * textSize * LineSpacing, paint1);
  if(textCharArray[i] & 127 && textCharArray[i] != &、& && textCharArray[i] != &,& && textCharArray[i] != &。& && textCharArray[i] != &:& && textCharArray[i] != &!&){
  drawedWidth += charWidth + S
  }else{
  drawedWidth += charW
  setHeight((int) ((lineCount + 1) * (int) textSize * LineSpacing + 10));
  public float getSpacing() {
  return S
  public void setSpacing(float spacing) {
  Spacing =
  public float getMYLineSpacing() {
  return LineS
  public void setMYLineSpacing(float lineSpacing) {
  LineSpacing = lineS
  public float getMYTextSize() {
  return textS
  public void setMYTextSize(float textSize) {
  this.textSize = textS
  paint1.setTextSize(textSize);
  paintColor.setTextSize(textSize);
  //MainActivity类
  package rong.android.
  import android.os.B
  import android.widget.TextV
  import android.app.A
  public class MainActivity extends Activity {
  private XRTextView xrtextview =
  private TextView textview =
  private String content = &abcdefgABCDEF我要你kjfsljfwfisdlfjsllkjsdfjlskjff3sd4f31s3dffslfksjdfljlsadkjfljdfls 的!@#$%^&*()_&;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  xrtextview = (XRTextView) this.findViewById(R.id.mytextview_tv);
  xrtextview.setText(content);
  textview = (TextView) this.findViewById(R.id.mytextview_tv1);
  textview.setText(content);
  //布局文件
  LinearLayout xmlns:android=&/apk/res/android&
  xmlns:tools=&/tools&
  android:layout_width=&match_parent&
  android:layout_height=&match_parent&
  android:orientation=&vertical& &
  &rong.android.test.XRTextView
  android:id=&@+id/mytextview_tv&
  android:layout_width=&match_parent&
  android:layout_height=&wrap_content& /&
  &TextView
  android:id=&@+id/mytextview_tv1&
  android:layout_width=&match_parent&
  android:layout_height=&wrap_content&
  android:textColor=&@android:color/black& /&
  /LinearLayout&
微信扫一扫
您好,感谢关注凌阳教育,如果您要索取免费技术资料,请点击此处留言,谢谢!你的位置:
> android 重写TextView 实现文字整齐排版
发表于( 10:14) 本文标签:
浏览量:loading次
//XRTextView类package rong.android.import org.json.JSONAimport org.json.JSONEimport android.content.Cimport android.graphics.Cimport android.graphics.Cimport android.graphics.Pimport android.util.AttributeSimport android.view.Vimport android.widget.TextVpublic class XRTextView extends TextView{private final String namespace = &rong.android.TextView&;private Sprivate float textSprivate float paddingLprivate float paddingRprivate float marginLprivate float marginRprivate int textCprivate JSONArray colorIprivate Paint paint1 = new Paint();private Paint paintColor = new Paint();private float textShowWprivate float Spacing = 0;private float LineSpacing = 1.3f;//行与行的间距public XRTextView(Context context, AttributeSet attrs) {super(context, attrs);text = attrs.getAttributeValue(&/apk/res/android&, &text&);textSize = attrs.getAttributeIntValue(namespace, &textSize&, 25);//字体大小textColor = attrs.getAttributeIntValue(namespace, &textColor&,Color.BLUE);//字体颜色paddingLeft = attrs.getAttributeIntValue(namespace, &paddingLeft&, 0);paddingRight = attrs.getAttributeIntValue(namespace, &paddingRight&, 0);marginLeft = attrs.getAttributeIntValue(namespace, &marginLeft&, 0);marginRight = attrs.getAttributeIntValue(namespace, &marginRight&, 0);paint1.setTextSize(textSize);paint1.setColor(textColor);paint1.setAntiAlias(true);paintColor.setAntiAlias(true);paintColor.setTextSize(textSize);paintColor.setColor(Color.BLUE);}public XRTextView(Context context, float textSize, int textColor, float paddingLeft, float paddingRight, float marginLeft, float marginRight){super(context);this.textSize = textSthis.textColor = textCthis.paddingLeft = paddingLthis.paddingRight = paddingRthis.marginLeft = marginLthis.marginRight = marginRpaint1.setTextSize(textSize);
日本的电子设备厂商Murata在CEATEC 2015展会上推出了自家新设计的智能概念眼镜。根据Murata官方的说法,这款运用了AR技术的智能眼镜中植入了目前全球最小的微型PS开关模块,能够让用户实现远程控制家庭事物的能力。比如说,使用Murata眼镜之后,用户可以不必
10月28日消息, 操控无人机的体验虽然令人兴奋,但也很容易乐极生悲,特别是发生坠机事故的时候。毕竟,那些配备4K视频摄录能力的无人机售价不菲,不是随意就可以另外购买一架的。 然而,局面即将发生改变。据国外媒体报道,AIG(美国国际集团)近日针对无人
目前,可穿戴设备集中发展的很快,形式也变得多样化,比如手表,腕带,眼镜,袜子,衣服,等等。今年,可穿戴技术的发展速度尤为明显,因为越来越多人已经开始接受可穿戴设备。不过,相比于快速创新的可穿戴设备,可穿戴电池的发展速度似乎比较缓慢。尽管绝
Bobsweep扫地机器人:专门针对宠物设计 近日,加拿大科技公司Bobi发布了一款全新的扫地机器人Bobsweep,其特色是完全针对宠物设计,有望解决宠物毛发无法清洁干净这个问题。
地上跑的机器人送货服务已开始试点测试 Starship的送货机器人初期主要用于同城快递服务,采用自动驾驶方式,当货品被送到最后一英里的时候机器人将会自动切断电路。
无人机飞过超级月亮。CFP 资料 当地时间10月19日,奥巴马政府表示,将要求无人机机主为他们的无人机进行登记,以减少无人机飞行对商业航班和人流密集场所造成的安全隐患。 当天,美国交通运输部部长安东尼福克斯宣布成立一个由私营部门和政府代表组成的工作
上海法院:流量劫持首次被认定为犯罪 上海市浦东新区人民法院判决了全国首起流量劫持刑事案件,两名被告人被判有期徒刑3年,缓刑3年。Android TextView自动换行文字排版参差不齐的原因
  今天项目没什么进展,公司后台出问题了。看了下刚刚学习时的笔记,发现TextView会自动换行,而且排版文字参差不齐。查了下资料,总结原因如下:
  1、半角字符与全角字符混乱所致:这种情况一般就是汉字与数字、英文字母混用
  解决方法一:
  将textview中的字符全角化。即将所有的数字、字母及标点全部转为全角字符,使它们与汉字同占两个字节,这样就可以避免由于占位导致的排版混乱问题了。 半角转为全角的代码如下,只需调用即可。
  public static String ToDBC(String input) {
  char[] c = input.toCharArray();
  for (int i = 0; i< c. i&#43;&#43;) {
  if (c[i] == 12288) {
  c[i] = (char) 32;
  }if (c[i]> 65280&& c[i]< 65375)
  c[i] = (char) (c[i] - 65248);
  return new String(c);
  解决方法二:
  去除特殊字符或将所有中文标号替换为英文标号。利用正则表达式将所有特殊字符过滤,或利用replaceAll()将中文标号替换为英文标号。则转化之后,则可解决排版混乱问题。
  // 替换、过滤特殊字符
  public static String StringFilter(String str) throws PatternSyntaxException{
  str=str.replaceAll("【","[").replaceAll("】","]").replaceAll("!","!");//替换中文标号
  String regEx="[『』]"; // 清除掉特殊字符
  Pattern p = pile(regEx);
  Matcher m = p.matcher(str);
  return m.replaceAll("").trim();
  2、TextView在显示中文的时候 标点符号不能显示在一行的行首和行尾,如果一个标点符号刚好在一行的行尾,该标点符号就会连同前一个字符跳到下一行显示。
  解决方法:在标点符号后加一个空&#26684;。
  3、一个英文单词不能被显示在两行中( TextView在显示英文时,标点符号是可以放在行尾的,但英文单词也不能分开 )。
  4、如果要两行对其的显示效果:有两种方法
  方法一:
  修改Android源代码;将frameworks/base/core/java/android/text下的StaticLayout.java文件中的如下代码:
  if (c == ' ' || c == '/t' ||
  ((c == '.' || c == ',' || c == ':' || c == ';') &&
  (j - 1 < here || !Character.isDigit(chs[j - 1 - start])) &&
  (j &#43; 1 >= next || !Character.isDigit(chs[j &#43; 1 - start]))) ||
  ((c == '/' || c == '-') &&
  (j &#43; 1 >= next || !Character.isDigit(chs[j &#43; 1 - start]))) ||
  (c >= FIRST_CJK && isIdeographic(c, true) &&
  j &#43; 1 < next && isIdeographic(chs[j &#43; 1 - start], false))) {
  okwidth =
  ok = j &#43; 1;
  if (fittop < oktop)
  oktop =
  if (fitascent < okascent)
  okascent =
  if (fitdescent > okdescent)
  okdescent =
  if (fitbottom > okbottom)
  okbottom =
  去掉就可以了。去掉后标点符号可以显示在行首和行尾,英文单词也可以被分开在两行中显示。
  方法二:
  自定义View显示文本
  网上就有达人采用自定义View来解决这个问题,我做了实验并总结了一下:
  自定义View的步骤:
  1)继承View类或其子类,例子继承了TextView类;
  2)写构造函数,通过XML获取属性(这一步中可以自定义属性,见例程);
  3)重写父类的某些函数,一般都是以on开头的函数,例子中重写了onDraw()和onMeasure()函数;
  =========================CYTextView.java=============================
  public class CYTextView extends TextView {
  public static int m_iTextH //文本的高度
  public static int m_iTextW//文本的宽度
  private Paint mPaint =
  private String string="";
  private float LineSpace = 0;//行间距
  public CYTextView(Context context, AttributeSet set)
  super(context,set);
  TypedArray typedArray = context.obtainStyledAttributes(set, R.styleable.CYTextView);
  int width = typedArray.getInt(R.styleable. CY TextView_textwidth, 320);
  float textsize = typedArray.getDimension(R.styleable. CY TextView_textSize, 24);
  int textcolor = typedArray.getColor(R.styleable. CY TextView_textColor, -);
  float linespace = typedArray.getDimension(R.styleable. CY TextView_lineSpacingExtra, 15);
  int typeface = typedArray.getColor(R.styleable. CY TextView_typeface, 0);
  typedArray.recycle();
  //设置 CY TextView的宽度和行间距
  m_iTextWidth=
  LineSpace=
  // 构建paint对象
  mPaint = new Paint();
  mPaint.setAntiAlias(true);
  mPaint.setColor(textcolor);
  mPaint.setTextSize(textsize);
  switch(typeface){
  case 0:
  mPaint.setTypeface(Typeface.DEFAULT);
  case 1:
  mPaint.setTypeface(Typeface.SANS_SERIF);
  case 2:
  mPaint.setTypeface(Typeface.SERIF);
  case 3:
  mPaint.setTypeface(Typeface.MONOSPACE);
  default:
  mPaint.setTypeface(Typeface.DEFAULT);
  @Override
  protected void onDraw(Canvas canvas)
  super.onDraw(canvas);
  int w = 0;
  int istart = 0;
  int m_iFontH
  int m_iRealLine=0;
  int x=2;
  int y=30;
  Vector m_String=new Vector();
  FontMetrics fm = mPaint.getFontMetrics();
  m_iFontHeight = (int) Math.ceil(fm.descent - fm.top) &#43; (int)LineS//计算字体高度(字体高度&#43;行间距)
  for (int i = 0; i < string.length(); i&#43;&#43;)
  ch = string.charAt(i);
  float[] widths = new float[1];
  String srt = String.valueOf(ch);
  mPaint.getTextWidths(srt, widths);
  if (ch == '/n'){
  m_iRealLine&#43;&#43;;
  m_String.addElement(string.substring(istart, i));
  istart = i &#43; 1;
  w = 0;
  }else{
  w &#43;= (int) (Math.ceil(widths[0]));
  if (w > m_iTextWidth){
  m_iRealLine&#43;&#43;;
  m_String.addElement(string.substring(istart, i));
  istart =
  w = 0;
  }else{
  if (i == (string.length() - 1)){
  m_iRealLine&#43;&#43;;
  m_String.addElement(string.substring(istart, string.length()));
  m_iTextHeight=m_iRealLine*m_iFontHeight&#43;2;
  canvas.setViewport(m_iTextWidth, m_iTextWidth);
  for (int i = 0, j = 0; i < m_iRealL i&#43;&#43;, j&#43;&#43;)
  canvas.drawText((String)(m_String.elementAt(i)), x, y&#43;m_iFontHeight * j, mPaint);
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
  int measuredHeight = measureHeight(heightMeasureSpec);
  int measuredWidth = measureWidth(widthMeasureSpec);
  this.setMeasuredDimension(measuredWidth, measuredHeight);
  this.setLayoutParams(new LinearLayout.LayoutParams(measuredWidth,measuredHeight));
  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  private int measureHeight(int measureSpec)
  int specMode = MeasureSpec.getMode(measureSpec);
  int specSize = MeasureSpec.getSize(measureSpec);
  // Default size if no limits are specified.
  initHeight();
  int result = m_iTextH
  if (specMode == MeasureSpec.AT_MOST){
  // Calculate the ideal size of your
  // control within this maximum size.
  // If your control fills the available
  // space return the outer bound.
  result = specS
  }else if (specMode == MeasureSpec.EXACTLY){
  // If your control can fit within these bounds return that value.
  result = specS
  private void initHeight()
  //设置 CY TextView的初始高度为0
  m_iTextHeight=0;
  //大概计算 CY TextView所需高度
  FontMetrics fm = mPaint.getFontMetrics();
  int m_iFontHeight = (int) Math.ceil(fm.descent - fm.top) &#43; (int)LineS
  int line=0;
  int istart=0;
  int w=0;
  for (int i = 0; i < string.length(); i&#43;&#43;)
  char ch = string.charAt(i);
  float[] widths = new float[1];
  String srt = String.valueOf(ch);
  mPaint.getTextWidths(srt, widths);
  if (ch == '/n'){
  line&#43;&#43;;
  istart = i &#43; 1;
  w = 0;
  }else{
  w &#43;= (int) (Math.ceil(widths[0]));
  if (w > m_iTextWidth){
  line&#43;&#43;;
  istart =
  w = 0;
  }else{
  if (i == (string.length() - 1)){
  line&#43;&#43;;
  m_iTextHeight=(line)*m_iFontHeight&#43;2;
  private int measureWidth(int measureSpec)
  int specMode = MeasureSpec.getMode(measureSpec);
  int specSize = MeasureSpec.getSize(measureSpec);
  // Default size if no limits are specified.
  int result = 500;
  if (specMode == MeasureSpec.AT_MOST){
  // Calculate the ideal size of your control
  // within this maximum size.
  // If your control fills the available space
  // return the outer bound.
  result = specS
  }else if (specMode == MeasureSpec.EXACTLY){
  // If your control can fit within these bounds return that value.
  result = specS
  public void SetText(String text)(注:此函数目前只有在UI线程中调用才可以把文本画出来,在其它线程中
  无法画文本,找了好久找不到原因,求高手解答)
  string =
  // requestLayout();
  // invalidate();
  =======================attrs.xml===============================
  该文件是自定义的属性,放在工程的res/values下
  =======================main.xml==========================
  <scrollview
  xmlns:Android="/apk/res/android"
  Android:layout_width="320px"
  Android:layout_height="320px"
  Android:background="#ffffffff"
  <linearlayout
  xmlns:Android="/apk/res/android"
  Android:orientation="vertical"
  Android:layout_width="fill_parent"
  Android:layout_height="fill_parent">
  <com.cy.cytextview.cytextview
  xmlns:cy="/apk/res/ com.cy.CYTextView "
  Android:id="@&#43;id/mv"
  Android:layout_height="wrap_content"
  Android:layout_width="wrap_content"
  cy :textwidth="320"
  cy :textSize="24sp"
  cy :textColor="#aa000000"
  cy :lineSpacingExtra="15sp"
  cy :typeface="serif">
  蓝色代码即为自定义View,其中以cy命名空间开头的属性是自定义属性;
  =======================Main.java=============================
  public class Main extends Activity {
  CYTextView mCYTextV
  String text = "Android提供了精巧和有力的化模型构建用户的UI部分。主要是基于布局类:View和 ViewGroup。在此基础上,android平台提供了大量的预制的View和xxxViewGroup子 类,即布局(layout)和窗口小部件(widget)。可以用它们构建自己的UI。";
  @Override
  public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  this.setContentView(R.layout.main);
  mCYTextView = (CYTextView)findViewById(R.id.mv);
  mCYTextView.SetText(text);| 521: 源站宕机
-- Event ID: a167d
如果您是网站管理员,点击查看。如需网站监控,可以使用。
您的浏览器
百度云加速

我要回帖

更多关于 安卓面试实际开发问题 的文章

 

随机推荐