@@ -102,7 +102,7 @@ class DialogLogFragment : DialogFragment() {
102102 binding.btnCopy.setOnClickListener {
103103 try {
104104 val clipboard = requireContext().getSystemService(Context .CLIPBOARD_SERVICE ) as ClipboardManager
105- // Copy toàn bộ log từ StringBuilder (không giới hạn)
105+ // Lấy toàn bộ log từ Builder (không giới hạn 5000 dòng )
106106 val fullLog = currentHandler?.getAllLogText() ? : " "
107107 val clip = ClipData .newPlainText(" shell_log" , fullLog)
108108 clipboard.setPrimaryClip(clip)
@@ -176,7 +176,7 @@ class DialogLogFragment : DialogFragment() {
176176 private val logData = mutableListOf<SpannableString >()
177177 private val fullLogBuilder = StringBuilder ()
178178
179- // SỬ DỤNG log_item.xml CỦA BẠN TẠI ĐÂY
179+ // Sử dụng log_item.xml bạn đã tạo
180180 private val adapter = ArrayAdapter <SpannableString >(
181181 context,
182182 R .layout.log_item,
@@ -192,7 +192,7 @@ class DialogLogFragment : DialogFragment() {
192192
193193 init {
194194 listView?.adapter = adapter
195- listView?.divider = null // Xóa gạch ngang giữa các dòng log
195+ listView?.divider = null
196196 }
197197
198198 private fun getColor (resId : Int ): Int {
@@ -260,22 +260,35 @@ class DialogLogFragment : DialogFragment() {
260260
261261 override fun updateLog (msg : SpannableString ? ) {
262262 val listView = listViewRef.get() ? : return
263- msg?.let {
264- val rawStr = it.toString()
265- // Lưu vào Builder để Copy (giữ nguyên gốc)
266- fullLogBuilder.append(rawStr).append(" \n " )
267-
268- // XỬ LÝ HIỂN THỊ: Xóa bỏ ký tự ngắt dòng thừa để log khít nhau
269- val displayStr = rawStr.replace(" \n " , " " ).replace(" \r " , " " )
270- if (displayStr.isEmpty()) return @let
271-
272- // Ở đây ta dùng lại object 'it' nhưng xóa bỏ ký tự xuống dòng nếu cần giữ Span màu sắc
273- // Hoặc đơn giản là tạo Spannable mới từ chuỗi đã làm sạch
274- val cleanSpannable = SpannableString (displayStr)
263+ msg?.let { origin ->
264+ // Lưu vào builder để Copy (giữ nguyên gốc kèm xuống dòng)
265+ fullLogBuilder.append(origin.toString()).append(" \n " )
266+
267+ // Xử lý hiển thị
268+ val rawStr = origin.toString()
269+ val cleanStr = rawStr.trim(' \n ' , ' \r ' )
270+ if (cleanStr.isEmpty()) return @let
271+
272+ // Tạo Spannable mới để hiển thị khít dòng
273+ val cleanSpannable = SpannableString (cleanStr)
274+
275+ // SAO CHÉP MÀU SẮC: Chuyển các Span từ msg gốc sang bản hiển thị
276+ val spans = origin.getSpans(0 , origin.length, Any ::class .java)
277+ for (span in spans) {
278+ val start = origin.getSpanStart(span)
279+ val end = origin.getSpanEnd(span)
280+
281+ if (start < cleanSpannable.length) {
282+ val newEnd = if (end > cleanSpannable.length) cleanSpannable.length else end
283+ try {
284+ cleanSpannable.setSpan(span, start, newEnd, origin.getSpanFlags(span))
285+ } catch (e: Exception ) {}
286+ }
287+ }
275288
276289 listView.post {
277290 logData.add(cleanSpannable)
278- // Giới hạn 5000 dòng trên giao diện để tránh lag
291+ // Giới hạn 5000 dòng cuối trên giao diện
279292 if (logData.size > 5000 ) {
280293 logData.subList(0 , logData.size - 5000 ).clear()
281294 }
0 commit comments