(Kotlin)com.google.gson.internal.LinkedTreeMap 无法转换为 com.example.phonetest2.model.HallData

问题描述 投票:0回答:1

我的数据类:

data class HallData(
var name:String,
var mobile:String,
var isAddInfoChecked:Boolean,
var isFanDetailChecked:Boolean,
var fanNumber:String,
var isPompDetailChecked:Boolean,
var pompNumber:String,
var isHeaterDetailChecked:Boolean,
var heaterNumber:String,
var isCircularFanDetailChecked:Boolean,
var circularFanNumber:String
)

用户适配器:

class UserAdapter(val c: Context, val userList: MutableList<HallData>) :
    RecyclerView.Adapter<UserAdapter.UserViewHolder>() {


    inner class UserViewHolder(val v: View) : RecyclerView.ViewHolder(v) {
        var name: TextView
        var mbNum: TextView
        var mMenus: ImageView
        var fanText: TextView
        var pompText: TextView
        var heaterText: TextView
        var circularFanText: TextView
        var fanNum: TextView
        var pompNum: TextView
        var heaterNum: TextView
        var circularFanNum: TextView

        init {
            name = v.findViewById<TextView>(R.id.mTitle)
            mbNum = v.findViewById<TextView>(R.id.mSubTitle)
            mMenus = v.findViewById(R.id.mMenus)
            mMenus.setOnClickListener { popupMenus(it) }
            fanText = v.findViewById(R.id.fan_text)
            pompText = v.findViewById(R.id.pomp_text)
            heaterText = v.findViewById(R.id.heater_text)
            circularFanText = v.findViewById(R.id.circular_text)
            fanNum = v.findViewById(R.id.fan_number)
            pompNum = v.findViewById(R.id.pomp_number)
            heaterNum = v.findViewById(R.id.heater_number)
            circularFanNum = v.findViewById(R.id.circular_number)

            fanText.visibility = View.GONE
            pompText.visibility = View.GONE
            heaterText.visibility = View.GONE
            circularFanText.visibility = View.GONE
            fanNum.visibility = View.GONE
            pompNum.visibility = View.GONE
            heaterNum.visibility = View.GONE
            circularFanNum.visibility = View.GONE

        }

        private fun popupMenus(v: View) {
            val position = userList[adapterPosition]
            val popupMenus = PopupMenu(c, v)
            popupMenus.inflate(R.menu.show_menu)
            popupMenus.setOnMenuItemClickListener {
                when (it.itemId) {
                    R.id.editText -> {
                        val v = LayoutInflater.from(c).inflate(R.layout.add_hall, null)
                        val name = v.findViewById<EditText>(R.id.userName)
                        val number = v.findViewById<EditText>(R.id.userNo)
                        val addInfoCheckBox = v.findViewById<CheckBox>(R.id.add_info_checkBox)
                        val fanCheckBox = v.findViewById<CheckBox>(R.id.fan_checkbox)
                        val pompCheckBox = v.findViewById<CheckBox>(R.id.pomp_checkbox)
                        val heaterCheckBox = v.findViewById<CheckBox>(R.id.heater_checkbox)
                        val circularFanCheckBox = v.findViewById<CheckBox>(R.id.circular_checkbox)
                        val fanNumberPicker = v.findViewById<NumberPicker>(R.id.fan_number_picker)
                        val pompNumberPicker = v.findViewById<NumberPicker>(R.id.pomp_number_picker)
                        val heaterNumberPicker =
                            v.findViewById<NumberPicker>(R.id.heater_number_picker)
                        val circularFanNumberPicker =
                            v.findViewById<NumberPicker>(R.id.circular_number_picker)
                        val fanLayout = v.findViewById<ConstraintLayout>(R.id.fan_layout)
                        val pompLayout = v.findViewById<ConstraintLayout>(R.id.pomp_layout)
                        val heaterLayout = v.findViewById<ConstraintLayout>(R.id.heater_layout)
                        val circularFanLayout = v.findViewById<ConstraintLayout>(R.id.circular_layout)
                        val fanNumberPreview = v.findViewById<TextView>(R.id.fan_number_preview)
                        val pompNumberPreview = v.findViewById<TextView>(R.id.pomp_number_preview)
                        val heaterNumberPreview = v.findViewById<TextView>(R.id.heater_number_preview)
                        val circularFanNumberPreview = v.findViewById<TextView>(R.id.circular_number_preview)
                        var fanNumber = 0
                        var pompNumber = 0
                        var heaterNumber = 0
                        var circularFanNumber = 0

                        addInfoCheckBox.setOnCheckedChangeListener { buttonView, isChecked ->
                            if (addInfoCheckBox.isChecked) {
                                Toast.makeText(c, "Checked", Toast.LENGTH_SHORT).show()
                                fanLayout.visibility = View.VISIBLE
                                pompLayout.visibility = View.VISIBLE
                                heaterLayout.visibility = View.VISIBLE
                                circularFanLayout.visibility = View.VISIBLE
                                fanNumberPicker.visibility = View.GONE
                                fanNumberPreview.visibility = View.GONE
                                pompNumberPicker.visibility = View.GONE
                                pompNumberPreview.visibility = View.GONE
                                heaterNumberPicker.visibility = View.GONE
                                heaterNumberPreview.visibility = View.GONE
                                circularFanNumberPicker.visibility = View.GONE
                                circularFanNumberPreview.visibility = View.GONE
                                //Fan Setting:
                                fanCheckBox.setOnCheckedChangeListener { buttonView, isChecked ->
                                    if (fanCheckBox.isChecked) {
                                        fanCheckBox.setBackgroundResource(R.drawable.green_stroke)
                                        fanNumberPicker.visibility = View.VISIBLE
                                        fanNumberPreview.visibility = View.VISIBLE
                                        fanNumberPicker.minValue = 0
                                        fanNumberPicker.maxValue = maxNumberPickerValue
                                        fanNumberPicker.setOnValueChangedListener { picker, oldVal, newVal ->
                                            fanNumberPreview.text = "تعداد فن : $newVal"
                                            fanNumber = newVal
                                        }
                                    } else {
                                        fanNumberPicker.visibility = View.GONE
                                        fanNumberPreview.visibility = View.GONE
                                        fanCheckBox.setBackgroundResource(R.drawable.red_stroke)
                                    }
                                }


                                //Pomp Setting:
                                pompCheckBox.setOnCheckedChangeListener { buttonView, isChecked ->
                                    if (pompCheckBox.isChecked) {
                                        pompCheckBox.setBackgroundResource(R.drawable.green_stroke)
                                        pompNumberPicker.visibility = View.VISIBLE
                                        pompNumberPreview.visibility = View.VISIBLE
                                        pompNumberPicker.minValue = 0
                                        pompNumberPicker.maxValue = maxNumberPickerValue
                                        pompNumberPicker.setOnValueChangedListener { picker, oldVal, newVal ->
                                            pompNumberPreview.text = "تعداد پمپ : $newVal"
                                            pompNumber = newVal
                                        }
                                    } else {
                                        pompCheckBox.setBackgroundResource(R.drawable.red_stroke)
                                        pompNumberPicker.visibility = View.GONE
                                        pompNumberPreview.visibility = View.GONE
                                    }
                                }

                                //Heater Setting:
                                heaterCheckBox.setOnCheckedChangeListener { buttonView, isChecked ->
                                    if (heaterCheckBox.isChecked) {
                                        heaterCheckBox.setBackgroundResource(R.drawable.green_stroke)
                                        heaterNumberPicker.visibility = View.VISIBLE
                                        heaterNumberPreview.visibility = View.VISIBLE
                                        heaterNumberPicker.minValue = 0
                                        heaterNumberPicker.maxValue = maxNumberPickerValue
                                        heaterNumberPicker.setOnValueChangedListener { picker, oldVal, newVal ->
                                            heaterNumberPreview.text = "تعداد هیتر : $newVal"
                                            heaterNumber = newVal
                                        }
                                    } else {
                                        heaterCheckBox.setBackgroundResource(R.drawable.red_stroke)
                                        heaterNumberPicker.visibility = View.GONE
                                        heaterNumberPreview.visibility = View.GONE
                                    }
                                }

                                //CircularFan Setting:
                                circularFanCheckBox.setOnCheckedChangeListener { buttonView, isChecked ->
                                    if (circularFanCheckBox.isChecked) {
                                        circularFanCheckBox.setBackgroundResource(R.drawable.green_stroke)
                                        circularFanNumberPicker.visibility = View.VISIBLE
                                        circularFanNumberPreview.visibility = View.VISIBLE
                                        circularFanNumberPicker.minValue = 0
                                        circularFanNumberPicker.maxValue = maxNumberPickerValue
                                        circularFanNumberPicker.setOnValueChangedListener { picker, oldVal, newVal ->
                                            circularFanNumberPreview.text = "تعداد فن : $newVal"
                                            circularFanNumber = newVal
                                        }


                                    } else {
                                        circularFanCheckBox.setBackgroundResource(R.drawable.red_stroke)
                                        circularFanNumberPicker.visibility = View.GONE
                                        circularFanNumberPreview.visibility = View.GONE
                                    }
                                }


                            } else {
                                Toast.makeText(c, "Unchecked", Toast.LENGTH_SHORT).show()
                                fanLayout.visibility = View.GONE
                                pompLayout.visibility = View.GONE
                                heaterLayout.visibility = View.GONE
                                circularFanLayout.visibility = View.GONE
                            }
                        }

                        name.setText(hallData[adapterPosition].name)
                        number.setText(hallData[adapterPosition].mobile)
                        AlertDialog.Builder(c)
                            .setView(v)
                            .setPositiveButton("ویرایش") { dialog, _ ->
                                position.name = name.text.toString()
                                position.mobile = number.text.toString()
                                Names[adapterPosition] = name.text.toString()
                                Phones[adapterPosition] = number.text.toString()
                                hallData[adapterPosition] = HallData(name.text.toString(),number.text.toString(),addInfoCheckBox.isChecked,fanCheckBox.isChecked,fanNumber.toString(),pompCheckBox.isChecked,pompNumber.toString(),heaterCheckBox.isChecked,heaterNumber.toString(),circularFanCheckBox.isChecked,circularFanNumber.toString())
                                notifyDataSetChanged()
                                Toast.makeText(c, "داده مورد نظر ویرایش شد", Toast.LENGTH_SHORT)
                                    .show()
                                dialog.dismiss()

                            }
                            .setNegativeButton("لغو") { dialog, _ ->
                                dialog.dismiss()

                            }
                            .create()
                            .show()

                        true
                    }

                    R.id.delete -> {
                        /**set delete*/
                        AlertDialog.Builder(c)
                            .setTitle("حذف «${Names[adapterPosition]}»")
                            .setIcon(R.drawable.ic_warning)
                            .setMessage("آیا از حذف این داده مطمئن هستید؟")
                            .setPositiveButton("بله") { dialog, _ ->
                                userList.removeAt(adapterPosition)
                                //Log.d("TAG","Names -> "+Data.Phones)
                                Data.number--
                                Names.removeAt(adapterPosition)
                                Phones.removeAt(adapterPosition)
                                hallData.removeAt(adapterPosition)
                                //Log.d("TAG","Message -> Removed")
                                notifyDataSetChanged()
                                Toast.makeText(c, "داده مورد نظر حذف شد", Toast.LENGTH_SHORT).show()
                                dialog.dismiss()
                            }
                            .setNegativeButton("خیر") { dialog, _ ->
                                dialog.dismiss()
                            }
                            .create()
                            .show()

                        true
                    }

                    else -> true
                }

            }
            popupMenus.show()
            val popup = PopupMenu::class.java.getDeclaredField("mPopup")
            popup.isAccessible = true
            val menu = popup.get(popupMenus)
            menu.javaClass.getDeclaredMethod("setForceShowIcon", Boolean::class.java)
                .invoke(menu, true)
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
        val inflater = LayoutInflater.from(parent.context)
        val v = inflater.inflate(R.layout.hall_item, parent, false)
        return UserViewHolder(v)
    }

    override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
        val newList = userList[position]
        holder.name.text = newList.name
        holder.mbNum.text = newList.mobile
        if(Data.hallData[position].isAddInfoChecked){
            holder.fanNum.text = newList.fanNumber.toString()
            holder.pompNum.text = newList.pompNumber.toString()
            holder.heaterNum.text = newList.heaterNumber.toString()
            holder.circularFanNum.text = newList.circularFanNumber.toString()

            holder.fanText.visibility = View.VISIBLE
            holder.pompText.visibility = View.VISIBLE
            holder.heaterText.visibility = View.VISIBLE
            holder.circularFanText.visibility = View.VISIBLE
            holder.fanNum.visibility = View.VISIBLE
            holder.pompNum.visibility = View.VISIBLE
            holder.heaterNum.visibility = View.VISIBLE
            holder.circularFanNum.visibility = View.VISIBLE
        }else{
            holder.fanText.visibility = View.GONE
            holder.pompText.visibility = View.GONE
            holder.heaterText.visibility = View.GONE
            holder.circularFanText.visibility = View.GONE
            holder.fanNum.visibility = View.GONE
            holder.pompNum.visibility = View.GONE
            holder.heaterNum.visibility = View.GONE
            holder.circularFanNum.visibility = View.GONE
        }
    }

    override fun getItemCount(): Int {
        return userList.size
    }
}

