1919
2020import android.content.Context;
2121import android.os.Looper;
22+ import android.text.Layout;
2223import android.text.Spannable;
2324import android.text.SpannableString;
2425import android.text.method.ScrollingMovementMethod;
2526import android.text.style.ForegroundColorSpan;
2627import android.util.AttributeSet;
2728
29+ import androidx.annotation.NonNull;
2830import androidx.annotation.Nullable;
2931import androidx.appcompat.widget.AppCompatTextView;
3032
3941 */
4042public class LoggerTextView extends AppCompatTextView {
4143
44+ /**
45+ * 日志格式化接口
46+ */
47+ private ILogFormatter mLogFormatter = new DefaultLogFormatter();
48+
49+ /**
50+ * 日志装饰接口
51+ */
52+ private ILogDecorator mLogDecorator = new DefaultLogDecorator();
53+
4254 public LoggerTextView(Context context) {
4355 this(context, null);
4456 }
@@ -52,6 +64,29 @@ public LoggerTextView(Context context, @Nullable AttributeSet attrs, int defStyl
5264 setMovementMethod(new ScrollingMovementMethod());
5365 }
5466
67+ /**
68+ * 设置日志格式化接口
69+ *
70+ * @param logFormatter 日志格式化接口
71+ * @return 日志打印显示控件
72+ */
73+ public LoggerTextView setLogFormatter(@NonNull ILogFormatter logFormatter) {
74+ mLogFormatter = logFormatter;
75+ return this;
76+ }
77+
78+
79+ /**
80+ * 设置日志装饰接口
81+ *
82+ * @param logDecorator 日志装饰接口
83+ * @return 日志打印显示控件
84+ */
85+ public LoggerTextView setLogDecorator(@NonNull ILogDecorator logDecorator) {
86+ mLogDecorator = logDecorator;
87+ return this;
88+ }
89+
5590 /**
5691 * 添加普通日志
5792 *
@@ -90,36 +125,24 @@ public void logWarning(String logContent) {
90125 addLog(logContent, LogType.WARNING);
91126 }
92127
128+ /**
129+ * 添加自定义等级日志
130+ *
131+ * @param logContent 日志内容
132+ */
133+
134+ public void logCustom(String logContent) {
135+ addLog(logContent, LogType.CUSTOM);
136+ }
137+
93138 /**
94139 * 添加日志
95140 *
96141 * @param logContent 日志内容
97142 * @param logType 日志类型
98143 */
99144 public void addLog(String logContent, LogType logType) {
100- SpannableString spannableString = new SpannableString(logContent);
101- switch (logType) {
102- case ERROR:
103- spannableString.setSpan(new ForegroundColorSpan(ResUtils.getColor(R.color.xui_config_color_error)),
104- 0,
105- logContent.length(),
106- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
107- break;
108- case SUCCESS:
109- spannableString.setSpan(new ForegroundColorSpan(ResUtils.getColor(R.color.xui_config_color_success)),
110- 0,
111- logContent.length(),
112- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
113- break;
114- case WARNING:
115- spannableString.setSpan(new ForegroundColorSpan(ResUtils.getColor(R.color.xui_config_color_waring)),
116- 0,
117- logContent.length(),
118- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
119- break;
120- default:
121- break;
122- }
145+ SpannableString spannableString = getLogDecorator().decorate(getLogFormatter().format(logContent, logType), logType);
123146 appendLogInMainThread(spannableString);
124147 }
125148
@@ -136,6 +159,31 @@ public void run() {
136159 }
137160 }
138161
162+
163+ /**
164+ * 获取日志装饰接口
165+ *
166+ * @return 日志装饰接口
167+ */
168+ public ILogDecorator getLogDecorator() {
169+ if (mLogDecorator == null) {
170+ mLogDecorator = new DefaultLogDecorator();
171+ }
172+ return mLogDecorator;
173+ }
174+
175+ /**
176+ * 获取日志格式化接口
177+ *
178+ * @return 日志格式化接口
179+ */
180+ public ILogFormatter getLogFormatter() {
181+ if (mLogFormatter == null) {
182+ mLogFormatter = new DefaultLogFormatter();
183+ }
184+ return mLogFormatter;
185+ }
186+
139187 private void appendLog(SpannableString spannableString) {
140188 append(spannableString);
141189 append("\r\n");
@@ -156,7 +204,8 @@ private void scrollToEnd() {
156204 * @return 获取当前TextView文字的真实高度
157205 */
158206 private int getTextRealHeight() {
159- return getLayout().getLineTop(getLineCount()) + getCompoundPaddingTop() + getCompoundPaddingBottom();
207+ Layout layout = getLayout();
208+ return (layout != null ? layout.getLineTop(getLineCount()) : 0) + getCompoundPaddingTop() + getCompoundPaddingBottom();
160209 }
161210
162211 /**
@@ -177,6 +226,92 @@ public void run() {
177226 }
178227 }
179228
229+ /**
230+ * 默认日志格式化接口
231+ *
232+ * @author xuexiang
233+ * @since 2021/4/14 1:48 AM
234+ */
235+ public static class DefaultLogFormatter implements ILogFormatter {
236+
237+ @Override
238+ public String format(String logContent, LogType logType) {
239+ return logContent;
240+ }
241+ }
242+
243+ /**
244+ * 日志格式化接口
245+ *
246+ * @author xuexiang
247+ * @since 2021/4/14 1:30 AM
248+ */
249+ public interface ILogFormatter {
250+ /**
251+ * 格式化日志内容
252+ *
253+ * @param logContent 日志内容
254+ * @param logType 日志类型
255+ * @return 格式化后的日志
256+ */
257+ String format(String logContent, LogType logType);
258+ }
259+
260+
261+ /**
262+ * 默认日志装饰接口
263+ *
264+ * @author xuexiang
265+ * @since 2021/4/14 1:49 AM
266+ */
267+ public static class DefaultLogDecorator implements ILogDecorator {
268+
269+ @Override
270+ public SpannableString decorate(String logContent, LogType logType) {
271+ SpannableString spannableString = new SpannableString(logContent);
272+ switch (logType) {
273+ case ERROR:
274+ spannableString.setSpan(new ForegroundColorSpan(ResUtils.getColor(R.color.xui_config_color_error)),
275+ 0,
276+ logContent.length(),
277+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
278+ break;
279+ case SUCCESS:
280+ spannableString.setSpan(new ForegroundColorSpan(ResUtils.getColor(R.color.xui_config_color_success)),
281+ 0,
282+ logContent.length(),
283+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
284+ break;
285+ case WARNING:
286+ spannableString.setSpan(new ForegroundColorSpan(ResUtils.getColor(R.color.xui_config_color_waring)),
287+ 0,
288+ logContent.length(),
289+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
290+ break;
291+ default:
292+ break;
293+ }
294+ return spannableString;
295+ }
296+ }
297+
298+ /**
299+ * 日志装饰接口
300+ *
301+ * @author xuexiang
302+ * @since 2021/4/14 1:30 AM
303+ */
304+ public interface ILogDecorator {
305+ /**
306+ * 装饰日志内容
307+ *
308+ * @param logContent 日志内容
309+ * @param logType 日志类型
310+ * @return 装饰后的日志
311+ */
312+ SpannableString decorate(String logContent, LogType logType);
313+ }
314+
180315 /**
181316 * 日志类型
182317 */
@@ -196,7 +331,11 @@ public enum LogType {
196331 /**
197332 * 警告日志
198333 */
199- WARNING
334+ WARNING,
335+ /**
336+ * 自定义等级日志
337+ */
338+ CUSTOM
200339 }
201340
202341
0 commit comments