效果如图:
package com.laugh.HighlightCode;
import android.widget.EditText;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Color;
import android.graphics.Typeface;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.Layout;
import android.os.Handler;
import android.os.Message;
import android.text.TextWatcher;
import android.text.Editable;
import android.text.style.ForegroundColorSpan;
import android.text.Spanned;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.text.style.BackgroundColorSpan;
import android.view.View;
import android.view.MotionEvent;
import android.util.Log;
public class HighlightEditor extends EditText implements TextWatcher {
public static final Pattern a = Pattern.compile("=|<|>|!|\\-|\\+|&|\\|");
public static final Pattern b = Pattern.compile("true|false|[0-9]*$|\\d+(\\.\\d+)?");
public static final Pattern c = Pattern.compile("class|import|extends|package|implements|switch|while(?=.*\\()|for(?=.*\\()|break|case|private|public|protected|void|super|this|static|final|if|else|return|new|catch|try|default|interface");
public static final Pattern d = Pattern.compile("\\;|\\(|\\)|\\{|\\}|R\\..+?\\b|String |int |boolean |float |double |char |long |(?=@).*?(\\s|(?=\\())|(?<=extends ).*|(?<=implements ).*|(?<=(class |interface )).*?(?=\\s\\b)");
public static final Pattern e = Pattern.compile("((?)");
public static final Pattern f = Pattern.compile("(?<=import ).*(?=;)");
public static final Pattern g = Pattern.compile("\".+?\"");
public static final int COLOR_A = 0xFFF44336;
public static final int COLOR_B = 0xFF99C794;
public static final int COLOR_C = 0xFFFF5252;
public static final int COLOR_D = 0xFF6699CC;
public static final int COLOR_E = 0xFF999999;
public static final int COLOR_F = 0xFF646464;
private Paint leftPaint;//左边栏背景色画笔
private int paddingLeft = 60;//左边边距宽度
private TextPaint textPaint;//左边文字画笔
private CharSequence text;
public HighlightEditor(Context context) {
this(context, null);
}
public HighlightEditor(Context context, AttributeSet attr) {
super(context, attr);
setPadding(paddingLeft, 0, 0, 0);
setTextColor(0xFF646464);
this.leftPaint = new Paint();//左边栏背景色画笔
this.leftPaint.setColor(Color.parseColor("#64646464"));
textPaint = new TextPaint();//创建一个textPaint画笔
textPaint.setColor(Color.parseColor("#FF4081"));
textPaint.setTextSize(24);
textPaint.setAntiAlias(true);
addTextChangedListener(this);
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
int LineCount = getLineCount();//编辑框行数
int LineHeight = getLineHeight();//编辑框每行高度
if (LineHeight != 0) {
canvas.drawRect(0, 0, paddingLeft, getHeight(), leftPaint);//绘制左边栏
for (int i = 0;i < LineCount;i++) {
StaticLayout layout = new StaticLayout(String.valueOf(i + 1), textPaint, paddingLeft,
Layout.Alignment.ALIGN_CENTER, 1.0F, 0.0F, true);
canvas.save();
canvas.translate(0, (i) * LineHeight);
layout.draw(canvas);
canvas.restore();
}
//绘制当前选中行的横条
int y = (getLayout().getLineForOffset(getSelectionStart()) + 1) * LineHeight;
canvas.drawRect(0, y - LineHeight, getWidth(), y, leftPaint);
}
}
@Override
public void onTextChanged(final CharSequence text, int start, int before, int count) {
//text 输入框中改变后的字符串信息
//start 输入框中改变后的字符串的起始位置
//before 输入框中改变前的字符串的位置 默认为0
//count 输入框中改变后的一共输入字符串的数量
this.text = text;
highlight();
/*
if (handler.hasMessages(0)) {
handler.removeMessages(0);
}
handler.sendEmptyMessage(0);*/
}
@Override
public void beforeTextChanged(final CharSequence text, int start, int count, int after) {
//text 输入框中改变前的字符串信息
//start 输入框中改变前的字符串的起始位置
//count 输入框中改变前后的字符串改变数量一般为0
//after 输入框中改变后的字符串与起始位置的偏移量
}
@Override
public void afterTextChanged(Editable edit) {
//edit 输入结束呈现在输入框中的信息
}
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch(msg.what)
{
case 0:
highlight();
break;
}
}
};
private void highlight()
{
ForegroundColorSpan[] spans = getText().getSpans(0, getText().length(), ForegroundColorSpan.class);
for (int n = spans.length;n-- > 0;) {
getText().removeSpan(spans[n]);
}
BackgroundColorSpan[] Spans = getText().getSpans(0, getText().length(), BackgroundColorSpan.class);
for (int n = Spans.length;n--> 0;) {
getText().removeSpan(spans[n]);
}
Matcher A = a.matcher(text);
Matcher B = b.matcher(text);
Matcher C = c.matcher(text);
Matcher D = d.matcher(text);
Matcher E = e.matcher(text);
Matcher F = f.matcher(text);
Matcher G = g.matcher(text);
while (A.find()) {
getText().setSpan(new ForegroundColorSpan(COLOR_A), A.start(), A.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
while (C.find()) {
getText().setSpan(new ForegroundColorSpan(COLOR_C), C.start(), C.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
while (D.find()) {
getText().setSpan(new ForegroundColorSpan(COLOR_D), D.start(), D.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
while (B.find()) {
getText().setSpan(new ForegroundColorSpan(COLOR_B), B.start(), B.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
while (G.find()) {
ForegroundColorSpan[] G_Spans = getText().getSpans(G.start(), G.end(), ForegroundColorSpan.class);
for (int n = G_Spans.length;n--> 0;) {
getText().removeSpan(G_Spans[n]);
}
getText().setSpan(new ForegroundColorSpan(COLOR_B), G.start(), G.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
while (E.find()) {
ForegroundColorSpan[] E_Spans = getText().getSpans(E.start(), E.end(), ForegroundColorSpan.class);
for (int n = E_Spans.length;n--> 0;) {
getText().removeSpan(E_Spans[n]);
}
getText().setSpan(new ForegroundColorSpan(COLOR_E), E.start(), E.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
while (F.find()) {
ForegroundColorSpan[] F_Spans = getText().getSpans(F.start(), F.end(), ForegroundColorSpan.class);
for (int n = F_Spans.length;n--> 0;) {
getText().removeSpan(F_Spans[n]);
}
getText().setSpan(new ForegroundColorSpan(COLOR_F), F.start(), F.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
基本没有bug,只不过没有较好的优化线程
Tisp:默默的告诉你这是我的第一篇博文
CSDN:https://download.csdn.net/download/qq_36109137/10949393