主要活动:

class MainActivity : AppCompatActivity() {

    private lateinit var addsBtn: FloatingActionButton
    private lateinit var recv: RecyclerView
    private lateinit var userList: MutableList<HallData>
    private lateinit var userAdapter: UserAdapter
    private lateinit var addInfoCheckBox: CheckBox
    private var backPressedTime = 0L
    lateinit var jsonString:String

    var gson = Gson()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        /**set List*/
        userList = ArrayList()
        /**set find Id*/
        addsBtn = findViewById(R.id.addingBtn)
        recv = findViewById(R.id.mRecycler)
        /**set Adapter*/
        userAdapter = UserAdapter(this,userList)
        /**setRecycler view Adapter*/
        recv.layoutManager = LinearLayoutManager(this)
        recv.adapter = userAdapter
        /**set Dialog*/
        addsBtn.setOnClickListener { addInfo() }
        Data.hallData.clear()
        Data.number=0
        Data.Names.clear()
        Data.Phones.clear()

        val sharedPrefsMain = getSharedPreferences("my_prefs", MODE_PRIVATE)
        val json_saved = sharedPrefsMain.getString("JsonHallData",null)
        val after_json_saved = gson.fromJson(json_saved, mutableListOf<HallData>()::class.java)

        if(!after_json_saved.isNullOrEmpty()){
        for (i in 0 until after_json_saved.size){
            try }
                userList.add(after_json_saved[i])
                Data.hallData.add(after_json_saved[i])

            } catch (e:Exception){
                Log.e("ERROR",e.message.toString())
            }

        }

        }
    }

    private fun addInfo() {
        val inflter = LayoutInflater.from(this)
        val v = inflter.inflate(R.layout.add_hall,null)
        /**set view*/
        val userName = v.findViewById<EditText>(R.id.userName)
        val userNo = v.findViewById<EditText>(R.id.userNo)

        val addInfoCheckBox = v.findViewById<CheckBox>(R.id.add_info_checkBox)
        val fanCheckBox = v.findViewById<CheckBox>(R.id.fan_checkbox)
        val pompCheckBox = v.findViewById<CheckBox>(R.id.pomp_checkbox)
        val heaterCheckBox = v.findViewById<CheckBox>(R.id.heater_checkbox)
        val circularFanCheckBox = v.findViewById<CheckBox>(R.id.circular_checkbox)
        val fanNumberPicker = v.findViewById<NumberPicker>(R.id.fan_number_picker)
        val pompNumberPicker = v.findViewById<NumberPicker>(R.id.pomp_number_picker)
        val heaterNumberPicker =
            v.findViewById<NumberPicker>(R.id.heater_number_picker)
        val circularFanNumberPicker =
            v.findViewById<NumberPicker>(R.id.circular_number_picker)
        val fanLayout = v.findViewById<ConstraintLayout>(R.id.fan_layout)
        val pompLayout = v.findViewById<ConstraintLayout>(R.id.pomp_layout)
        val heaterLayout = v.findViewById<ConstraintLayout>(R.id.heater_layout)
        val circularFanLayout = v.findViewById<ConstraintLayout>(R.id.circular_layout)
        val fanNumberPreview = v.findViewById<TextView>(R.id.fan_number_preview)
        val pompNumberPreview = v.findViewById<TextView>(R.id.pomp_number_preview)
        val heaterNumberPreview = v.findViewById<TextView>(R.id.heater_number_preview)
        val circularFanNumberPreview = v.findViewById<TextView>(R.id.circular_number_preview)
        var fanNumber = 0
        var pompNumber = 0
        var heaterNumber = 0
        var circularFanNumber = 0

        addInfoCheckBox.setOnCheckedChangeListener { buttonView, isChecked ->
            if (addInfoCheckBox.isChecked) {
                fanLayout.visibility = View.VISIBLE
                pompLayout.visibility = View.VISIBLE
                heaterLayout.visibility = View.VISIBLE
                circularFanLayout.visibility = View.VISIBLE
                fanNumberPicker.visibility = View.GONE
                fanNumberPreview.visibility = View.GONE
                pompNumberPicker.visibility = View.GONE
                pompNumberPreview.visibility = View.GONE
                heaterNumberPicker.visibility = View.GONE
                heaterNumberPreview.visibility = View.GONE
                circularFanNumberPicker.visibility = View.GONE
                circularFanNumberPreview.visibility = View.GONE
                //Fan Setting:
                fanCheckBox.setOnCheckedChangeListener { buttonView, isChecked ->
                    if (fanCheckBox.isChecked) {
                        fanCheckBox.setBackgroundResource(R.drawable.green_stroke)
                        fanNumberPicker.visibility = View.VISIBLE
                        fanNumberPreview.visibility = View.VISIBLE
                        fanNumberPicker.minValue = 0
                        fanNumberPicker.maxValue = Data.maxNumberPickerValue
                        fanNumberPicker.setOnValueChangedListener { picker, oldVal, newVal ->                                fanNumberPreview.text = "تعداد فن : $newVal"
                            fanNumber = newVal
                        }
                    } else {
                        fanNumberPicker.visibility = View.GONE
                        fanNumberPreview.visibility = View.GONE
                        fanCheckBox.setBackgroundResource(R.drawable.red_stroke)
                    }
                }


                //Pomp Setting:
                ...

                //Heater Setting:
                ...

                //CircularFan Setting:
...


            } else {
                fanLayout.visibility = View.GONE
                pompLayout.visibility = View.GONE
                heaterLayout.visibility = View.GONE
                circularFanLayout.visibility = View.GONE
            }
        }

        val addDialog = AlertDialog.Builder(this)
        addDialog.setView(v)


        addDialog.setPositiveButton("افزودن"){
                dialog,_->


            val names = userName.text.toString()
            val number = userNo.text.toString()
            userList.add(HallData(
                names,
                number,
                addInfoCheckBox.isChecked,
                fanCheckBox.isChecked,
                fanNumber.toString(),
                pompCheckBox.isChecked,
                pompNumber.toString(),
                heaterCheckBox.isChecked,
                heaterNumber.toString(),
                circularFanCheckBox.isChecked,
                circularFanNumber.toString()
            ))
            userAdapter.notifyDataSetChanged()
            Data.number++
            Data.Names.add(names)
            Data.Phones.add(number)

                Data.hallData.add(HallData(
                    names,
                    number,
                    addInfoCheckBox.isChecked,
                    fanCheckBox.isChecked,
                    fanNumber.toString(),
                    pompCheckBox.isChecked,
                    pompNumber.toString(),
                    heaterCheckBox.isChecked,
                    heaterNumber.toString(),
                    circularFanCheckBox.isChecked,
                    circularFanNumber.toString()
                    ))

            Toast.makeText(this,"داده مورد نظر با موفقیت اضافه شد", Toast.LENGTH_SHORT).show()
            dialog.dismiss()
            }

        addDialog.setNegativeButton("لغو"){
                dialog,_->
            dialog.dismiss()
            Toast.makeText(this,"افزودن داده مورد نظر لغو شد", Toast.LENGTH_SHORT).show()

        }
        addDialog.create()
        addDialog.show()
    }

    /**ok now run this */
    override fun onPause() {
        super.onPause()
        val sharedPrefsOnPause = getSharedPreferences("my_prefs", MODE_PRIVATE)
        val mEditor = sharedPrefsOnPause.edit()
        mEditor.remove("Names")
        mEditor.remove("Phone")
        mEditor.remove("JsonHallData")



        jsonString = gson.toJson(Data.hallData)
        Log.d("JSON TAG","OnPause jsonString -> $jsonString")
        mEditor.putString("JsonHallData",jsonString)
        mEditor.apply()
    }

    override fun onBackPressed() {
        if(backPressedTime + 2000 > System.currentTimeMillis()){
            super.onBackPressed()
        } else{
            Toast.makeText(this, "برای خروج از برنامه، دوباره دکمه بازگشت را فشار دهید\n", Toast.LENGTH_SHORT).show()
        }
        backPressedTime = System.currentTimeMillis()

    }

}

