ТАК Я использую Firestore RecyclerView
, в котором метод onBindViewHolder
обновляет значение переменной с именем isFollowingBack: Boolean
(упоминается во 2-й последней строке моего кода) на основе некоторых условий Firestore. Методы работают отлично, но в методе onClick
Адаптера переменная по умолчанию соответствует тому, как она была изменена последним элементом viewHolder в адаптере, но я ожидаю, что каждый viewHolder будет иметь свое собственное значение переменной и действовать по-разному при нажатии, но адаптер несущий одно общее значение для той переменной, которая была изменена последним элементом. Я не уверен, что это ограничение просмотра переработчика Firestore или ограничение класса адаптера:
Вот код:
open class FollowersPeopleAdapter(options: FirestoreRecyclerOptions<PersonUser>) :
FirestoreRecyclerAdapter<PersonUser, FollowersPeopleAdapter.ViewHolder>(options) {
private var isFollowingBack: Boolean? = null
//Inflate the xml
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.followers_people_list_item, parent, false))
}
//Bind every dataView to the xml based on the Int value
override fun onBindViewHolder(viewHolder: ViewHolder, holderNumber: Int, personUser: PersonUser) {
viewHolder.bind(personUser)
//Set appropriate button styles based on the user Following state towards the person and change
styles when clicked on the buttons
getUserFollowingDocReference(personUser.Uid).get().addOnSuccessListener { it ->
if (it.exists()) {
//User is Following this person already so set Following button style
setFollowingButtonStyle(viewHolder)
isFollowingBack = true
Timber.i("Following value in bindView is $isFollowingBack")
} else {
//User is not Following this person already so set Follow button style
setFollowBackButtonStyle(viewHolder)
isFollowingBack = false
Timber.i("Following value in bindView is $isFollowingBack")
}
//When user clicks the follow button he is following now so change the style to following
//button style
viewHolder.itemView.followers_people_list_follow_button.setOnClickListener {
if (isFollowingBack!!) {
isFollowingBack = false
Timber.i("Following value in bindView is $isFollowingBack")
//Set style here itself so that it appears as an instant action for the user
setFollowBackButtonStyle(viewHolder)
unFollowThePersonAndRemoveFollowerFromFollowee(personUser)
} else if (!isFollowingBack!!) {
isFollowingBack = true
Timber.i("Following value in bindView is $isFollowingBack")
//Set style here itself so that it appears as an instant action for the user
setFollowingButtonStyle(viewHolder)
followThePersonAtClientAndFollowee(personUser)
}
}
}
}
private fun setFollowingButtonStyle(viewHolder: ViewHolder) {
viewHolder.itemView.followers_people_list_follow_button.text = "Following"
viewHolder.itemView.followers_people_list_follow_button.background =
getDrawable(getApplicationContext(), R.drawable.white_green_ripple_rectangular_button)
viewHolder.itemView.followers_people_list_follow_button.textColor =
getColor(getApplicationContext(), R.color.secondaryColor)
}
//Set the Button Style
private fun setFollowBackButtonStyle(viewHolder: ViewHolder) {
viewHolder.itemView.followers_people_list_follow_button.text = "Follow Back"
viewHolder.itemView.followers_people_list_follow_button.background =
getDrawable(getApplicationContext(), R.drawable.green_ripple_rectangular_button)
viewHolder.itemView.followers_people_list_follow_button.textColor =
getColor(getApplicationContext(), R.color.whiteColor)
}
private fun followThePersonAtClientAndFollowee(model: PersonUser) {
getUserFollowingDocReference(model.Uid).set(model).addOnSuccessListener {
}.addOnFailureListener {
Timber.i("Error trying to follow: $it")
}
}
private fun unFollowThePersonAndRemoveFollowerFromFollowee(model: PersonUser) {
getUserFollowingDocReference(model.Uid).delete().addOnSuccessListener {
}.addOnFailureListener {
Timber.i("Error trying to un-follow: $it")
}
}
//Adds functionality to each View (aka ViewHolder) which is every person downloaded
inner class ViewHolder(itemView: View?) : RecyclerView.ViewHolder(itemView!!), View.OnClickListener {
//We are downloading User Objects so this Variable will be assigned to the UserObject downloaded
private var currentPersonUser : PersonUser? = null
//When the class is initiated this function is called which sets an OnClickListener to each View
init {
itemView!!.setOnClickListener(this)
}
//The Data from the Object is used to Populate the TextViews
fun bind(model: PersonUser) {
currentPersonUser = model
itemView.followers_people_person_list_name.text = model.Name
itemView.followers_people_person_username.text = model.UserName
if ( currentPersonUser!!.profilePhotoChosen ) {
//If the personUser has set a profilePhoto then download & populate it with Glide
getThumbnailProfilePhotoStorageRef(model.Uid).downloadUrl.addOnSuccessListener {
val downloadUrl = it.toString()
Timber.i("Followers People download URL : $downloadUrl")
//Added get Application context to avoid glide loading the image
// while the activity is being destroyed and avoid a crash
Glide.with(getApplicationContext())
.load(downloadUrl)
.placeholder(R.drawable.black_color_rectangle)
.apply(CompanionObjects.requestOptions)
.transition(DrawableTransitionOptions.withCrossFade(150))
.into(itemView.followers_people_list_profile_image)
}.addOnFailureListener {
Timber.i("unable to retrieve your profile photo")
Glide.with(getApplicationContext())
.load(R.drawable.ic_person_black_24dp)
.into(itemView.followers_people_list_profile_image)
}
} else {
Glide.with(getApplicationContext())
.load(R.drawable.ic_person_black_24dp)
.transition(DrawableTransitionOptions.withCrossFade(150))
.into(itemView.followers_people_list_profile_image)
}
}
//The onClick function is called when the View is clicked,
//In this case we are starting an Intent
override fun onClick(v: View?) {
Timber.i("Following value is $isFollowingBack")
val intent = Intent(v!!.context, PersonProfileActivity::class.java)
//If the Person has an Image then add it to the Intent Extras,
//Also the person is not the user himself,
if ( currentPersonUser!!.profilePhotoChosen && currentPersonUser!!.Uid !=
CompanionObjects.user.Uid ) {
//Retrieve the glide drawable as a Bitmap and pass it into the Intent Extras as a
//ByteArray
val bmp: Bitmap = itemView.followers_people_list_profile_image.drawToBitmap()
val baos = ByteArrayOutputStream()
bmp.compress(Bitmap.CompressFormat.PNG, 100, baos)
val personThumbnailPhotoByteArray: ByteArray = baos.toByteArray()
intent.putExtra(CompanionObjects.PERSON_THUMBNAIL_PHOTO_INTENT_EXTRA,
personThumbnailPhotoByteArray)
}
intent.putExtra(CompanionObjects.PERSON_NAME_INTENT_EXTRA, currentPersonUser!!.Name)
intent.putExtra(CompanionObjects.PERSON_USERNAME_INTENT_EXTRA, currentPersonUser!!.UserName)
intent.putExtra(CompanionObjects.PERSON_UID_INTENT_EXTRA, currentPersonUser!!.Uid)
intent.putExtra(CompanionObjects.INTENT_FROM_FOLLOWERS, true)
//THIS IS THE VARIABLE 'isFollowingBack' WHICH IS NOT CARRYING A VALUE WHICH IS SPECIFIC TO THIS VIEWHOLDER
//BUT IS CARRYING THE VALUE OF THE LATEST ITEM IN THIS VIEWHOLDER
intent.putExtra(CompanionObjects.PERSON_NAME_USER_FOLLOWING_BACK_STATUS, isFollowingBack)
v.context.startActivity(intent)
}
}
}