热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

WordTextView首行缩进左右对齐

项目中一般会遇到特殊的TextView,比如保证文字的左右对齐,首行缩进啦,这样的话系统定制的TextView就无法满足要求了,需要我们自定义WordT

项目中一般会遇到特殊的TextView,比如保证文字的左右对齐,首行缩进啦,这样的话系统定制的TextView就无法满足要求了,需要我们自定义WordTextView。

直接上效果图:
这里写图片描述

上面的是系统的TextView,下面的是WordTextView

package com.views;

import android.content.Context;
import android.graphics.Canvas;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.widget.TextView;

/**
* By Jie 2017.7.9
*
* Word排版文本View
*
* 首行缩进,左右对齐TextView
*/

public class WordTextView extends TextView {

private int mLineY;//y轴绘制的坐标
private int mViewWidth;//view总宽度
private int mViewHeight;//view总高度

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

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//如果设置的是确切值,那么就不再继续测量了
if(MeasureSpec.getMode(widthMeasureSpec)==MeasureSpec.EXACTLY&&MeasureSpec.getMode(heightMeasureSpec)==MeasureSpec.EXACTLY){
return;
}
//如果有的值测量的不准确,需要重新测量
Layout layout = getLayout();//获取测量的文本布局
mViewHeight =0;
mViewWidth = layout.getWidth()+getPaddingLeft()+getPaddingRight();
for (int i = 0; i mViewHeight += getLineHeight();
}
mViewHeight = mViewHeight + getPaddingTop() + getPaddingBottom();
setMeasuredDimension(mViewWidth,mViewHeight);//重新设置宽和高
}


/**
*
* 整体思路如下:
*
* 1 确定整个文本有多少行
*
* 2 重新绘制每一行的文本保证能左右对齐,或者首行缩进
*
* 3 最后一行正常绘制,因为他没有下一行,不一定要设置右对齐了
* @param canvas
*/

@Override
protected void onDraw(Canvas canvas) {
TextPaint paint = getPaint();
mViewWidth = getMeasuredWidth();//获取测量的实际的宽度
String text = (String) getText();//获取字符串string
mLineY = 0;
mLineY += getTextSize()*1.5;//开始绘制的y轴坐标
Layout layout = getLayout();
for (int i = 0; i int lineStart = layout.getLineStart(i);
int lineEnd = layout.getLineEnd(i);
String line = text.substring(lineStart, lineEnd);

float width = StaticLayout.getDesiredWidth(text, lineStart, lineEnd, getPaint());//每一行文本的宽度
if (needScale(line) && i 1 ) {
drawScaledText(canvas,line, width,i);//自己绘制,保证可以左右对齐或者首行缩进
} else {
canvas.drawText(line, 0, mLineY, paint);//不用自己绘制,系统绘制即可
}
mLineY += getLineHeight();//继续绘制下一行,找到下一行坐标
}
}

/**
* 思路如下:
*
* 举个例子,屏幕宽度100,文本90,要想让文本填充整个屏幕怎么办呢?
* 很简单,让文本字符间隔填充剩下的10,还是不懂?
* 假如文本有10个字符,那么我让每个字符绘制的时候都和上一个字符间隔多1,那么正好文本宽度就成了(90+10=100)可以左右对齐屏幕了
* @param canvas
* @param line
* @param lineWidth
* @param index
*/

private void drawScaledText(Canvas canvas,String line, float lineWidth,int index) {
float x = 0;
if (isFirstLineOfParagraph(index)) {//如果是第一行就要加空格字符,保证可以首行缩进
String blanks = " ";
canvas.drawText(blanks, x, mLineY, getPaint());
float bw = StaticLayout.getDesiredWidth(blanks, getPaint());
x += bw;
lineWidth = lineWidth +bw;
}

float d = (mViewWidth-lineWidth) /line.length();//每个字符的额外间隔,专门是为了填充屏幕剩下的宽度
for (int i = 0; i String c = String.valueOf(line.charAt(i));
float cw = StaticLayout.getDesiredWidth(c, getPaint());
canvas.drawText(c, x, mLineY, getPaint());
x += cw+d;
}
}

private boolean isFirstLineOfParagraph(int lineIndex) {
return lineIndex==0;
}

private boolean needScale(String line) {
if (line.length() == 0) {
return false;
} else {
return line.charAt(line.length() - 1) != '\n';
}
}

}


推荐阅读
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Android系统源码分析Zygote和SystemServer启动过程详解
    本文详细解析了Android系统源码中Zygote和SystemServer的启动过程。首先介绍了系统framework层启动的内容,帮助理解四大组件的启动和管理过程。接着介绍了AMS、PMS等系统服务的作用和调用方式。然后详细分析了Zygote的启动过程,解释了Zygote在Android启动过程中的决定作用。最后通过时序图展示了整个过程。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • 今日份分享:Flutter自定义之旋转木马
    今日份分享:Flutter自定义之旋转木马-先上图,带你回到童年时光:效果分析子布局按照圆形顺序放置且平分角度子布局旋转、支持手势滑动旋转、快速滑动抬手继续旋转、自动旋转支持X轴旋 ... [详细]
  • 1简介本文结合数字信号处理课程和Matlab程序设计课程的相关知识,给出了基于Matlab的音乐播放器的总体设计方案,介绍了播放器主要模块的功能,设计与实现方法.我们将该设 ... [详细]
  • 今天就跟大家聊聊有关怎么在Android应用中实现一个换肤功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根 ... [详细]
  • 使用Flutternewintegration_test进行示例集成测试?回答首先在dev下的p ... [详细]
  • Editedbymythouhttp:www.cnblogs.commythoupublicbooleancreateReflectedForAdapter(){finalintr ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了10分钟了解Android的事件分发相关的知识,希望对你有一定的参考价值。什么是事件分发?大家 ... [详细]
  • 时域|波形_语音处理基于matlab GUI音频数据处理含Matlab源码 1734期
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了语音处理基于matlabGUI音频数据处理含Matlab源码1734期相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 注:根据Qt小神童的视频教程改编概论:利用最新的Qt5.1.1在windows下开发的一个小的时钟程序,有指针与表盘。1.Qtforwindows开发环境最新的Qt已经集 ... [详细]
  • 当我在doWork方法中运行代码时,通过单击button1,进度条按预期工作.但是,当我从其他方法(即btn2,btn3)将列表传递给doWork方法时,进度条在启动后会跳转到10 ... [详细]
  • 四、连接屏幕流各位读者好!我们已经到了应用开发的一个重要阶段——连接屏幕。如您所知,我们在上一章 ... [详细]
  • 请修改resxmldefault_workspace.xml文件,添加如下代码:    launcher:packageName完整的包名    launcher:cla ... [详细]
author-avatar
尛丶俊_188
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有