I have add an some condition in viewholder of recycleradapter of recyclerview to hide some items
but it shows empty spaces of removed items in recyclerview which I hide how can I solve these problem to remove empty spaces.is there any another way to hide the items in recyclerview if is then share us.
Bookadapter.kt
class bookadapter(
private var booklist: ArrayList<Booksmodel>,
private val itemClickListener: OnBookItemClicklistner
) : RecyclerView.Adapter<bookadapter.bookholder>() {
var searchText: String = ""
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): bookholder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.singlebook, parent, false)
return bookholder(view)
}
fun filterlist(filterlist: ArrayList<Booksmodel>, searchText: String) {
this.searchText = searchText
booklist = filterlist
notifyDataSetChanged()
}
override fun onBindViewHolder(holder: bookholder, position: Int) {
val view = booklist[position]
holder.dind(view, itemClickListener)
}
override fun getItemCount(): Int {
return booklist.size
}
inner class bookholder(view: View) : RecyclerView.ViewHolder(view) {
val bookname: TextView = view.findViewById(R.id.recbooknametxt)
val bookpublication = view.findViewById<TextView>(R.id.recbookpubtxt)
val bookdept = view.findViewById<TextView>(R.id.recbookdepttxt)
val bookimage = view.findViewById<ImageView>(R.id.recbookimg)
val bookview = view.findViewById<CardView>(R.id.bookcardView)
fun bind(book: Booksmodel, clicklistner: OnBookItemClicklistner) {
val database = FirebaseDatabase.getInstance()
val auth = FirebaseAuth.getInstance()
database.getReference("Users").child(book.UserUID.toString())
.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
if (snapshot.value != null) {
val usercollege = snapshot.child("College").value.toString()
database.getReference("Users")
.child(auth.currentUser!!.uid)
.addListenerForSingleValueEvent(object :
ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
if (snapshot.value != null) {
val mycollege =
snapshot.child("College").value.toString()
if (usercollege == mycollege) {
if (searchText.isNotBlank()) {
val highlightedText = book.BookName!!.replace(
searchText,
"<font color='red'>$searchText</font>",
true
)
bookname.text =
HtmlCompat.fromHtml(
highlightedText,
HtmlCompat.FROM_HTML_MODE_LEGACY
)
} else {
bookname.text = book.BookName
}
//bookname.text=book.BookName
bookpublication.text = book.BookPublication
bookdept.text = book.Department
Picasso.get().load(book.BookImage).into(bookimage)
} else {
bookview.visibility = View.GONE
}
}
}
override fun onCancelled(error: DatabaseError) {
}
})
}
}
override fun onCancelled(error: DatabaseError) {
}
})
itemView.setOnClickListener {
clicklistner.onBookItemclick(book)
}
}
}
interface OnBookItemClicklistner {
fun onBookItemclick(books: Booksmodel)
}
}
Are you using Android studio?. It should have caught such errors.
override fun onBindViewHolder(holder: bookholder, position: Int) {
val view = booklist[position]
//holder.dind(view, itemClickListener) typo
holder.bind(view, itemClickListener)
}
If you want to hide the item completely
bookview.visibility = View.GONE
bookview.layoutParams = ViewGroup.LayoutParams(0,0) //sets width and height of the view
Related
I have set up a fragment with a recyclerView in it and I fetch data from firestore successfully. What I want to know is that if it is possible to add items at a certain position in recyclerView. Suppose, I want to add an item (from a different collection in Firestore) after every 5 items in a recyclervView. Is it possible to do it in Android using Kotlin?
Thank you.
Edit:
DashboardFragment.kt
class DashboardFragment : BaseFragment() {
var srchProductsList: ArrayList<Product> = ArrayList()
var adList: ArrayList<Ads> = ArrayList()
var srchTempProductsList: ArrayList<Product> = ArrayList()
var newView: String = "ListView"
private lateinit var binding: FragmentDashboardBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentDashboardBinding.inflate(inflater, container, false)
binding.fbDashboard.setImageResource(R.drawable.ic_grid_view)
binding.fbDashboard.setOnClickListener {
if (newView=="ListView"){
newView="GridView"
fb_dashboard.setImageResource(R.drawable.ic_list_view)
}else{
newView="ListView"
fb_dashboard.setImageResource(R.drawable.ic_grid_view)
}
onResume()
}
return binding.root
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val id = item.itemId
when (id) {
R.id.action_settings -> {
startActivity(Intent(activity, SettingsActivity::class.java))
return true
}
R.id.action_cart -> {
startActivity(Intent(activity, CartListActivity::class.java))
return true
}
}
return super.onOptionsItemSelected(item)
}
override fun onResume() {
super.onResume()
srchProductsList.clear()
srchTempProductsList.clear()
getDashboardItemsList()
}
private fun getDashboardItemsList() {
showProgressDialog(resources.getString(R.string.please_wait))
getDashboardItemsList2()
}
fun successDashboardItemsList(dashboardItemsList: ArrayList<Product>) {
val adsLists =getListOfAds()
hideProgressDialog()
if (dashboardItemsList.size > 0) {
Toast.makeText(
context,
"Total " + dashboardItemsList.size + " products loaded",
Toast.LENGTH_LONG
).show()
rv_dashboard_items.visibility = View.VISIBLE
tv_no_dashboard_items_found.visibility = View.GONE
rv_dashboard_items.layoutManager =
StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
rv_dashboard_items.setHasFixedSize(true)
val adapter = DashboardItemsListAdapterTest(requireActivity(), dashboardItemsList,adsLists)
rv_dashboard_items.adapter = adapter
//////// I HAVE PROBLEM WITH THE FOLLOWING BLOCK OF CODE WHICH IS WHY I HAVE COMMENTED IT OUT ONLY TO CHECK IF OTHER PART OF THE CODE IS WORKING. I NEED TO FIX THE ERROR FOR THE BELOW BLOCK OF CODE ALSO
/* adapter.setOnClickListener(object :
DashboardItemsListAdapter.OnClickListener {
override fun onClick(position: Int, product: Product) {
val intent = Intent(context, ProductDetailsActivity::class.java)
intent.putExtra(Constants.EXTRA_PRODUCT_ID, product.product_id)
intent.putExtra(Constants.EXTRA_PRODUCT_OWNER_ID, product.user_id)
startActivity(intent)
}
})*/
} else {
rv_dashboard_items.visibility = View.GONE
tv_no_dashboard_items_found.visibility = View.VISIBLE
}
}
fun successDashboardItemsListListView(dashboardItemsList: ArrayList<Product>) {
val adsLists =getListOfAds()
hideProgressDialog()
if (dashboardItemsList.size > 0) {
Toast.makeText(
context,
"Total " + dashboardItemsList.size + " products loaded",
Toast.LENGTH_LONG
).show()
rv_dashboard_items.visibility = View.VISIBLE
tv_no_dashboard_items_found.visibility = View.GONE
rv_dashboard_items.layoutManager =
LinearLayoutManager(context)
rv_dashboard_items.setHasFixedSize(true)
val adapter = DashboardItemsListAdapterTest(requireActivity(), dashboardItemsList,adsLists)
rv_dashboard_items.adapter = adapter
//////// I HAVE PROBLEM WITH THE FOLLOWING BLOCK OF CODE WHICH IS WHY I HAVE COMMENTED IT OUT ONLY TO CHECK IF OTHER PART OF THE CODE IS WORKING. I NEED TO FIX THE ERROR FOR THE BELOW BLOCK OF CODE ALSO
/* adapter.setOnClickListener(object :
DashboardItemsListAdapter.OnClickListener {
override fun onClick(position: Int, product: Product) {
val intent = Intent(context, ProductDetailsActivity::class.java)
intent.putExtra(Constants.EXTRA_PRODUCT_ID, product.product_id)
intent.putExtra(Constants.EXTRA_PRODUCT_OWNER_ID, product.user_id)
startActivity(intent)
}
})*/
} else {
rv_dashboard_items.visibility = View.GONE
tv_no_dashboard_items_found.visibility = View.VISIBLE
}
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.dashboard_menu, menu)
super.onCreateOptionsMenu(menu, inflater)
val item = menu.findItem(R.id.my_search_bar)
val searchView = item?.actionView as SearchView
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
srchTempProductsList.clear()
val searchKey = query
if (searchKey != null) {
if (searchKey.isNotEmpty()) {
srchProductsList.forEach {
if (it.description.toLowerCase(Locale.getDefault())
.contains(searchKey)
) {
srchTempProductsList.add(it)
}
}
rv_dashboard_items.adapter!!.notifyDataSetChanged()
} else {
srchTempProductsList.clear()
srchTempProductsList.addAll(srchProductsList)
rv_dashboard_items.adapter!!.notifyDataSetChanged()
}
}
return false
}
override fun onQueryTextChange(newText: String?): Boolean {
srchTempProductsList.clear()
val searchText = newText!!.toLowerCase(Locale.getDefault())
if (searchText.isNotEmpty()) {
srchProductsList.forEach {
if (it.description.toLowerCase(Locale.getDefault()).contains(searchText)) {
srchTempProductsList.add(it)
}
}
rv_dashboard_items.adapter!!.notifyDataSetChanged()
} else {
srchTempProductsList.clear()
srchTempProductsList.addAll(srchProductsList)
rv_dashboard_items.adapter!!.notifyDataSetChanged()
}
return false
}
})
}
private fun getDashboardItemsList2() {
val mFireStore = FirebaseFirestore.getInstance()
mFireStore.collection(Constants.PRODUCTS)
.get()
.addOnSuccessListener { document ->
for (i in document.documents) {
val product = i.toObject(Product::class.java)!!
product.product_id = i.id
srchProductsList.add(product)
}
srchTempProductsList.addAll(srchProductsList)
if (newView == "ListView") {
successDashboardItemsListListView(srchTempProductsList)
} else {
successDashboardItemsList(srchTempProductsList)
}
}
.addOnFailureListener {
}
}
private fun getListOfAds() : ArrayList<Ads>{
val mFireStore = FirebaseFirestore.getInstance()
mFireStore.collection("ads")
.get()
.addOnSuccessListener { document ->
for (i in document.documents) {
val ad = i.toObject(Ads::class.java)!!
ad.ad_id = i.id
adList.add(ad)
}
}
.addOnFailureListener {
}
return adList
}
}
DashboardItemListAdapterTest.kt
open class DashboardItemsListAdapterTest(
private val context: Context,
private var prodlist: ArrayList<Product>,
private var adslist: ArrayList<Ads>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
companion object {
const val produc= 1
const val ads= 2
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return if (viewType == produc) {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_dashboard_list_view_layout, parent, false)
Collection1Holder(view)
} else {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_dashboard_ad_view_layout, parent, false)
Collection2Holder(view)
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val promodel = prodlist[position]
val adsmodel = adslist[position]
if(getItemViewType(position) == produc) {
holder.itemView.tv_item_name.text = promodel.title
}else{
holder.itemView.tv_item_name.text = adsmodel.title
}
}
override fun getItemCount(): Int {
return prodlist.size + adslist.size
}
override fun getItemViewType(position: Int): Int {
return if(position%5 == 0) ads else produc
}
inner class Collection1Holder(itemView: View) : RecyclerView.ViewHolder(itemView) {
}
inner class Collection2Holder(itemView: View) : RecyclerView.ViewHolder(itemView) {
}
}
Model class
Ads.kt
data class Ads(
val title: String = "",
var ad_id: String = ""
)
You can use two viewholder for two different collections of data.
Change your adapter class like this.
class YourAdapter() : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
companion object {
const val COLLCTION1= 1
const val COLLCTION2= 2
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return if (viewType == COLLCTION1) {
val view = LayoutInflater.from(viewGroup.context)
.inflate(R.layout.collection1, viewGroup, false)
Collection1Holder(view)
} else {
val view = LayoutInflater.from(viewGroup.context)
.inflate(R.layout.collection2, viewGroup, false)
Collection2Holder(view)
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if(getItemViewType(position) == COLLCTION1) {
holder.name.text = collection1.text
}else{
holder.name.text = collection2.text
}
}
override fun getItemCount(): Int {
return collection1.size + collection2.size
}
override fun getItemViewType(position: Int): Int {
return if(position%5 == 0) COLLCTION2 else COLLCTION1
}
inner class Collection1Holder(itemView: View) : RecyclerView.ViewHolder(itemView) {
}
inner class Collection2Holder(itemView: View) : RecyclerView.ViewHolder(itemView) {
}
}
I'm working on a firebase realtime database android project. I build a feed system that shows all the users posts but it sorts all data at once. I need to show 10 posts then show progress bar then load 10 others etc...
Explore Fragment
class ExploreFragment : Fragment() {
private var postAdapter:PostAdapter? = null
private var postList: MutableList<Post>? = null
override fun onCreateView(
recyclerView.layoutManager = linearLayoutManager
postList= ArrayList()
postAdapter = context?.let { PostAdapter(it,postList as ArrayList<Post>) }
recyclerView.adapter = postAdapter
retrievePosts()
return view
}
private fun retrievePosts() {
val postRef = FirebaseDatabase.getInstance().reference.child("Posts")
postRef.addValueEventListener(object :ValueEventListener{
override fun onDataChange(p0: DataSnapshot) {
if (p0.exists()){
postList!!.clear()
for (snapshot in p0.children){
val post = snapshot.getValue(Post::class.java)!!
(postList as ArrayList<Post>).add(post)
}
postAdapter?.notifyDataSetChanged()
}
}
override fun onCancelled(p0: DatabaseError) {
}
})
}}
PostAdapter
class PostAdapter(private val mContext: Context,private val mPost: List<Post>
):RecyclerView.Adapter<PostAdapter.ViewHolder>()
{
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(mContext).inflate(R.layout.post_layout, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val post = mPost[position]
Picasso.get().load(post.getPost()).into(holder.postImg)
publisherInfo(holder.profileImg, holder.userName, post.getPublisher())
}
override fun getItemCount(): Int {return mPost.size}
inner class ViewHolder(#NonNull itemView: View): RecyclerView.ViewHolder(itemView)
{
var profileImg:CircleImageView
var postImg:ImageView
var userName:TextView
init {
profileImg = itemView.findViewById(R.id.profile_image_post)
postImg = itemView.findViewById(R.id.post_image)
userName = itemView.findViewById(R.id.username_post)
}
}
private fun publisherInfo(profileImg: CircleImageView, userName: TextView, publisherID: String) {
val userRef = FirebaseDatabase.getInstance().reference.child("Users").child(publisherID)
userRef.addValueEventListener(object : ValueEventListener {
override fun onDataChange(p0: DataSnapshot) {
if (p0.exists()) {
val user = p0.getValue<User>(User::class.java)
Picasso.get().load(user!!.getImage()).into(profileImg)
userName.text = user!!.getUsername()
}
}
override fun onCancelled(p0: DatabaseError) {
}
})
}
}
I remove some lines to make the code simple
I have implemented searchView with recyclerView it is not working and giving errors I did not understand where I am making mistakes. below my MainActivity where I have implemented searchview logic
I have implemented searchView with recyclerView it is not working and giving errors I did not understand where I am making mistakes. below my MainActivity where I have implemented searchview logic
class MemberActivity : AppCompatActivity() {
private var memberAdapter: MemberAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_member)
val compositeDisposable = CompositeDisposable()
compositeDisposable.add(
ServiceBuilder.buildService(SpectrumInterface::class.java)
.getMembers()
.toObservable()
.flatMap { Observable.fromIterable(it) }
.flatMap { Observable.fromIterable(it.members) }
.toList()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ members -> onResponse(members) },
{ t -> onFailure(t) })
)
memberAdapter = MemberAdapter()
recyclerView.setHasFixedSize(true)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.addItemDecoration(DividerItemDecoration(this, LinearLayout.VERTICAL))
private fun onFailure(t: Throwable) {
Toast.makeText(this, t.message, Toast.LENGTH_SHORT).show()
}
private fun onResponse(members: List<Member>) {
progressBar.visibility = View.GONE
(recyclerView.adapter as MemberAdapter).setMembers(members)
}
override fun onQueryTextSubmit(query: String?): Boolean {
return false
}
override fun onQueryTextChange(newText: String?): Boolean {
memberAdapter?.getFilter()?.filter(newText)
return true
}
ascendingButton.setOnClickListener
{
memberAdapter?.sortAscending()
}
descendingButton.setOnClickListener {
memberAdapter?.sortDescending()
}
}
}
below my Adapter where I have implemented filter logic
class MemberAdapter : RecyclerView.Adapter<MemberAdapter.MemberViewHolder>() {
private val members = mutableListOf<Member>()
fun setMembers(data: List<Member>) {
members.clear()
members.addAll(data)
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MemberViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.member_list, parent, false)
return MemberViewHolder(view)
}
override fun getItemCount() = members.size
fun sortAscending() {
members.sortBy { it.age }
notifyDataSetChanged()
}
fun sortDescending() {
members.sortByDescending { it.age }
notifyDataSetChanged()
}
fun getFilter(): Filter {
return object : Filter() {
override fun performFiltering(charSequence: CharSequence): FilterResults {
val query = charSequence.toString()
val filtered: MutableList<Member> = ArrayList()
if (query.isEmpty()) {
filtered.clear()
filtered.addAll(members)
} else {
filtered.addAll(members.filter {
it.id.toLowerCase(Locale.ROOT)
.contains(query.toLowerCase(Locale.ROOT)) || it.age.toString()
.contains(query)
})
}
val results = FilterResults()
results.count = filtered.size
results.values = filtered
return results
}
override fun publishResults(charSequence: CharSequence, results: FilterResults) {
members.clear()
members.addAll(results.values as Collection<Member>)
notifyDataSetChanged()
}
}
}
override fun onBindViewHolder(holder: MemberViewHolder, position: Int) {
return holder.bind(members[position])
}
class MemberViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val memberAge: TextView = itemView.findViewById(R.id.memberAge)
// private val memberName: TextView = itemView.findViewById(R.id.memberName)
private val lastName: TextView = itemView.findViewById(R.id.lastName)
private val firstName: TextView = itemView.findViewById(R.id.firstName)
private val emailAddress: TextView = itemView.findViewById(R.id.emailAddress)
private val phone: TextView = itemView.findViewById(R.id.phone)
fun bind(member: Member) {
memberAge.text = member.age.toString()
lastName.text = member.name?.last
firstName.text = member.name?.first
emailAddress.text = member.email
phone.text = member.phone
}
}
}
Your mistake is updating members and then using it again as your base for future filtering.
Instead:
Create another list filteredMembers in MembersAdapter, initialize it to be equal to members in setMembers()
Make MembersAdapter reflect the items in filteredMembers
override fun getItemCount() = filteredMembers.size
override fun onBindViewHolder(holder: MemberViewHolder, position: Int) {
return holder.bind(filteredMembers[position])
}
Make your filter update filteredMembers and not members
I think the main problem happened during adding foodInfo into foodLists, and also the part where I pass data to listAdapter. I did check with Log.d for foodData.foodName and it works fine, but when I try Log.d to get the foodList it doesn't work.
here are my code for the moment
EDITED SOLVED
My Adapter
class listAdapter(val food : ArrayList<Foods>) : RecyclerView.Adapter<listAdapter.ViewHolder>() {
val unfoldedIndexes = HashSet<Int>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.cell, parent, false)
return ViewHolder(view)
}
override fun getItemCount(): Int {
return food.count()
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(position)
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(position: Int) = with(itemView) {
// folding_cell.setBackgroundColor(resources.getColor(R.color.colorPrimary))
folding_cell.backSideColor = resources.getColor(R.color.White)
if (unfoldedIndexes.contains(position)) {
cell_title_view.visibility = View.GONE
cell_content_view.visibility = View.VISIBLE
} else {
cell_content_view.visibility = View.GONE
cell_title_view.visibility = View.VISIBLE
}
itemView.setOnClickListener {
// toggle clicked cell state
folding_cell.toggle(false)
// register in adapter that state for selected cell is toggled
registerToggle(position)
}
}
private fun registerToggle(position: Int) {
if (unfoldedIndexes.contains(position))
registerFold(position)
else
registerUnfold(position)
}
private fun registerFold(position: Int) {
unfoldedIndexes.remove(position)
}
private fun registerUnfold(position: Int) {
unfoldedIndexes.add(position)
}
}
}
My Activity for the recyclerView
class FoodListActivity : BaseActivity(1) {
private val TAG = "FoodListActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_food_list)
setupBottomNavigation()
Log.d(TAG,"onCreate")
getFromFirebase()
}
private fun getFromFirebase() {
val currentUserUID = FirebaseAuth.getInstance().uid.toString()
val ref = FirebaseDatabase.getInstance().reference
ref.child("users").child(currentUserUID).child("foods").addListenerForSingleValueEvent(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(p0: DataSnapshot) {
setHasFixedSize(true)
recyclerview.layoutManager = LinearLayoutManager(this#FoodListActivity)
p0.children.forEach {
Log.d("getFood", it.toString())
val foodData = it.getValue(Foods::class.java)
if (foodData != null) {
val foodList = ArrayList<Foods>()
val adapter = ListAdapter(foodList)
foodList.add(foodData)
recyclerview.adapter = adapter
}
}
}
})
}}
I have an infinite loop in my code. Until I completely shut down the program, it is continuously writing data to my Firebase database... I am in real need, please help. I want my function MemberAdding execute just one time after button is clicked...
override fun MemberAdding(accountKey: String) {
DBdatabaseName!!.reference!!.child(user!!.currentUser!!.uid).child("Group-List").addValueEventListener(object : ValueEventListener{
override fun onDataChange(dataSnapshot: DataSnapshot) {
groupKey = intent.getStringExtra("GroupKey")
val flag = dataSnapshot.child("Groups").child(groupKey).child("members").value.toString()
val newpath = "member" + flag
DBdatabaseName!!.reference!!.child(user!!.currentUser!!.uid).child("Group-List").child("Groups").child(groupKey).child(newpath).setValue(accountKey)
}
override fun onCancelled(databaseError: DatabaseError) {
}
})
DBdatabaseName!!.reference!!.child(user!!.currentUser!!.uid).child("Group-List").addValueEventListener(object : ValueEventListener{
override fun onDataChange(dataSnapshot: DataSnapshot) {
val groupKey = intent.getStringExtra("GroupKey")
var flag = dataSnapshot.child("Groups").child(groupKey).child("members").value.toString()
val flag2 = flag.toInt()
val flag3 = flag2 + 1
DBdatabaseName!!.reference!!.child(user!!.currentUser!!.uid).child("Group-List").child("Groups").child(groupKey).child("members").setValue(flag3)
}
override fun onCancelled(databaseError: DatabaseError) {
}
})
refresh()
}
private fun refresh() {
groupKey = intent.getStringExtra("GroupKey")
val intent = Intent(this#GroupMemberAddingActivity, GroupMemberAddingActivity::class.java)
intent.putExtra("GroupKey", groupKey)
startActivity(intent)
}
}
at below i will also send the Adapter class that i am using
class GroupMemberAddingItemAdapter (context: Context, friendItemList: MutableList<FriendItem>) : BaseAdapter() {
private class ListRowHolder (row: View? ) {
val label: TextView = row!!.findViewById(R.id.friendName_textview) as TextView
val addMember: Button? = row!!.findViewById(R.id.addMember_button) as Button
}
private val mInflater: LayoutInflater = LayoutInflater.from(context)
private var itemList = friendItemList
private var mView: View? = null
private var rowListener: GroupMemberAddingRowListener = context as GroupMemberAddingRowListener
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
val friendName: String = itemList.get(position).friendName as String
val friendLastName: String = itemList.get(position).friendLastName as String
val friendemail: String = itemList.get(position).accountKey as String
val vh: ListRowHolder
if (convertView == null) {
mView = mInflater.inflate(R.layout.groupmemberadding_row, parent, false)
vh = ListRowHolder(mView)
mView!!.tag = vh
} else {
mView = convertView
vh = mView!!.tag as ListRowHolder
}
vh.label.text = "$friendName $friendLastName"
vh.addMember!!.setOnClickListener{rowListener.MemberAdding(friendemail)}
return mView!!
}
override fun getItem(index: Int): Any {
return itemList[index]
}
override fun getItemId(index: Int): Long {
return index.toLong()
}
override fun getCount(): Int {
return itemList.size
}
}
my initial row listener is.....
interface GroupMemberAddingRowListener {
fun MemberAdding (accountKey:String)
}
If you need any more code parts just tell me.... Thanks for helping
First, you had to debug and look where it happens, anyway I think it is inside onDataChanged implementation
Since you fire:
DBdatabaseName!!.reference!!.child(user!!.currentUser!!.uid).child("Group-List").child("Groups").child(groupKey).child("members").setValue(flag3)
setValue will happen to fire onDataChanged again.
I found the problem
DBdatabaseName!!.reference!!.child(user!!.currentUser!!.uid).child("Group-List").addValueEventListener(object : ValueEventListener{
override fun onDataChange(dataSnapshot: DataSnapshot) {
Line makes onDataChange is called back every time data changes...(culprit is addValueEventListener) so i changed it to
BdatabaseName!!.reference!!.child(user!!.currentUser!!.uid).child("Group-List").addListenerForSingleValueEvent(object : ValueEventListener{
override fun onDataChange(dataSnapshot: DataSnapshot) {
addListenerForSingleValueEvent calls the onDataChange only once than destroys the all callbacks