From 2c4e4f5090466be257b9b00528e525f08b4c8e1b Mon Sep 17 00:00:00 2001 From: fankesyooni Date: Fri, 3 Jun 2022 01:59:29 +0800 Subject: [PATCH] Merge ListView's adapter to BaseAdapterFactory --- .../errors/AppErrorsRecordActivity.kt | 39 +++------ .../utils/factory/BaseAdapterFactory.kt | 86 +++++++++++++++++++ 2 files changed, 99 insertions(+), 26 deletions(-) create mode 100644 app/src/main/java/com/fankes/apperrorstracking/utils/factory/BaseAdapterFactory.kt diff --git a/app/src/main/java/com/fankes/apperrorstracking/ui/activity/errors/AppErrorsRecordActivity.kt b/app/src/main/java/com/fankes/apperrorstracking/ui/activity/errors/AppErrorsRecordActivity.kt index 827071a..3307bbb 100644 --- a/app/src/main/java/com/fankes/apperrorstracking/ui/activity/errors/AppErrorsRecordActivity.kt +++ b/app/src/main/java/com/fankes/apperrorstracking/ui/activity/errors/AppErrorsRecordActivity.kt @@ -25,9 +25,10 @@ package com.fankes.apperrorstracking.ui.activity.errors import android.app.Activity import android.content.Intent -import android.view.* +import android.view.ContextMenu +import android.view.MenuItem +import android.view.View import android.widget.AdapterView.AdapterContextMenuInfo -import android.widget.BaseAdapter import androidx.core.view.isVisible import com.fankes.apperrorstracking.R import com.fankes.apperrorstracking.bean.AppErrorsInfoBean @@ -83,33 +84,19 @@ class AppErrorsRecordActivity : BaseActivity() { } /** 设置列表元素和 Adapter */ binding.listView.apply { - adapter = object : BaseAdapter() { - - override fun getCount() = listData.size - - override fun getItem(position: Int) = listData[position] - - override fun getItemId(position: Int) = position.toLong() - - override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { - var cView = convertView - val holder: AdapterAppErrorsRecordBinding - if (convertView == null) { - holder = AdapterAppErrorsRecordBinding.inflate(LayoutInflater.from(context)) - cView = holder.root - cView.tag = holder - } else holder = convertView.tag as AdapterAppErrorsRecordBinding - getItem(position).also { - holder.appIcon.setImageDrawable(appIcon(it.packageName)) - holder.appNameText.text = appName(it.packageName) - holder.errorsTimeText.text = it.crossTime - holder.errorTypeIcon.setImageResource(if (it.isNativeCrash) R.drawable.ic_cpp else R.drawable.ic_java) - holder.errorTypeText.text = if (it.isNativeCrash) "Native crash" else it.exceptionClassName.let { text -> + bindAdapter { + onBindDatas { listData } + onBindViews { binding, position -> + listData[position].also { bean -> + binding.appIcon.setImageDrawable(appIcon(bean.packageName)) + binding.appNameText.text = appName(bean.packageName) + binding.errorsTimeText.text = bean.crossTime + binding.errorTypeIcon.setImageResource(if (bean.isNativeCrash) R.drawable.ic_cpp else R.drawable.ic_java) + binding.errorTypeText.text = if (bean.isNativeCrash) "Native crash" else bean.exceptionClassName.let { text -> if (text.contains(other = ".")) text.split(".").let { e -> e[e.lastIndex] } else text } - holder.errorMsgText.text = it.exceptionMessage + binding.errorMsgText.text = bean.exceptionMessage } - return cView!! } }.apply { onChanged = { notifyDataSetChanged() } } registerForContextMenu(this) diff --git a/app/src/main/java/com/fankes/apperrorstracking/utils/factory/BaseAdapterFactory.kt b/app/src/main/java/com/fankes/apperrorstracking/utils/factory/BaseAdapterFactory.kt new file mode 100644 index 0000000..a26eebc --- /dev/null +++ b/app/src/main/java/com/fankes/apperrorstracking/utils/factory/BaseAdapterFactory.kt @@ -0,0 +1,86 @@ +/* + * AppErrorsTracking - Added more features to app's crash dialog, fixed custom rom deleted dialog, the best experience to Android developer. + * Copyright (C) 2019-2022 Fankes Studio(qzmmcn@163.com) + * https://github.com/KitsunePie/AppErrorsTracking + * + * This software is non-free but opensource software: you can redistribute it + * and/or modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * and eula along with this software. If not, see + * + * + * This file is Created by fankes on 2022/6/3. + */ +package com.fankes.apperrorstracking.utils.factory + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.BaseAdapter +import android.widget.ListView +import androidx.viewbinding.ViewBinding +import com.highcapable.yukihookapi.hook.factory.method +import com.highcapable.yukihookapi.hook.type.android.LayoutInflaterClass + +/** + * 绑定 [BaseAdapter] 到 [ListView] + * @param initiate 方法体 + * @return [BaseAdapter] + */ +inline fun ListView.bindAdapter(initiate: BaseAdapterCreater.() -> Unit) = + BaseAdapterCreater(context).apply(initiate).baseAdapter?.apply { adapter = this } ?: error("BaseAdapter not binded") + +/** + * [BaseAdapter] 创建类 + * @param context 实例 + */ +class BaseAdapterCreater(val context: Context) { + + /** 当前 [List] 回调 */ + var listDataCallback: (() -> List<*>)? = null + + /** 当前 [BaseAdapter] */ + var baseAdapter: BaseAdapter? = null + + /** + * 绑定 [List] 到 [ListView] + * @param result 回调数据 + */ + fun onBindDatas(result: (() -> List<*>)) { + listDataCallback = result + } + + /** + * 绑定 [BaseAdapter] 到 [ListView] + * @param bindViews 回调 - ([VB] 每项,[Int] 下标) + */ + inline fun onBindViews(crossinline bindViews: (binding: VB, position: Int) -> Unit) { + baseAdapter = object : BaseAdapter() { + override fun getCount() = listDataCallback?.let { it() }?.size ?: 0 + override fun getItem(position: Int) = listDataCallback?.let { it() }?.get(position) + override fun getItemId(position: Int) = position.toLong() + override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { + var holderView = convertView + val holder: VB + if (convertView == null) { + holder = VB::class.java.method { + name = "inflate" + param(LayoutInflaterClass) + }.get().invoke(LayoutInflater.from(context)) ?: error("ViewHolder binding failed") + holderView = holder.root.apply { tag = holder } + } else holder = convertView.tag as VB + bindViews(holder, position) + return holderView ?: error("ViewHolder binding failed") + } + } + } +} \ No newline at end of file