I'm trying to do a little login page that compares user input to a string and lets you past that screen when the password and email are correct but I can't seem to work it out.
`
package com.example.polihack2
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import android.widget.Button
import android.widget.EditText
val realpw="realpassword"
val realemail="realemail#gmail.com"
class SecondActivity : AppCompatActivity(){
override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
val buttonlogin = findViewById(R.id.login_button) as Button
/**buttonlogin.setOnClickListener{
intent = Intent(this, ThirdActivity::class.java)
startActivity(intent)
}*/
var email = findViewById(R.id.email) as EditText
var password = findViewById(R.id.password) as EditText
var login_button = findViewById(R.id.login_button) as Button
login_button.setOnClickListener{
}
}
}
`
just email and password returns you a Editable. If you want to reach text in those input you should use like this:
if(email.text.toString() == realemail && password.text.toString() == realpw){
intent = Intent(this, ThirdActivity::class.java)
startActivity(intent)
}
Related
Im trying to proceed on the next activty from Kotlin to Java it gives me a red line in ".java"
in
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
This is my whole code:
package com.heyletscode.artutorial
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Button
class Garlic : AppCompatActivity() {
lateinit var button : Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_garlic)
button = findViewById(R.id.Button)
button.setOnClickListener(listener)
}
val listener= View.OnClickListener { view ->
when (view.getId()) {
R.id.Button -> {
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
}
}
}
Ive tried different methods to proceed to next activty but give me red line in .java
I'd suggest moving your listener set-up to your onCreate like this
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_garlic)
button = findViewById(R.id.Button)
button.setOnClickListener { ->
val intent = Intent(this#Garlic, MainActivity::class.java)
startActivity(intent)
}
}
and the this is referencing to your onClickListener, append it with # followed by your activity name
val intent = Intent(this#Garlic, MainActivity::class.java)
may be you provide wrong context to Intent try below code
package com.heyletscode.artutorial
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Button
class Garlic : AppCompatActivity() {
lateinit var button : Button
private lateinit var context: Context //create object of context
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_garlic)
context= this#MainActivity // init context here
button = findViewById(R.id.Button)
button.setOnClickListener(listener)
}
val listener= View.OnClickListener { view ->
when (view.getId()) {
R.id.Button -> {
val intent = Intent(context, MainActivity::class.java) //replace this with context
startActivity(intent)
}
}
}
}
I just started learning Kotlin. I am making an application that saves bank (IBAN) information. I save the information locally using sharedpreferences.
I save the information to the list and save it as sharedpreferences.
Information is recorded on page 2 and I want to list this recorded information on page 1.
I was doing this simply in Flutter, but I couldn't understand how to do it in Kotlin.
package com.example.ibansfer
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.ibansfer.databinding.ActivityAddIbanBinding
import com.example.ibansfer.models.IbanModel
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
class AddIbanActivity : AppCompatActivity() {
private lateinit var binding: ActivityAddIbanBinding
private var ibanList: ArrayList<IbanModel> = ArrayList()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityAddIbanBinding.inflate(layoutInflater)
setContentView(binding.root)
setTitle("IBAN bilgisi ekle")
getSupportActionBar()?.setDisplayHomeAsUpEnabled(true);
val sharedPreferences = this.getSharedPreferences("ibans", MODE_PRIVATE)
val editor = sharedPreferences.edit()
fun saveData() {
val gson = Gson()
val json = gson.toJson(ibanList)
editor.putString("ibans", json)
editor.apply()
}
binding.ibanSaveBttn.setOnClickListener {
val ibanOwner = binding.ibanOwner.text.toString()
val bankName = binding.bankName.text.toString()
val ibanAdress = binding.ibanAdress.text.toString()
if (ibanOwner.isEmpty() || bankName.isEmpty() || ibanAdress.isEmpty()) {
Toast.makeText(this, "Lütfen tüm alanları doldurunuz.", Toast.LENGTH_LONG).show()
} else {
ibanList.add(IbanModel(ibanOwner, bankName, ibanAdress))
saveData()
Toast.makeText(this, "IBAN bilgileri başarıyla eklendi.", Toast.LENGTH_LONG).show()
finish()
}
}
}
}
If you save the data in SharedPrefferences, you can always retrieve it back in the other screen.
val sharedPref = activity?.getPreferences("ibans", Context.MODE_PRIVATE) ?: return
val myString = sharedPref.getString("ibans", defaultValue)
You can even set up a SharedPrefferences listener that will get notified whenever new data is added to it and act accordingly.
val sharedPreferencesListener =
SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key ->
// code to execute on changes here
}
activity?.getPreferences("ibans", Context.MODE_PRIVATE)
?.registerOnSharedPreferenceChangeListener(sharedPreferencesListener )
Also don't forget to unregister using unregisterOnSharedPreferenceChangeListener
Or alternatively, use Intents as the comment suggests to pass data between Activities/Fragments.
I have an adapter for my RecyclerView where I program that when I click on the element (of my RecyclerView) it executes an Intent with a putExtra to take me to another activity, the variable that contains my putExtra comes from the element that I clicked, but now I need to add a More variable that comes from the activity. The issue is that I don't know how to send it from the adapter.
this is my adapter.
package com.example.atipicoapp
import android.app.Activity
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.view.menu.ActionMenuItemView
import androidx.core.content.ContextCompat.startActivity
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.list_item.view.*
class MyAdapter(private val platoList : ArrayList<Plato>
) : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyAdapter.MyViewHolder {
val itemView =
LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)
itemView.platoTouch.setOnClickListener(View.OnClickListener { v: View ->
})
return MyViewHolder(itemView)
}
override fun onBindViewHolder(holder: MyAdapter.MyViewHolder, position: Int) {
val plato: Plato = platoList[position]
holder.platoName.text = plato.platoName
holder.platoDescription.text = plato.platoDescription
holder.platoPrecio.text = plato.platoPrecio.toString()
holder.platoCantidad.text = plato.platoCantidad.toString()
when(holder){
is MyViewHolder -> {
holder.bind(platoList[position])
}
}
}
override fun getItemCount(): Int {
return platoList.size
}
public class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val platoName: TextView = itemView.findViewById(R.id.platoNombre)
val platoDescription: TextView = itemView.findViewById(R.id.platoDescripcion)
val platoPrecio: TextView = itemView.findViewById(R.id.platoPrecio)
val platoTouch: LinearLayout = itemView.findViewById(R.id.platoTouch)
val platoCantidad: TextView = itemView.findViewById(R.id.platoCant)
private val mActivity = itemView.context as Activity
private val intent = Intent(mActivity,SlotActivity::class.java)
fun bind(plato: Plato){
platoTouch.setOnClickListener{
intent.putExtra("id", platoName.text.toString())
mActivity.startActivity(intent)
}
}
}
}
And this is my Activity which contains my RecyclerView and the variable I want to send.
package com.example.atipicoapp
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.firebase.firestore.*
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.activity_menu_atipico.*
class MenuAtipicoActivity : AppCompatActivity() {
private lateinit var recyclerView: RecyclerView
private lateinit var platoArrayList: ArrayList<Plato>
private lateinit var myAdapter: MyAdapter
private lateinit var db: FirebaseFirestore
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_menu_atipico)
recyclerView = findViewById(R.id.recyclerView)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.setHasFixedSize(true)
platoArrayList = arrayListOf()
myAdapter = MyAdapter(platoArrayList)
recyclerView.adapter = myAdapter
pedidoId = intent.extras?.getString("pedidoId") //This is the variable I need to send
EventChangeListener()
Setup()
}
private fun EventChangeListener() {
db = FirebaseFirestore.getInstance()
db.collection("Platos").addSnapshotListener(object : EventListener<QuerySnapshot> {
override fun onEvent(
value: QuerySnapshot?,
error: FirebaseFirestoreException?
) {
if (error != null) {
Log.e("Firestore Error", error.message.toString())
return
}
for (dc: DocumentChange in value?.documentChanges!!) {
if (dc.type == DocumentChange.Type.ADDED) {
platoArrayList.add(dc.document.toObject(Plato::class.java))
}
}
myAdapter.notifyDataSetChanged()
}
})
}
private fun Setup() {
botonAceptar.setOnClickListener {
val SlotIntent = Intent(this, SlotActivity::class.java).apply {
}
startActivity(SlotIntent)
}
}
}
How can I send the variable if the Intent is executed from the Adapter?
Or... If it is not recommended to send intent from my Adapter, how can I send them from the activity?
Knowing that I have to carry a variable that is in the item of the RecyclerView.
Thanks for your help <3
Firstly, create a MyAdapter constructor where you pass arrayList as well as pedidoId like, your MyAdapter should be something like below:
MyAdapter.class
class MyAdapter(private val platoList : ArrayList<Plato>, val pedidoId:String
) : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {
........
.....
....
//in your bind(..) method
fun bind(plato: Plato){
platoTouch.setOnClickListener{
intent.putExtra("id", platoName.text.toString())
intent.putExtra("pedidoId", pedidoId)
mActivity.startActivity(intent)
}
}
}
And, in your MenuAtipicoActivity you need to do something like:
MenuAtipicoActivity
class MenuAtipicoActivity : AppCompatActivity() {
...............
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_menu_atipico)
recyclerView = findViewById(R.id.recyclerView)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.setHasFixedSize(true)
platoArrayList = arrayListOf()
pedidoId = intent.extras?.getString("pedidoId") //This is the variable I need to send
myAdapter = MyAdapter(platoArrayList,pedidoId)
recyclerView.adapter = myAdapter
EventChangeListener()
Setup()
}
..........
........
}
I am attempting to make a function :
In recyclerView
when you click the user image ,navigate to the userActivity,
and when you click the "gift" icon ,navigate to otherActivity .
As follow is my Adapter.kt :
package Users.UserReceiveGiftItem
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gearsrun.www.R
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.user_receive_gift_item.view.*
class UserReceiveGiftAdapter(val userList : List<UserReceiveGiftItem>) : RecyclerView.Adapter<UserReceiveGiftAdapter.UserHolder>(){
private lateinit var mListener :onItemClickListener
interface onItemClickListener{
fun onItemClick(view:View,position: Int)
}
fun setOnItemClickListener(listener: onItemClickListener){
mListener = listener
}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): UserHolder {
val layoutInflater = LayoutInflater.from(parent.context)
return UserHolder(layoutInflater.inflate(R.layout.user_receive_gift_item,parent,false),mListener)
}
override fun onBindViewHolder(holder: UserReceiveGiftAdapter.UserHolder, position: Int) {
holder.render(userList[position])
}
override fun getItemCount(): Int = userList.size
class UserHolder(val view : View,listener:onItemClickListener) : RecyclerView.ViewHolder(view){
fun render(userList: UserReceiveGiftItem){
Picasso.get().load(userList.user_img).into(view.user_img)
view.user_name.text = userList.user_name
view.time.text = userList.time
view.userId.text = userList.userId
view.giftImg.setImageResource(userList.giftImg)
}
init {
view.setOnClickListener {
listener.onItemClick(it,absoluteAdapterPosition)
}
}
}
}
And I use in the Activity :
package com.gearsrun.www.UI.Receive
import Users.UserReceiveGiftItem.UserReceiveGiftAdapter
import Users.UserReceiveGiftItem.UserReceiveGiftItem
import android.content.Intent
import android.graphics.drawable.ColorDrawable
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.ImageView
import android.widget.Toast
import androidx.appcompat.app.ActionBar
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import com.gearsrun.www.R
import com.gearsrun.www.UI.Gift.AwaitingToUnwrapActivity
import com.gearsrun.www.UI.Sunflower.SunflowerAvailableActivity
import com.gearsrun.www.UI.User.UserDetailActivity
import kotlinx.android.synthetic.main.activity_who_receive_gift.*
import kotlinx.android.synthetic.main.user_receive_gift_item.view.*
class ReceiveActivity : AppCompatActivity() {
val userList : List<UserReceiveGiftItem> = listOf(
UserReceiveGiftItem(
"https://i.pinimg.com/564x/63/85/68/63856877880614e0dab080071513156f.jpg",
"Sharry",
"10 mins ago",
"517ddY",
R.drawable.donut
),
)
lateinit var gift_unwrap : ImageView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_receive)
changeColor(R.color.font_green)
initRecycler()
gift_unwrap = findViewById(R.id.gift_unwrap)
gift_unwrap.setOnClickListener {
}
}
private fun changeColor(resourseColor: Int) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.statusBarColor = ContextCompat.getColor(applicationContext, resourseColor)
}
val bar: ActionBar? = supportActionBar
if (bar != null) {
bar.setBackgroundDrawable(ColorDrawable(resources.getColor(resourseColor)))
}
}
fun initRecycler(){
rvUser.layoutManager = LinearLayoutManager(this)
val adapter = UserReceiveGiftAdapter(userList)
rvUser.adapter = adapter
adapter.setOnItemClickListener(object:UserReceiveGiftAdapter.onItemClickListener{
override fun onItemClick(view: View, position: Int) {
view.user_img.setOnClickListener {
val intent = Intent(this#ReceiveActivity,UserDetailActivity::class.java)
startActivity(intent)
}
view.giftImg.setOnClickListener {
val intent =Intent(this#ReceiveActivity,SunflowerAvailableActivity::class.java)
startActivity(intent)
}
}
})
}
}
It is a bit rare that it is able to navigate successfully ,however ,it dosen't react for the first click ..Could you please take a look my code ?Thank you guys in advance !!
You are using the click listener of the list item to add more click listeners to its children. So the first time you click it, the children don't have listeners yet and won't do anything. It is also error prone that a parent and its children both have click listeners, because it's undefined what will happen if you change the click listener as you are clicking it.
Instead, you should define your interface in the adapter to handle both types of clicks. In the ViewHolder, set click listeners only on the relevant children to be clicked.
Also, I think you're misusing lateinit. I would make the property nullable. And it is redundant to have a setter function for a property's value.
If you make the ViewHolder class inner, then you don't have to pass instances of the listener to the view holder instances, which will cause problems if you ever change the Adapter's listener.
Finally, personally I think the listener should return the list item, not the specific view and position in the list. Those are implementation details that the outer class doesn't need to know about.
class UserReceiveGiftAdapter(val userList : List<UserReceiveGiftItem>) : RecyclerView.Adapter<UserReceiveGiftAdapter.UserHolder>(){
var onItemClickListener: OnItemClickListener? = null
interface OnItemClickListener{
fun onUserClick(item: UserReceiveGiftItem)
fun onGiftClick(item: UserReceiveGiftItem)
}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): UserHolder {
val layoutInflater = LayoutInflater.from(parent.context)
return UserHolder(layoutInflater.inflate(R.layout.user_receive_gift_item,parent,false))
}
override fun onBindViewHolder(holder: UserReceiveGiftAdapter.UserHolder, position: Int) {
holder.render(userList[position])
}
override fun getItemCount(): Int = userList.size
inner class UserHolder(val view : View) : RecyclerView.ViewHolder(view){
fun render(userList: UserReceiveGiftItem){
Picasso.get().load(userList.user_img).into(view.user_img)
view.user_name.text = userList.user_name
view.time.text = userList.time
view.userId.text = userList.userId
view.giftImg.setImageResource(userList.giftImg)
}
init {
view.user_img.setOnClickListener {
onItemClickListener?.onUserClick(userList[absoluteAdapterPosition])
}
view.giftImg.setOnClickListener {
onItemClickListener?.onGiftClick(userList[absoluteAdapterPosition])
}
}
}
}
In Activity or Fragment:
adapter.onItemClickListener = object: UserReceiveGiftAdapter.OnItemClickListener {
override fun onUserClick(item: UserReceiveGiftItem) {
val intent = Intent(this#ReceiveActivity, UserDetailActivity::class.java)
startActivity(intent)
}
override fun onGiftClick(item: UserReceiveGiftItem) {
val intent = Intent(this#ReceiveActivity, SunflowerAvailableActivity::class.java)
startActivity(intent)
}
}
What I think after looking your code is, that you are setting adapter to your recyclerview first and then you are injecting a click listener to adapter.
What happens here is that some items from recycler view are loaded and they wouldn't have the click listener at that time,
for example if you scroll down, the newly appeared items on the screen will have proper click listeners, now if you scroll up, the previous one's will also have listener attached.
What to do to get rid of this problem:
Change your initRecycler() method as below:
fun initRecycler(){
rvUser.layoutManager = LinearLayoutManager(this)
val adapter = UserReceiveGiftAdapter(userList)
adapter.setOnItemClickListener(object:UserReceiveGiftAdapter.onItemClickListener{
override fun onItemClick(view: View, position: Int) {
view.user_img.setOnClickListener {
val intent = Intent(this#ReceiveActivity,UserDetailActivity::class.java)
startActivity(intent)
}
view.giftImg.setOnClickListener {
val intent =Intent(this#ReceiveActivity,SunflowerAvailableActivity::class.java)
startActivity(intent)
}
}
})
//set adapter after setting click listener to your adapter.
rvUser.adapter = adapter
}
I am having difficulties retrieving the information correctly from Firebase Firestore for my Recycler Adapter. I am not sure what I might be doing wrong but I used a Document Reference to get the required field but now it seems to just copy the same thing over and over, I want it to display each created users profile and display it on my RecyclerAdapter but am not sure what I should do and have tried different methods but get a
"No setter/field error" on my Model Class "Users".
This is my Firebase Schema
This is what it is outputting
This is what I have my code as so far
[Update]
This is what I have imported
import Models.User
import android.content.Intent
import android.content.res.Configuration
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.widget.Toolbar
import androidx.core.view.GravityCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.firebase.ui.firestore.FirestoreRecyclerAdapter
import com.firebase.ui.firestore.FirestoreRecyclerOptions
import com.google.android.material.navigation.NavigationView
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.firestore.*
import com.squareup.picasso.Picasso
import de.hdodenhof.circleimageview.CircleImageView
import kotlinx.android.synthetic.main.all_nearby_users.*
import kotlinx.android.synthetic.main.toolbar_layout.*
Oncreate
auth = FirebaseAuth.getInstance()
val customUserId = auth.currentUser!!.uid
val db = FirebaseFirestore.getInstance()
val userRef = db.collection("sUsers").document(customUserId)
val userQuery = db.collection("sUsers").orderBy("Full Name", Query.Direction.DESCENDING).limit(10)
//User List Layout
all_users_nearby_list.layoutManager = LinearLayoutManager(this)
//Firestore
val firestoreRecyclerOptions: FirestoreRecyclerOptions<Users> = FirestoreRecyclerOptions.Builder<Users>()
.setQuery(userQuery, Users::class.java)
.build()
adapter = UserFirestoreRecyclerAdapter(firestoreRecyclerOptions)
all_users_nearby_list.adapter = adapter
Firestore Recycler Adapter
private inner class UserFirestoreRecyclerAdapter internal constructor
(firestoreRecyclerOptions: FirestoreRecyclerOptions<Users>): FirestoreRecyclerAdapter<Users, UserViewHolder>(firestoreRecyclerOptions) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
val userView = LayoutInflater.from(parent.context)
.inflate(R.layout.display_users_profile, parent, false)
return UserViewHolder(userView)
}
override fun onBindViewHolder(holder: UserViewHolder, position: Int, model: Users) {
holder.setFullname(model.fullname)
holder.setProfileimage(model.profileImage)
}
}
UserViewHolder
private inner class UserViewHolder internal constructor (private val pView: View) : RecyclerView.ViewHolder(pView) {
internal fun setFullname(fullname: String) {
val username = pView.findViewById<TextView>(R.id.usernameTextView)
val db = FirebaseFirestore.getInstance()
val docRef = db.collection("sUsers").document(auth.currentUser!!.uid)
docRef.get()
.addOnSuccessListener { document ->
if (document != null) {
Log.d("HomeActivity", "DocumentSnapshot data: ${document.data}")
username.text = document.getString("Full Name")
} else {
Log.d("HomeActivity", "No such document")
}
}
.addOnFailureListener { exception ->
Log.d("HomeActivity", "get failed with ", exception)
}
username.text = fullname
Log.d("HomeActivity", "Current Data: " + fullname)
}
internal fun setProfileimage(profileImage: String) {
val userProfileImage = pView.findViewById<CircleImageView>(R.id.profileUserImage)
Picasso.get().load(profileImage).into(userProfileImage)
}
}
Model Class
package Models
class Users(
var fullname: String= "",
var profileImage: String= "",
var uid: String? = "",
var haircut: Boolean? = null,
var waxing: Boolean? = null,
var nails: Boolean? = null,
var profileRatingBar: Float? = 1.0f
)
My onStart and onStop
override fun onStart() {
super.onStart()
adapter!!.startListening()
}
override fun onStop() {
super.onStop()
if (adapter != null) {
adapter!!.stopListening()
}
}
This is how I would write your RecyclerView. Key points:
Don't make a 2nd FireStore query inside the ViewHolder
Your Firestore schema must exactly match your model
Use lifecycle owner instead of onStart/onStop
Firebase UI doesn't capture the uid; so do this manually (see apply)
ViewHolder must "hold" the views as fields (to avoid calling find every time)
Model represents 1 object, so I name it "User" not "Users"
Set layoutManager in XML to reduce boilerplate in onCreate
Layout XML
<androidx.recyclerview.widget.RecyclerView
...
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:itemCount="5"
tools:listitem="#layout/display_users_profile"
... />
Activity onCreate
val query = FirebaseFirestore.getInstance()
.collection("sUsers") // Why not "users" ?
.orderBy("fullname", Query.Direction.DESCENDING)
.limit(10)
val options = FirestoreRecyclerOptions.Builder<User>()
.setLifeCycleOwner(this)
.setQuery(query) { it.toObject(User::class.java)!!.apply { uid = it.id } }
.build()
all_users_nearby_list.adapter = UserFirestoreRecyclerAdapter(options)
Adapter
internal class UserFirestoreRecyclerAdapter(options: FirestoreRecyclerOptions<User>) :
FirestoreRecyclerAdapter<User, UserViewHolder>(options) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
LayoutInflater.from(parent.context)
.inflate(R.layout.display_users_profile, parent, false)
.let { UserViewHolder(it) }
override fun onBindViewHolder(holder: UserViewHolder, position: Int, model: Users) =
holder.bind(model)
}
ViewHolder
internal class UserViewHolder(itemView: View) :
RecyclerView.ViewHolder(itemView) {
// Hold view refs
private val usernameTextView: TextView = itemView.userNameTextView
private val profileUserImage: ImageView = itemView.profileUserImage
internal fun bind(model: User) {
model.apply {
usernameTextView.text = fullname
Picasso.get().load(profileImage).into(profileUserImage)
}
}
}
Model
// Set sensible defaults here (or null if no sensible default)
data class User(
var uid: String = "",
var fullname: String= "",
var profileImage: String= "",
var haircut: Boolean = false,
var waxing: Boolean = false,
var nails: Boolean = false,
var profileRatingBar: Float? = null
)