Merge ListView's adapter to BaseAdapterFactory

This commit is contained in:
2022-06-03 01:59:29 +08:00
parent 8635ad3874
commit 2c4e4f5090
2 changed files with 99 additions and 26 deletions

View File

@@ -25,9 +25,10 @@ package com.fankes.apperrorstracking.ui.activity.errors
import android.app.Activity import android.app.Activity
import android.content.Intent 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.AdapterView.AdapterContextMenuInfo
import android.widget.BaseAdapter
import androidx.core.view.isVisible import androidx.core.view.isVisible
import com.fankes.apperrorstracking.R import com.fankes.apperrorstracking.R
import com.fankes.apperrorstracking.bean.AppErrorsInfoBean import com.fankes.apperrorstracking.bean.AppErrorsInfoBean
@@ -83,33 +84,19 @@ class AppErrorsRecordActivity : BaseActivity<ActivityAppErrorsRecordBinding>() {
} }
/** 设置列表元素和 Adapter */ /** 设置列表元素和 Adapter */
binding.listView.apply { binding.listView.apply {
adapter = object : BaseAdapter() { bindAdapter {
onBindDatas { listData }
override fun getCount() = listData.size onBindViews<AdapterAppErrorsRecordBinding> { binding, position ->
listData[position].also { bean ->
override fun getItem(position: Int) = listData[position] binding.appIcon.setImageDrawable(appIcon(bean.packageName))
binding.appNameText.text = appName(bean.packageName)
override fun getItemId(position: Int) = position.toLong() binding.errorsTimeText.text = bean.crossTime
binding.errorTypeIcon.setImageResource(if (bean.isNativeCrash) R.drawable.ic_cpp else R.drawable.ic_java)
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { binding.errorTypeText.text = if (bean.isNativeCrash) "Native crash" else bean.exceptionClassName.let { text ->
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 ->
if (text.contains(other = ".")) text.split(".").let { e -> e[e.lastIndex] } else 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() } } }.apply { onChanged = { notifyDataSetChanged() } }
registerForContextMenu(this) registerForContextMenu(this)

View File

@@ -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
* <https://www.gnu.org/licenses/>
*
* 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 <reified VB : ViewBinding> 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<VB>(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")
}
}
}
}