This commit is contained in:
zyp
2026-07-09 10:11:25 +08:00
commit f632730452
2156 changed files with 764537 additions and 0 deletions

View File

@@ -0,0 +1,453 @@
package dji.sampleV5.aircraft.keyvalue
import android.content.Context
import android.view.View
import dji.sampleV5.aircraft.util.Util
import dji.v5.utils.common.LogUtils
import java.lang.Exception
import java.lang.StringBuilder
import java.lang.reflect.Field
import java.lang.reflect.ParameterizedType
import java.util.*
/**
* @author feel.feng
* @time 2022/03/10 11:23 上午
* @description:
*/
object KeyItemHelper {
val TAG = LogUtils.getTag(this)
val LISTEN_RECORD_MAX_LENGTH = 2000
val FILED_CHANGE = "\$change"
/**
* 通过反射给字段赋值
*
* @param obj
*/
fun initSubItemData(obj: Any): Map<String?, List<EnumItem>> {
val dataMap: MutableMap<String?, List<EnumItem>> = HashMap()
try {
val fields = obj.javaClass.declaredFields
for (field in fields) {
if (field.name == FILED_CHANGE || field.name == "serialVersionUID") {
continue
}
val clazz = field.type
if (clazz.isEnum) {
dataMap[clazz.canonicalName] =
buildParamsSubItemListWithEnum(field.type as Class<Enum<*>>)
} else if (isEnumList(field)) {
val type = field.genericType
if (type is ParameterizedType) {
val subObject: Class<out Enum<*>> =
type.actualTypeArguments[0] as Class<Enum<*>>
dataMap[clazz.canonicalName] = buildParamsSubItemListWithEnum(subObject)
}
} else {
dataMap.clear()
break
}
}
} catch (e: Exception) {
LogUtils.e(TAG,e.message)
}
return dataMap
}
/**
* 处理界面参数选择和设置
*
* @param anchor
* @param dataMap
*/
fun <P> processSubListLogic(
anchor: View,
param: P,
dataMap: Map<String?, List<EnumItem>>,
callBack: KeyItemActionListener<String?>
) {
try {
val nameList = Util.getMapKeyList(dataMap)
val subItemList = Util.getMapValueList(dataMap)
if (dataMap.size == 1) {
//简单列表
val list = subItemList[0]
val clazz = Class.forName(nameList[0]!!) as Class<Enum<*>>
showSimpleSubItemList(anchor.context, list, clazz, object :
KeyItemActionListener<List<String>?> {
override fun actionChange(t: List<String>?) {
updateClassData(param, dataMap)
callBack.actionChange(param.toString())
}
})
} else {
//复合列表
KeyValueDialogUtil.showListConfirmWindow(
anchor,
getSimpleNameList(nameList),
"select item for setting",
object :
KeyItemActionListener<String?> {
override fun actionChange(msg: String?) {
if ("confirm" == msg) {
updateClassData(param, dataMap)
callBack.actionChange(param.toString())
} else {
val clazz = getClassWithName(msg, nameList) as Class<Enum<*>>?
val list = dataMap[clazz!!.canonicalName]!!
showSimpleSubItemList(
anchor.context,
list,
clazz
) { updateClassData(param, dataMap) }
}
}
})
}
} catch (e: ClassNotFoundException) {
LogUtils.e(TAG , e.message)
}
}
/**
* 类名列表获取通过全名list获取简名list
*
* @param nameList
* @return
*/
fun getSimpleNameList(nameList: List<String?>): List<String> {
val simpleNameList: MutableList<String> = ArrayList()
for (str in nameList) {
simpleNameList.add(str!!.substring(str!!.lastIndexOf(".") + 1))
}
return simpleNameList
}
/**
* 通过简名获取类字节码
*
* @param simpleName
* @param nameList
* @return
*/
fun getClassWithName(simpleName: String?, nameList: List<String?>): Class<*>? {
var clazz: Class<*>? = null
try {
for (str in nameList) {
if (str!!.endsWith(simpleName!!)) {
clazz = Class.forName(str!!)
break
}
}
} catch (e: ClassNotFoundException) {
LogUtils.e(TAG , e.message)
}
return clazz
}
/**
* 构建参数条目的选项子列表
*
* @param <E>
* @return
</E> */
fun <E : Enum<*>?> buildParamsSubItemListWithEnum(clazz: Class<E>): List<EnumItem> {
val list: MutableList<EnumItem> = ArrayList()
try {
var item: EnumItem
val objs: Array<out E>? = clazz.getEnumConstants()
for (obj in objs!!) {
item = EnumItem()
item.setName(obj.toString())
list.add(item)
}
} catch (e: Exception) {
LogUtils.e(TAG,e.message)
}
return list
}
/**
* 获取属性子列表数据
*
* @param data
* @return
*/
fun getSubItemNameList(data: List<EnumItem>): List<String> {
val result: MutableList<String> = ArrayList()
for (item in data) {
result.add(item.getName().toString())
}
return result
}
/**
* 获取选中属性的顺序值
*
* @param data
* @return
*/
fun getSelectedIndex(data: List<EnumItem>): Int {
var index = 0
for (i in data.indices) {
if (data[i].isSelected()) {
index = i
break
}
}
return index
}
/**
* 获取选中属性的value
*
* @param data
* @return
*/
fun getSelectedValue(data: List<EnumItem>): String {
var value = ""
for (i in data.indices) {
if (data[i].isSelected()) {
value = data[i].getName().toString()
break
}
}
return value
}
/**
* 更新选择状态
*
* @param data
* @param name
*/
fun updatedSelectedInfo(data: List<EnumItem>, names: List<String?>) {
for (item in data) {
item.setSelected(false)
for (name in names) {
if (item.getName().equals(name)) {
item.setSelected(true)
}
}
}
}
/**
* 简单参数列表,逻辑处理
*/
fun <E : Enum<*>?> showSimpleSubItemList(
context: Context?,
simpleItemList: List<EnumItem>,
clazz: Class<E>,
callBack: KeyItemActionListener<List<String>?>
) {
val StrList = getSubItemNameList(simpleItemList)
if (StrList.size == 0) {
return
}
val selectedIndex = getSelectedIndex(simpleItemList)
if (clazz.isEnum) {
KeyValueDialogUtil.showSingleChoiceDialog(
context,
StrList,
selectedIndex,
object : KeyItemActionListener<List<String>?> {
override fun actionChange(values: List<String>?) {
updatedSelectedInfo(simpleItemList, values!!)
callBack.actionChange(values)
}
})
} else {
KeyValueDialogUtil.showMultiChoiceDialog(
context,
StrList,
) { values ->
updatedSelectedInfo(simpleItemList, values!!)
callBack.actionChange(values)
}
}
}
/**
* 通过反射给字段赋值
*
* @param obj
*/
fun initClassData(obj: Any?) {
if (obj == null || Util.isBlank(obj.toString())) {
return
}
try {
val pFields = obj.javaClass.declaredFields
for (field in pFields) {
if (field.name == FILED_CHANGE || field.name == "serialVersionUID") {
continue
}
field.isAccessible = true
val clazz = field.type
if (setFieldPro(field , obj)){
continue
}
val subObj = clazz.newInstance()
field[obj] = subObj
initClassData(subObj)
}
} catch (e: Exception) {
LogUtils.e(TAG, e.message)
}
}
fun setFieldPro(field:Field , obj: Any?):Boolean{
val clazz = field.type
if (clazz.isEnum) {
field[obj] = clazz.enumConstants!![0]
return true;
}
if (Util.isWrapClass(clazz)) {
if (clazz == Boolean::class.javaObjectType) {
field[obj] = false
}
//如果需要 可在else 中可给Integer Double 等设置初始值
return true
}
if (clazz == MutableList::class.java) {
field[obj] = ArrayList<Any>()// todo
return true
} else if (clazz == String::class.java) {
field[obj] = ""
return true
}
return false
}
private fun isEnumList(field: Field): Boolean {
if (field.type == MutableList::class.java) {
val type = field.genericType
if (type is ParameterizedType) {
val subType = type.actualTypeArguments[0]
val clazz = subType as Class<*>
if (clazz.isEnum) {
return true
}
}
}
return false
}
/**
* 通过反射给字段赋值
*
* @param obj
*/
fun updateClassData(obj: Any?, subItemMap: Map<String?, List<EnumItem>>) {
try {
val pFields = obj?.javaClass?.declaredFields
if (pFields != null) {
for (field in pFields) {
if (field.name == FILED_CHANGE || field.name == "serialVersionUID") {
continue
}
field.isAccessible = true
val clazz = field.type
if (clazz.isEnum) {
val itemList = subItemMap[clazz.canonicalName]!!
field[obj] = getEnumData(clazz as Class<Enum<*>>, getSelectedValue(itemList))
} else if (isEnumList(field)) {
setEnumListProperty(field , obj , subItemMap)
}
}
}
} catch (e: Exception) {
LogUtils.e(TAG , e.message)
}
}
fun setEnumListProperty(field: Field , obj: Any? , subItemMap: Map<String?, List<EnumItem>>) {
val type = field.genericType
val clazz = field.type
if (type is ParameterizedType) {
val subObject = type.actualTypeArguments[0] as Class<Enum<*>>
val itemList = subItemMap[clazz.canonicalName]
val list: MutableList<Any> = ArrayList()
val values: List<String> = getSelectedValues(itemList!!)
for (value in values) {
val test: Any = getEnumData(subObject, value)!!
list.add(test)
}
field[obj] = list
}
}
fun getSelectedValues(data: List<EnumItem>): List<String> {
var value: String = ""
val values: MutableList<String> = ArrayList()
for (i in data.indices) {
if (data[i].isSelected()) {
value = data[i].getName()!!
values.add(value)
continue
}
}
return values
}
/**
* 追加携带日期的推送字符串
*
* @param targetStr
* @param appendStr
* @return
*/
fun appendListenRecord(targetStr: String, appendStr: String?): String {
if (Util.isBlank(appendStr)) {
return targetStr
}
val sb = StringBuilder(targetStr)
sb.append("\n")
sb.append(Util.getDateStr(Date()) + ":")
sb.append("\n")
sb.append(appendStr)
//长度限制
var result = sb.toString()
if (result.length > LISTEN_RECORD_MAX_LENGTH) {
result = result.substring(result.length - LISTEN_RECORD_MAX_LENGTH)
}
val title = "push info:"
if (!result.startsWith(title)) {
result = """
$title
$result
""".trimIndent()
}
return result
}
/**
* 通过字节码和值来获取实例
*
* @param clazz
* @param value
* @param <E>
* @return
</E> */
fun <E : Enum<*>?> getEnumData(clazz: Class<E>, value: String): E? {
var data: E? = null
try {
val objs: Array<out E>? = clazz.getEnumConstants()
for (obj in objs!!) {
if (obj.toString() == value) {
data = obj as E
break
}
}
} catch (e: Exception) {
LogUtils.e(TAG , e.message)
}
return data
}
}