在Android的Room数据库中保存API数据

时间:2019-01-22 16:24:07

标签: android api kotlin android-room

我想通过改型从API中获取数据并将其保存在会议室数据库中。然后填充我的适配器,我将数据添加到“房间”中,但是当我单击用户列表中的某个元素时,向我显示数据列表时,我单击了X用户,它显示了另一个用户的数据。我还没弄清楚我的问题在哪里 这是我的代码:

class TutorsFragment : Fragment(), TutorListAdapter.ListItemClickListener, fromBackgroundToMainUIThread {


private var recyclerView: RecyclerView? = null
private var tutorListAdapter: TutorListAdapter? = null
private lateinit var tutors: List<Tutors>
private lateinit var tutorViewModel: StudentTutorViewModel

override fun onTutorsReceived(tutors: List<Tutors>) {
    this.tutors = tutors
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    val tutorView = inflater.inflate(R.layout.fragment_tutors, null)

    recyclerView = tutorView.findViewById<View>(R.id.recyclerview_tutors) as RecyclerView
    tutorViewModel = ViewModelProviders.of(this).get(StudentTutorViewModel::class.java)

    val layoutManager = LinearLayoutManager(this.activity, LinearLayoutManager.VERTICAL, false)
    recyclerView!!.layoutManager = layoutManager

    recyclerView!!.setHasFixedSize(true)

    tutorViewModel.getAllTutors().observe(viewLifecycleOwner, Observer {
        if (it != null) {
            tutorListAdapter = TutorListAdapter(it as MutableList<Tutor>?, this@TutorsFragment)
            recyclerView!!.adapter = tutorListAdapter
        }
    })

    val api = RetrofitClient.getInstance().apiService
    val call = api!!.tutorsList

    call.enqueue(object : Callback<List<Tutors>> {
        override fun onResponse(call: Call<List<Tutors>>, response: Response<List<Tutors>>) {

            Log.d("Tutors:  ", response.toString())
            val tutorsList = response.body()

            tutorsList!!.forEach {
                val tutor = Tutor(it.userID!!, it.name!!, it.lastname!!, it.email!!, it.roleFK!!, it.course!!.pathName)
                tutorViewModel.addTutor(tutor)
            }

            if (true) {
                this@TutorsFragment.onTutorsReceived(tutorsList)
            }

        }

        override fun onFailure(call: Call<List<Tutors>>, t: Throwable) {
            Toast.makeText(activity!!.applicationContext, t.message, Toast.LENGTH_SHORT).show()
        }
    })

    }

    val fab = tutorView.findViewById<View>(R.id.fab_tutors) as FloatingActionButton
    fab.setOnClickListener {
        val fragment = AddStudentAndTutorFragment()
        val title = "Add Tutors"
        val fragmentManager = fragmentManager
        val ft = fragmentManager!!.beginTransaction()
        ft.replace(R.id.frame, fragment)
        ft.addToBackStack(null)
        ft.commit()

        (activity as AppCompatActivity).supportActionBar!!.setTitle(title)
    }

    return tutorView
}

override fun onListItemClick(view: View, position: Int) {

    val tutor = tutors[position]
    val fragment = UserDetails()
    val title = "User Details"
    val bundle = Bundle()
    bundle.putString("name", tutor.name)
    bundle.putString("lastname", tutor.lastname)
    bundle.putString("email", tutor.email)
    bundle.putInt("userID", tutor.userID!!)
    bundle.putInt("role", tutor.roleFK!!)
    bundle.putString("course", tutor.course!!.pathName)
    fragment.arguments = bundle

    val fragmentManager = fragmentManager!!
    val ft = fragmentManager.beginTransaction()
    ft.replace(R.id.frame, fragment)
    ft.addToBackStack(null)
    ft.commit()

    (activity as AppCompatActivity).supportActionBar!!.title = title

}

override fun onResume() {
    super.onResume()
    val activity = activity as AppCompatActivity?
    val actionBar = activity!!.supportActionBar
    val my_fragment_title = "Tutors"
    actionBar!!.title = my_fragment_title
}

}

internal interface fromBackgroundToMainUIThread {
fun onTutorsReceived(tutors: List<Tutors>)

}

这是我的适配器类:

