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