can anyone help me?
i try lesson online for android-firebase, but it an old one.
So the code change already. I got stuck at onBindViewHolder and onCreateViewHolder because the lesson don't have that.
class UsersAdapter(databaseQuery: DatabaseReference, var context: Context):
FirebaseRecyclerAdapter<Users, ViewHolder>(
FirebaseRecyclerOptions.Builder<Users>().setQuery(databaseQuery, Users::class.java).build()
) {
override fun onBindViewHolder(holder: ViewHolder, position: Int, model: Users) {
var userID = getRef(position).key
holder.bindView(model, context)
holder.itemView.setOnClickListener {
//todo create a popup dialog where user can do
Toast.makeText(context, "user row click $userID", Toast.LENGTH_LONG).show()
}
}
override fun onCreateViewHolder(p0: ViewGroup, p1: Int): ViewHolder {
var view = LayoutInflater.from(p0.getContext())
.inflate(R.layout.friendlist_row, p0, false)
return ViewHolder(view,context)
}
}
above is my adapter for RecycleView
class ViewHolder(itemView: View, context: Context): RecyclerView.ViewHolder(itemView) {
var userNameTxt: String ? = null
var userStatusTxt: String ? = null
var userProfilePicLink: String ? = null
fun bindView(user: Users, context: Context) {
var userName = itemView.findViewById < TextView > (R.id.friendlistNameTXID)
var userStatus = itemView.findViewById < TextView > (R.id.friendlistStatusTXID)
// var userProfilePic = itemView.findViewById<CircleImageView>(R.id.friendlistImageIVID)
//set the string so we can pass in the intent
userNameTxt = user.usernickname
userStatusTxt = user.userstatus
// userProfilePicLink = user.thumb_image
userName.text = userNameTxt
userStatus.text = userStatusTxt
// Picasso.get()
// .load(userProfilePicLink)
// .placeholder(R.drawable.ic_launcher_foreground)
// .into(userProfilePic)
}
}
above is my ViewHolder for myAdapter
class UsersFragment: Fragment() {
var mUserDatabase: DatabaseReference ? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup ? ,
savedInstanceState : Bundle ?
): View ? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_user, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle ? ) {
super.onViewCreated(view, savedInstanceState)
var linearLayoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
mUserDatabase = FirebaseDatabase.getInstance().reference.child("Users")
friendlistRVID.setHasFixedSize(true)
friendlistRVID.layoutManager = linearLayoutManager
friendlistRVID.adapter = UsersAdapter(mUserDatabase!!, context!!)
}
}
and above is the fragment that I use that has RecycleView inside it
It would't show anything and no error too. Thank you in advance
did you use itemCount in adapter?
override fun getItemCount(): Int {
return count
}
Related
Database
enter image description here
output
enter image description here
it only showing the last entry in array i wann show each entry
Adapter code
package com.example.caterers_app
class CommentAdapter(private val commentlist : ArrayList<CommentDataClass>) : RecyclerView.Adapter<CommentAdapter.MyViewHolder>() {
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): CommentAdapter.MyViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.commentstemplate,
parent,false)
return MyViewHolder(itemView) }
override fun getItemCount(): Int {
Log.d("size", commentlist.size.toString())
return commentlist.size
}
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val comment : TextView = itemView.findViewById(R.id.comment)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val comments = commentlist[position]
comments.list?.forEach {
holder.comment.text = it.toString()
}
//holder.comment.text = comments.list.toString()
}
}
if i use holder.comment.text = comments.list.toString()
it will display all array items in single recyclerview block
data class
package com.example.caterers_app
data class CommentDataClass(val list : List<String>? = null)
{
}
fragment
package com.example.caterers_app
class Comments(val doc : String) : Fragment() {
private lateinit var docid : String
private lateinit var recyclerView: RecyclerView
private lateinit var commentarraylist : ArrayList<CommentDataClass>
private lateinit var adapter: CommentAdapter
private lateinit var db : FirebaseFirestore
init {
docid = doc
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_comments, container, false)
recyclerView = view.findViewById(R.id.comentoo)
recyclerView.layoutManager = LinearLayoutManager(context)
recyclerView.setHasFixedSize(true)
commentarraylist = arrayListOf()
adapter = CommentAdapter(commentarraylist)
recyclerView.adapter = adapter
EventChangeListner()
return view
}
companion object {
fun newInstance(): Comments {
return Comments("null")
}
}
private fun EventChangeListner() {
var obj = CommentDataClass()
db = FirebaseFirestore.getInstance()
db.collection("User_Events")
.addSnapshotListener(object : EventListener<QuerySnapshot> {
override fun onEvent(value: QuerySnapshot?, error: FirebaseFirestoreException?) {
if(error!= null) {
return
}
for (dc : DocumentChange in value?.documentChanges!!){
if(dc.type == DocumentChange.Type.ADDED){
//eventarraylist.add(dc.document.toObject(EventsData::class.java))
if(dc.document.id.toString() == docid.toString()){
obj = dc.document.toObject(CommentDataClass::class.java)
commentarraylist.add(obj)
}
}
}
adapter.notifyDataSetChanged()
}
})
}
}
i want to display each array item in seperate recyclerview item how can i do that in kotlin using firebase firestore
You're passing an ArrayList<CommentDataClass> into the adapter when you likely want to pass List<String> instead, since CommentDataClass contains that List<String>?
You'll probably want to make CommentAdapter.commentlist modifiable:
class CommentAdapter() : RecyclerView.Adapter<CommentAdapter.MyViewHolder>() {
var commentlist = emptyList<String>()
...
}
and overwrite it once you have your CommentDataClass:
if(dc.document.id.toString() == docid.toString()){
obj = dc.document.toObject(CommentDataClass::class.java)
adapter.commentlist = obj.list
}
I'm using a RecyclerView to show some info from Firebase, with kotlin in Android Studio.
But when I click on the RecyclerView, it return the position as -1, so the page that opens that item is always empty...
This is my code from setOnClickListener on the ViewHolder:
class CustomViewHolder(view: View): RecyclerView.ViewHolder(view){
val titulo = view.findViewById<TextView>(R.id.txtTitle)
val localizacao = view.findViewById<TextView>(R.id.txtDescription)
//val urlPag = view.findViewById<TextView>(R.id.record_amount)
//val descricao = view.findViewById<TextView>(R.id.record_date)
val img = view.findViewById<ImageView>(R.id.imageItem)
init {
view.setOnClickListener{
val position: String = CustomViewHolder(it).bindingAdapterPosition.toString()
val intent = Intent(view.context, NotificationActivity::class.java).apply {
putExtra("id", position)
println(position)
}
view.context.startActivity(intent)
}
}
}
This is the fragment were the recyclerView is:
class InboxFragment : Fragment() {
private var listData: List<Notifications>? = null
private var adapter: MainAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_inbox, container, false)
val rv = view.findViewById<RecyclerView>(R.id.recyclerView)
rv.setHasFixedSize(true)
rv.layoutManager = LinearLayoutManager(context)
listData = ArrayList()
val nm = FirebaseDatabase.getInstance().getReference("notifications")
nm.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
if (dataSnapshot.exists()) {
for (npsnapshot in dataSnapshot.children) {
val l: Notifications? = npsnapshot.getValue(Notifications::class.java)
if (l != null) {
(listData as ArrayList<Notifications>).add(l)
}
}
adapter = MainAdapter(listData)
rv.adapter = adapter
}
}
override fun onCancelled(databaseError: DatabaseError) {}
})
return view
}
}
This is the adapter:
class MainAdapter(var listData: List<Notifications>?) : RecyclerView.Adapter<CustomViewHolder>(){
override fun getItemCount(): Int {
return listData!!.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
//create view
val layoutInflater = LayoutInflater.from(parent.context)
val cellForRow = layoutInflater.inflate(R.layout.inforow, parent, false)
return CustomViewHolder(cellForRow)
}
override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
val ld: Notifications = listData!![position]
holder.titulo.text = ld.titulo
holder.localizacao.text = ld.localizacao
Picasso.get().load(ld.img).into(holder.img)
}
}
Can someone please help?
Not sure why is this behaviour, but almost tried everything, please let me know in case you are aware of the fix for the issue
When I return from SellerAddNewProductActivity by clicking back button then RecyclerView always scroll to beginning
class SellerHomeFragment : Fragment() {
private var searchInputText:String = ""
private var sellerProductsViewListRecyclerView: RecyclerView? = null
private var layoutManager: RecyclerView.LayoutManager? = null
private var scroll_state: Parcelable? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val root = inflater.inflate(R.layout.fragment_seller_home, container, false)
sellerProductsViewListRecyclerView = root.findViewById(R.id.seller_products_view_list)
layoutManager = LinearLayoutManager(this.context)
sellerProductsViewListRecyclerView?.layoutManager = layoutManager
val searchText: EditText = root.findViewById(R.id.seller_search_product_name)
val searchProductsBtn: Button = root.findViewById(R.id.seller_search_products_btn)
val sellerViewByProductState: Spinner = root.findViewById(R.id.seller_view_by_product_state)
sellerViewByProductState.setSelection(0)
searchProductsBtn.setOnClickListener {
searchInputText = searchText.text.toString()
createProductRecyclerView()
}
sellerViewByProductState?.onItemSelectedListener = object : AdapterView.OnItemSelectedListener{
override fun onNothingSelected(parent: AdapterView<*>?) {
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
createProductRecyclerView()
}
}
return root
}
override fun onResume() {
super.onResume()
if(scroll_state!=null){
sellerProductsViewListRecyclerView!!.layoutManager!!.onRestoreInstanceState(scroll_state)
}
}
override fun onPause() {
super.onPause()
scroll_state = sellerProductsViewListRecyclerView!!.layoutManager!!.onSaveInstanceState()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
createProductRecyclerView()
}
private fun createProductRecyclerView() {
var productRef: DatabaseReference = FirebaseDatabase.getInstance().reference.child(
PRODUCTS_DB_NAME
)
var options: FirebaseRecyclerOptions<Products>? = null
val sellerViewByProductState: Spinner =
requireView().findViewById(R.id.seller_view_by_product_state)
val selectedProductState = sellerViewByProductState.selectedItem.toString()
options = FirebaseRecyclerOptions.Builder<Products>().setQuery(
productRef.child(selectedProductState).orderByChild(SID_PROPERTY)
.equalTo(FirebaseAuth.getInstance().currentUser!!.uid), Products::class.java
).setLifecycleOwner(this).build()
val adapter = object : FirebaseRecyclerAdapter<Products, ProductViewHolder>(options) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductViewHolder {
return ProductViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.product_items_layout, parent, false)
)
}
protected override fun onBindViewHolder(
holder: ProductViewHolder,
position: Int,
model: Products
) {
holder.txtProductName.text = model.pname
holder.txtProductDescription.text = model.description
holder.txtProductPrice.text = "Price = ₹ " + model.price.toString()
val context = holder.itemView.context
Picasso.with(this#SellerHomeFragment.context).load(model.image).networkPolicy(
NetworkPolicy.OFFLINE
).tag(context).into(holder.imageView,
object : Callback {
override fun onSuccess() {
}
override fun onError() {
Picasso.with(this#SellerHomeFragment.context).load(model.image)
.into(holder.imageView)
}
})
holder.itemView.setOnClickListener {
val intent: Intent = Intent(
this#SellerHomeFragment.context,
SellerAddNewProductActivity::class.java
)
intent.putExtra("category", model.category)
intent.putExtra("pid", model.pid)
val sellerViewByProductState: Spinner =
requireView().findViewById(R.id.seller_view_by_product_state)
val existingProductState = sellerViewByProductState.selectedItem.toString()
intent.putExtra("existingProductState", existingProductState)
startActivity(intent)
}
}
}
sellerProductsViewListRecyclerView?.setAdapter(adapter)
adapter.startListening()
}
}
I'm not sure I understand your code, but I think if you call function setAdapter(adapter) after added product you reload adapter.
When you add item to adapter use function notifyItemInserted() or notifyItemRangeInserted(position, range) on adapter.
i want to get recyclerview in my homefragment end set into elements from firestore firebase
my problem with get elements from firestore! maybe whos know how to search a problem because elements doesnt come frome firestore!
HomeFragment
class HomeFragment : Fragment() {
private val TAG = "HomeFragment"
private val firebaseRepository: FirebaseNoteRepo = FirebaseNoteRepo()
private var noteList: List<NotesModel> = ArrayList()
private val notesListAdapter: NotesListAdapterClass = NotesListAdapterClass(noteList)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_home, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
init(view)
}
private fun init(view: View) {
if(firebaseRepository.getUser() == null){
Log.d(TAG,"Error log user")
}else{ loadNotesData()}
note_list_recycler_view.layoutManager = LinearLayoutManager(context)
note_list_recycler_view.adapter = notesListAdapter
add_note_fab.setOnClickListener {
noteCreateDialog(view)
}
}
private fun loadNotesData() {
firebaseRepository.getNoteList().addOnCompleteListener {
if (it.isSuccessful){
noteList = it.result!!.toObjects(NotesModel::class.java)
notesListAdapter.notesListItem = noteList
notesListAdapter.notifyDataSetChanged()
}else{
Log.d(TAG,"Error: ${it.exception!!.message}")
}
}
}
my NotesModel
data class NotesModel(
val title: String = "",
val date: com.google.firebase.Timestamp? = null,
val post_type: Long = 0
)
my repository
FirebaseNoreRepo
class FirebaseNoteRepo {
private val firebaseAuth: FirebaseAuth = FirebaseAuth.getInstance()
private val firebaseFirestore: FirebaseFirestore = FirebaseFirestore.getInstance()
fun getUser(): FirebaseUser? {
return firebaseAuth.currentUser
}
fun getNoteList(): Task<QuerySnapshot> {
Log.d("HomeFragment"," ad "+ firebaseFirestore.collection("Notes").get().toString())
return firebaseFirestore
.collection("Notes")
.orderBy("title", Query.Direction.ASCENDING)
.get()
}
and my adapter
class NotesListAdapterClass (var notesListItem: List<NotesModel>):
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.note_layout,parent,false)
return ViewHolderNotes(view)
}
override fun getItemViewType(position: Int): Int {
return if (notesListItem[position].post_type == 1L){
POST_TYPE1
}else{
POST_TYPE1
}
}
override fun getItemCount(): Int {
Log.d("HomeFragment","notesListAdapter size : "+notesListItem.size)
return notesListItem.size
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (getItemViewType(position) == POST_TYPE1){
(holder as ViewHolderNotes).bind(notesListItem[position])
}
}
class ViewHolderNotes(itemView: View):RecyclerView.ViewHolder(itemView){
fun bind(notesModel: NotesModel){
itemView.note_title.text = notesModel.title
}
}
}
in my adapter i have Log.d he say me size of list of item ( is always equal 0), in firestore i have 2 elements. i dont understand why in log i have 0!
Database sceenshot
I am using MVVM with Room persistence and livedata. I am fetching the data from local database and want to show in the form of list in the recyclerView and my recyclerView is not showing anything.
My adapter is like any other regular adapter
RecyclerView Code
class MyInformationAdapter : RecyclerView.Adapter<MyInformationAdapter.ViewHolder>() {
private var myList: List<PersonInformation> = ArrayList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val view = layoutInflater.inflate(R.layout.my_adapter_data, parent, false)
return ViewHolder(view)
}
override fun getItemCount(): Int = myList.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
var myDataClass: PersonInformation = myList[position]
holder.name.text = myDataClass.name
holder.fName.text = myDataClass.fatherName
holder.email.text = myDataClass.email
holder.contact.text = myDataClass.contactNo.toString()
}
fun updateTheState(myList: List<PersonInformation>){
this.myList = myList
notifyDataSetChanged()
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var name: TextView = itemView.findViewById(R.id.yourName)
var fName: TextView = itemView.findViewById(R.id.yourFatherName)
var email: TextView = itemView.findViewById(R.id.yourEmail)
var contact: TextView = itemView.findViewById(R.id.yourContact)
}
}
RecyclerView Activity Code
class FinalActivity : AppCompatActivity() {
private var myDataList : List<PersonInformation> = ArrayList()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_final)
setAdapter()
}
private fun setAdapter() {
val adapter = MyInformationAdapter()
val layoutManager = LinearLayoutManager(this)
recyclerView.layoutManager = layoutManager
recyclerView.adapter = adapter
adapter.updateTheState(myDataList)
}
}
*Fragment as a View of MVVM *
class PersonalInformationFragment : Fragment() {
private var viewModel: PersonInformationViewModel? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_personal_information, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
btn.setOnClickListener {
viewModel = ViewModelProviders.of(this)[PersonInformationViewModel::class.java]
viewModel?.getAllData()?.observe(this, Observer {
this.setAllData(it)
})
val intent = Intent(activity, FinalActivity::class.java)
startActivity(intent)
}
}
private fun setAllData(personInformation: List<PersonInformation>) {
val setData = PersonInformation(
name.text.toString(),
fName.text.toString(),
email.text.toString(),
contact.text.toString().toInt()
)
viewModel?.setTheData(setData)
}
}