After doing some research i found out that i need to clear the list that i am using each time i refresh the activity, after trying it to refresh the list at different places, the result remains the same and i have decided to give my brain a break and ask for help. The refreshing takes place on the PostDialogFragment class
i have circled the recycler view causing the issue
PostAdapter
package com.example.osrscritic.view
import android.text.method.ScrollingMovementMethod
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.osrscritic.databinding.PostRowItemBinding
import com.example.osrscritic.model.Skillvalue
import com.google.firebase.firestore.CollectionReference
import com.google.firebase.firestore.DocumentSnapshot
import com.google.firebase.firestore.QueryDocumentSnapshot
import com.google.firebase.firestore.QuerySnapshot
class PostsAdapter: RecyclerView.Adapter<PostsViewHolder>() {
val postsMutableList : MutableList<DocumentSnapshot> = mutableListOf()
fun setPostsList(statsList: List<DocumentSnapshot>) {
postsMutableList.addAll(statsList)
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PostsViewHolder {
val binding = PostRowItemBinding.inflate(LayoutInflater.from(parent.context)
,parent,false)
return PostsViewHolder(binding)
}
override fun onBindViewHolder(holder: PostsViewHolder, position: Int) {
val post = postsMutableList[position]
holder.binding.tvCritic.text = post["critic"].toString()
val posts = post["posts"] as List<String>
var count = 0;
holder.binding.tvActualPost.movementMethod = ScrollingMovementMethod()
for(p in posts) {
holder.binding.tvActualPost.append("${count}: " p "\n")
count
}
}
override fun getItemCount() = postsMutableList.size
}
class PostsViewHolder(val binding: PostRowItemBinding) : RecyclerView.ViewHolder(binding.root)
DisplayUserActivty
package com.example.osrscritic
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.osrscritic.databinding.ActivityDisplayUserBinding
import com.example.osrscritic.view.PostDialogFragment
import com.example.osrscritic.view.PostsAdapter
import com.example.osrscritic.view.StatsAdapter
import com.example.osrscritic.viewmodel.DisplayUserViewModel
import com.google.android.gms.tasks.OnCompleteListener
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.firestore.DocumentSnapshot
import org.koin.androidx.viewmodel.ext.android.viewModel
class DisplayUserActivity : AppCompatActivity() {
private val displayUserViewModel : DisplayUserViewModel by viewModel()
lateinit var binding: ActivityDisplayUserBinding
val statsAdapter = StatsAdapter()
val postsAdapter = PostsAdapter()
lateinit var critiquing: String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val extras = intent.extras
critiquing = extras?.getString("c")!!
binding = ActivityDisplayUserBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.rsStatsRv.adapter = statsAdapter
binding.rsStatsRv.layoutManager = LinearLayoutManager(this,
LinearLayoutManager.VERTICAL, false)
binding.rvPosts.adapter = postsAdapter
binding.rvPosts.layoutManager = LinearLayoutManager(this,
LinearLayoutManager.VERTICAL, false)
configureObservers()
displayUserViewModel.getFirebaseRef()
displayUserViewModel.getOSRSPlayer()
binding.ivWritePost.setOnClickListener {
PostDialogFragment.newInstance(critiquing).show(supportFragmentManager
, PostDialogFragment.KEY)
}
}
private fun configureObservers() {
displayUserViewModel.displayUserLiveData.observe(this, {
statsAdapter.setStatsList(it.skillvalues)
binding.tvRunescapeName.text = String.format("Account Name: %s", it.name)
binding.tvCombat.text = String.format("Combat Level: %s", it.combatlevel.toString())
})
displayUserViewModel.loadingState.observe(this, {
when(it){
true -> binding.pgBar.visibility = View.VISIBLE
false -> binding.pgBar.visibility = View.GONE
}
})
displayUserViewModel.errorData.observe(this, {
Toast.makeText(this, it, Toast.LENGTH_LONG).show()
})
displayUserViewModel.displayUserPostsLiveData.observe(this, {
postsAdapter.postsMutableList.clear()
it.document(critiquing).collection("posts").get()
.addOnSuccessListener {
postsAdapter.setPostsList(it.documents)
}
})
}
}
PostDialogFragment
package com.example.osrscritic.view
import android.app.AlertDialog
import android.app.Dialog
import android.content.DialogInterface
import android.content.Intent
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import androidx.fragment.app.DialogFragment
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.EditText
import android.view.Gravity
import androidx.core.app.ActivityCompat.recreate
import com.example.osrscritic.DisplayUserActivity
import com.example.osrscritic.viewmodel.DisplayUserViewModel
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.firestore.FieldPath
import com.google.firebase.firestore.FieldValue
import com.google.firebase.firestore.SetOptions
import org.koin.androidx.viewmodel.ext.android.viewModel
class PostDialogFragment: DialogFragment() {
private val displayUserViewModel : DisplayUserViewModel by viewModel()
val currentUser = FirebaseAuth.getInstance().currentUser
lateinit var critiquing: String
val postsAdapter = PostsAdapter()
companion object {
const val KEY: String = "KEY2"
//lateinit var param: String
fun newInstance(text: String): PostDialogFragment {
val args = Bundle()
val postDialogFragment = PostDialogFragment()
args.putString(KEY, text)
postDialogFragment.arguments = args
return postDialogFragment
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
critiquing = arguments?.getString(KEY)!!
Log.d("*******8", critiquing)
val builder = AlertDialog.Builder(activity)
val layout = LinearLayout(activity)
val parms = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
)
layout.orientation = LinearLayout.VERTICAL
layout.layoutParams = parms
layout.gravity = Gravity.CLIP_VERTICAL
layout.setPadding(2, 2, 2, 2)
val tv = TextView(activity)
tv.text = "Text View title"
tv.setPadding(40, 40, 40, 40)
tv.gravity = Gravity.CENTER
tv.textSize = 20f
val et = EditText(activity)
var etString = ""
et.addTextChangedListener(object: TextWatcher{
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun afterTextChanged(p0: Editable?) {
Log.d("etText", et.text.toString())
etString = et.text.toString()
}
})
val tv1 = TextView(activity)
tv1.text = "Input Student ID"
val tv1Params = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
)
tv1Params.bottomMargin = 5
//layout.addView(tv1, tv1Params)
layout.addView(
et,
LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
)
)
//param = arguments?.getString(KEY)!!
builder.setTitle("New Post")
builder.setView(layout).setPositiveButton("Done", object: DialogInterface.OnClickListener{
override fun onClick(p0: DialogInterface?, p1: Int) {
activity?.let {
displayUserViewModel.displayUserPostsLiveData.observe(it, {
val post : MutableMap<String, Any> = mutableMapOf()
val posts : MutableList<String> = mutableListOf()
posts.add(etString)
post["critic"] = currentUser?.email!!
post["posts"] = posts
if(it.document(critiquing).collection("posts").document().equals(null)) {
it.document(critiquing).collection("posts")
.document(currentUser?.email!!).set(post)
}
it.document(critiquing).collection("posts")
.document(currentUser?.email!!).update("posts", FieldValue.arrayUnion(etString))
})
}
activity!!.finish()
activity!!.overridePendingTransition( 0, 0);
startActivity(activity!!.intent)
//trying to clear the list here once being refreshed
postsAdapter.postsMutableList.clear()
activity!!.overridePendingTransition( 0, 0);
}
})
builder.setNegativeButton("Cancel", object:DialogInterface.OnClickListener{
override fun onClick(p0: DialogInterface?, p1: Int) {
dismiss()
}
})
return builder.create()
}
}
CodePudding user response:
For me overriding getItemId
, getItemCount
and getItemType
(if there's multiple view types) and using setHasStableIds(true)
always solves this kind of issues.