我的数据类:

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
    }
}

MainActivity:

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中,用户的大厅详细信息将保存在共享首选项中

首先,大厅详细信息转换为json(字符串),之后jsonString将保存在sharedPreferences中:

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

现在,当用户打开应用程序时,我有一个变量"json_save",它从sharedPreferences接收jsonString

并且,变量"After_json_save"保存了uses gson to convert json to my data class mutableList

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

When I log this variable, after reopening app my saved data is correctly shown in this variable but the app crashes!

并且这个变量应该添加到userList(和我的对象"data"中我的halData变量中-&gt;不重要)

但该应用程序崩溃,并出现以下错误:

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

And the error contains these lines of UserAdapter (Error is related to onBindViewHolder):

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

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

您的帮助将不胜感激

推荐答案

这是因为mutableListOf<HallData>()::class.java中的type erasure.它丢失了它是HallData的信息,并将其反序列化为LinkedTreeMap

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

Json相关问答推荐

抓取低于w jolt的对象级别

如何创建生成两个不同对象的JSON数组的SQL查询?

使用JQ合并JSON列表中的对象

用 Jolt 替换 JSON 中的值

NoneType 对象的 Python 类型错误

如何在 JSonPath 中按值查找列表中的所有元素

使用杰克逊解析Kotlin 中的通用密封类

使用 Jolt 变换将平面 json 转换为具有多个数组的嵌套 Json

传统编程语言等价于动态 SQL

Google GCM 服务器返回未经授权的错误 401

如何使用 gson 调用默认反序列化

如何使用 Newtonsoft.Json 反序列化 JSON 数组

使用非美国日期格式时,JsonConvert.DeserializeObject 无法将字符串转换为 DateTime

使用 @ResponseBody 自定义 HttpMessageConverter 来做 Json 事情

使用 Spring 和 JsonTypeInfo 注释将 JSON 反序列化为多态对象模型

什么是类型和类型令牌?

TypeError: b'1' 不是 JSON 可序列化的

我可以使用空字符串作为对象标识符吗?

如何将 mysqli 结果转换为 JSON?

你如何在 Arrays of Arrays 上 OPENJSON