class TutorListAdapter(private val tutorsList: MutableList<Tutor>?, private val onItemClickListener: ListItemClickListener) : RecyclerView.Adapter<TutorListAdapter.ListViewHolder>() {

override fun onCreateViewHolder(viewGroup: ViewGroup, viewtype: Int): ListViewHolder {

    return ListViewHolder(viewGroup.inflate(R.layout.list_item))
}

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

@SuppressLint("SetTextI18n")
override fun onBindViewHolder(listViewHolder: ListViewHolder, position: Int) {

    val tutors = tutorsList!![position]
    listViewHolder.listItemTextView.text = tutors.name + "  " + tutors.lastname
}

fun removeItem(position: Int) {
    if (position < 0 || position >= tutorsList!!.size) {
        return
    }

    tutorsList.removeAt(position)
    notifyItemRemoved(position)
    notifyDataSetChanged()

}

interface ListItemClickListener {

    fun onListItemClick(view: View, position: Int)
}

inner class ListViewHolder(view: View) : RecyclerView.ViewHolder(view), View.OnClickListener {
    var listItemTextView: TextView

    init {

        listItemTextView = view.findViewById<View>(R.id.list_item_textview) as TextView
        view.setOnClickListener(this)
    }

    override fun onClick(v: View) {
        onItemClickListener.onListItemClick(v, adapterPosition)
    }
}

}

ViewModel类:

class StudentTutorViewModel(application: Application) : AndroidViewModel(application) {

var repository: Repository = Repository(application)

fun addTutor(tutor: Tutor) = repository.addTutor(tutor)

fun getAllTutors() = repository.getTutors()

}

如果有人能帮助我,我将不胜感激

2 个答案:

答案 0 :(得分:0)

问题可能出在您识别已在列表中单击的项目数据的方式之内。 我通常要做的是将clicklistener作为lambda函数传递给RecyclerAdapter 这样,您可以在onBindViewHolder中的viewholder上设置clicklistener 所以这种方法可能是这样的:

//in your ListAdapter class constructor instead of
class TutorListAdapter(private val tutorsList: MutableList<Tutor>?, private val onItemClickListener: ListItemClickListener)
//do like this
class TutorListAdapter(private val tutorsList: MutableList<Tutor>?, private val onItemClicked: (Tutor)->Unit)
//in your onBindViewHolder
override fun onBindViewHolder(listViewHolder: ListViewHolder, position: Int) {
   listViewHolder.view.setOnClickListener{
      onItemClicked(tutorsList[position])
      //rest of your code
   }
}
//in your fragment when creating TutorListAdapter
tutorViewModel.getAllTutors().observe(viewLifecycleOwner, Observer {
        if (it != null) {
            tutorListAdapter = TutorListAdapter(it as MutableList<Tutor>?, {tutor->
                    //you have the tutor object
                    //now do what ever you want
                })
            recyclerView!!.adapter = tutorListAdapter
        }
    })

答案 1 :(得分:0)

我找到了解决方案 问题是,在onListItemClick函数中,我调用了从API而不是从Room填充的列表 所以这就是解决方案

我创建了一个列表变量,该变量填充在getAlltutors()函数中:

private lateinit var list: List<Tutor>

tutorViewModel.getAllTutors().observe(viewLifecycleOwner, Observer {
        list = it!!
        //rest of the code
    })

然后在OnListClickItem函数中:

 override fun onListItemClick(view: View, position: Int) {

    val tutor = list[position]    //line that changed
    val fragment = UserDetails()
    val title = "User Details"
    val bundle = Bundle()
    println("Name: " + tutor.name)
    bundle.putString("name", tutor.name)
    bundle.putString("lastname", tutor.lastname)
    bundle.putString("email", tutor.email)
    bundle.putInt("userID", tutor.userId)
    bundle.putInt("role", tutor.roleFk)
    bundle.putString("course", tutor.pathName)
    fragment.arguments = bundle

    val fragmentManager = fragmentManager!!
    val ft = fragmentManager.beginTransaction()
    ft.replace(R.id.frame, fragment)
    ft.addToBackStack(null)
    ft.commit()

    (activity as AppCompatActivity).supportActionBar!!.title = title

}

现在可以使用