在onPause中,用户的大厅详细信息将保存在sharedpreferences中

首先,大厅详细信息转换为 Json(字符串),然后 jsonString 将保存在共享首选项中:

    jsonString = gson.toJson(Data.hallData)
    
    mEditor.putString("JsonHallData",jsonString)
    mEditor.apply()

现在,当用户打开应用程序时,我有一个变量“json_saved”,它从共享首选项接收 jsonString

还有一个变量“after_json_saved”,使用 gson 将 json 转换为我的数据类 mutableList

val after_json_saved = gson.fromJson(json_saved, mutableListOf<HallData>()::class.java)

当我记录此变量时,重新打开应用程序后,我保存的数据正确显示在该变量中,但应用程序崩溃了!

这个变量应该添加到 userList (以及我的对象“数据”中的 HallData 变量 -> 不重要)

但是应用程序因以下错误而崩溃:

java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to com.example.phonetest2.model.HallData

错误包含UserAdapter的这些行(错误与onBindViewHolder有关):

  1. class UserAdapter(val c: Context, val userList: MutableList<HallData>) :
  2. val newList = userList[position]

我已阅读与此错误相关的可能答案,但我的问题尚未解决

您的帮助将不胜感激

android json kotlin android-studio gson
1个回答
0
投票

这是因为mutableListOf<HallData>()::class.java中的

类型擦除
。它丢失了它是
HallData
的信息,并将其反序列化为
LinkedTreeMap

请尝试将

val after_json_saved = gson.fromJson(json_saved, mutableListOf<HallData>()::class.java)
替换为
val after_json_saved = gson.fromJson(json_saved, object : TypeToken<MutableList<HallData>>() {})

© www.soinside.com 2019 - 2024. All rights reserved.