问题
I am trying to populate my RecyclerView ViewHolder but I seem to be having difficulties. I think it may because of incorrect db reference but I am not quite sure what I am doing wrong.
I have tried using the datasnapshot from childEventListener to retrieve the values from my firebase db and pass to the RecyclerView but unfortunately have not been successful
private var mAuth: FirebaseAuth? = null
private var mChatKey: String? = null
private var mDatabase: DatabaseReference? = null
private var mMsgRef: DatabaseReference? = null
private var mRecyclerView: RecyclerView? = null
private var inputMsg: EditText? = null
private var sendMsgBtn: ImageView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat)
mChatKey = intent.extras!!.getString("Chat_id")
mAuth = FirebaseAuth.getInstance()
mDatabase = FirebaseDatabase.getInstance().reference.child("Chat").child(mChatKey!!).child("messages")
val toolbar: Toolbar = findViewById(R.id.chat_toolbar) //make toolbar value and get xml toolbar id
toolbar.title = "Lyrics Nigeria"
setSupportActionBar(toolbar)
if (supportActionBar != null) {
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
supportActionBar!!.setDisplayShowHomeEnabled(true)
}//set back button on toolbar
inputMsg = findViewById(R.id.chat_msg_edit)
sendMsgBtn = findViewById(R.id.chat_send_btn)
sendMsgBtn!!.setOnClickListener {
saveMsgToDatabase()
inputMsg!!.text = null
}
mRecyclerView = findViewById(R.id.chat_recycler_view)
mRecyclerView!!.layoutManager = LinearLayoutManager(this)
}
override fun onStart() {
super.onStart()
mDatabase!!.addChildEventListener(object : ChildEventListener {//set lyrics body to firebase database value
override fun onChildAdded(dataSnapshot: DataSnapshot, p1: String?) {
if (dataSnapshot.exists()){
Toasty.normal(this@ChatActivity, dataSnapshot.child("message").toString()).show()
displayMessage()
}
}
override fun onChildChanged(dataSnapshot: DataSnapshot, p1: String?) {
}
override fun onChildMoved(dataSnapshot: DataSnapshot, p1: String?) {
}
override fun onChildRemoved(dataSnapshot: DataSnapshot) {
}
override fun onCancelled(databaseError: DatabaseError) {
}
})
}
private fun saveMsgToDatabase() {
val messageKey = mDatabase!!.push().key
val message = inputMsg!!.text.toString()
val dateTime = SimpleDateFormat("MMM dd, yyyy HH:mm a", Locale.getDefault()).format(Date())
val allMessageKey: HashMap<String, Any> = HashMap()
mDatabase!!.updateChildren(allMessageKey)
mMsgRef = mDatabase!!.child(messageKey!!)
val msgInfoMap: HashMap<String, Any> = HashMap()
msgInfoMap.put("name", mAuth!!.currentUser!!.displayName.toString())
msgInfoMap.put("message", message)
msgInfoMap.put("time", dateTime)
mMsgRef!!.updateChildren(msgInfoMap)
}
private fun displayMessage() {
val mDatabaseMsgs = mDatabase!!.push().key
val mRef = mDatabase!!.child(mDatabaseMsgs!!)
val firebaseRecyclerAdapter = object : FirebaseRecyclerAdapter<MessageAdapter, ChatViewHolder>(MessageAdapter::class.java, R.layout.layout_listitem_inmsg_chat, ChatViewHolder::class.java, mRef) {
override fun populateViewHolder(viewHolder: ChatViewHolder, model: MessageAdapter, position: Int) {
viewHolder.setName(model.userName!!)
viewHolder.setMessage(model.userMessage!!)
viewHolder.setTime(model.msgTime!!)
}
}
mRecyclerView!!.adapter = firebaseRecyclerAdapter
}
class ChatViewHolder(val mView: View) : RecyclerView.ViewHolder(mView) {
fun setName(name: String) {
val userName = mView.findViewById<View>(R.id.user_display_text) as TextView
userName.text = name
}
fun setMessage(message: String) {
val userMessage = mView.findViewById<View>(R.id.msg_display_text) as TextView
userMessage.text = message
}
fun setTime(time: String) {
val msgTime = mView.findViewById<View>(R.id.time_display_text) as TextView
msgTime.text = time
}
}
}
The app crashes when I enter the above code and only way I can reach the db values so far is by using the childEventListener but can't populate viewHolder. Will appreciate any help. Thanks.
Below is the error report:
2019-09-11 17:08:42.290 6961-6961/? E/RecyclerView: Cannot scroll to position a LayoutManager set. Call setLayoutManager with a non-null argument.
2019-09-11 17:08:42.347 6961-6961/? E/RecyclerView: Cannot scroll to position a LayoutManager set. Call setLayoutManager with a non-null argument.
2019-09-11 17:08:42.453 10677-10677/com.lyricsnigeria.lyricsnigeria E/RecyclerView: No adapter attached; skipping layout
2019-09-11 17:08:43.283 6961-7153/? E/native: personalized-decoder.cc:832 Cannot create punctuation prediction model.
2019-09-11 17:08:43.283 6961-7153/? E/native: personalized-decoder.cc:839 Cannot create graph rescoring model.
2019-09-11 17:08:43.386 6961-6961/? E/RecyclerView: Cannot scroll to position a LayoutManager set. Call setLayoutManager with a non-null argument.
2019-09-11 17:08:43.717 6961-6961/? E/RecyclerView: Cannot scroll to position a LayoutManager set. Call setLayoutManager with a non-null argument.
2019-09-11 17:08:44.204 6961-6961/? E/RecyclerView: Cannot scroll to position a LayoutManager set. Call setLayoutManager with a non-null argument.
2019-09-11 17:08:44.213 6961-6961/? E/RecyclerView: Cannot scroll to position a LayoutManager set. Call setLayoutManager with a non-null argument.
2019-09-11 17:08:44.223 6961-6961/? E/RecyclerView: Cannot scroll to position a LayoutManager set. Call setLayoutManager with a non-null argument.
2019-09-11 17:08:44.284 6961-6961/? E/RecyclerView: Cannot scroll to position a LayoutManager set. Call setLayoutManager with a non-null argument.
2019-09-11 17:08:44.368 6961-6961/? E/RecyclerView: Cannot scroll to position a LayoutManager set. Call setLayoutManager with a non-null argument.
2019-09-11 17:08:44.547 6961-6961/? E/RecyclerView: Cannot scroll to position a LayoutManager set. Call setLayoutManager with a non-null argument.
2019-09-11 17:08:48.806 11188-11188/? E/ACRA: Skipping ANR Detector for process: com.instagram.android:mqtt
2019-09-11 17:08:50.051 6961-6961/? E/RecyclerView: Cannot scroll to position a LayoutManager set. Call setLayoutManager with a non-null argument.
2019-09-11 17:08:50.414 6961-6961/? E/RecyclerView: Cannot scroll to position a LayoutManager set. Call setLayoutManager with a non-null argument.
2019-09-11 17:08:50.635 6961-6961/? E/RecyclerView: Cannot scroll to position a LayoutManager set. Call setLayoutManager with a non-null argument.
2019-09-11 17:08:50.823 6961-6961/? E/RecyclerView: Cannot scroll to position a LayoutManager set. Call setLayoutManager with a non-null argument.
2019-09-11 17:08:51.465 6961-6961/? E/RecyclerView: Cannot scroll to position a LayoutManager set. Call setLayoutManager with a non-null argument.
2019-09-11 17:08:52.501 6961-6961/? E/RecyclerView: Cannot scroll to position a LayoutManager set. Call setLayoutManager with a non-null argument.
2019-09-11 17:08:52.523 6961-6961/? E/RecyclerView: Cannot scroll to position a LayoutManager set. Call setLayoutManager with a non-null argument.
2019-09-11 17:08:52.613 6961-6961/? E/RecyclerView: Cannot scroll to position a LayoutManager set. Call setLayoutManager with a non-null argument.
2019-09-11 17:08:52.656 6961-6961/? E/RecyclerView: Cannot scroll to position a LayoutManager set. Call setLayoutManager with a non-null argument.
2019-09-11 17:08:52.696 6961-6961/? E/RecyclerView: Cannot scroll to position a LayoutManager set. Call setLayoutManager with a non-null argument.
2019-09-11 17:08:52.882 6961-6961/? E/RecyclerView: Cannot scroll to position a LayoutManager set. Call setLayoutManager with a non-null argument.
ChatActivity xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color4"
android:keepScreenOn="false"
tools:context=".ChatActivity"
android:id="@+id/chat_recycler_lyt">
<include
android:id="@+id/chat_toolbar"
layout="@layout/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/chat_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
android:layout_above="@+id/input_msg_lyt"
android:layout_below="@+id/chat_toolbar"
tools:listitem="@layout/layout_listitem_inmsg_chat"/>
<RelativeLayout
android:id="@+id/input_msg_lyt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal"
android:background="@color/colorBackground">
<EditText
android:id="@+id/chat_msg_edit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/edit_text_bg2"
android:padding="10dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:layout_marginLeft="20dp"
android:layout_marginStart="20dp"
android:hint="@string/start_typing"
android:singleLine="false"
android:inputType="textCapSentences|textMultiLine"
android:layout_toLeftOf="@+id/chat_send_btn"
android:layout_toStartOf="@+id/chat_send_btn" />
<ImageView
android:id="@+id/chat_send_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_send_black_24dp"
android:layout_gravity="center"
android:layout_margin="8dp"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>
</RelativeLayout>
list_item xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="start|bottom"
android:layout_margin="5dp"
android:background="@drawable/chat_bg">
<TextView
android:id="@+id/user_display_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:padding="2dp"
android:textAllCaps="false"
android:textColor="@color/colorBlack"
android:textSize="12sp"
android:layout_marginLeft="5dp" />
<TextView
android:id="@+id/msg_display_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="2dp"
android:layout_marginLeft="2dp"
android:padding="10dp"
android:textAllCaps="false"
android:textColor="@color/colorBlack"
android:textSize="16sp" />
<TextView
android:id="@+id/time_display_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="15dp"
android:layout_marginRight="15dp"
android:padding="2dp"
android:textAllCaps="false"
android:textColor="@color/colorBlack"
android:textSize="12sp"
android:layout_gravity="end|bottom"/>
</LinearLayout>
Adapter class:
class MessageAdapter {
var userName:String? = null
var userMessage:String? = null
var msgTime:String? = null
constructor(userName:String, userMessage:String, msgTime:String) {
this.userName = userName
this.userMessage = userMessage
this.msgTime = msgTime
}
constructor() {}
}
And the screenshot of my db:
回答1:
The problem in your code lies in the fact that the name of the fields in your MessageAdapter
class are different than the name of the properties in your database. You have in your MessageAdapter
class three fields named userName
, userMessage
and msgTime
while in the database I see that the names are different, name
, message
and time
and this is not correct. The names must match.
A solution might be to change the name of the fields in your MessageAdapter
class like this:
class MessageAdapter {
var name:String? = null
var message:String? = null
var time:String? = null
constructor(name:String, message:String, time:String) {
this.name = name
this.message = message
this.time = time
}
constructor() {}
}
And your problem will be solved or you can use an annotation
class MessageAdapter {
@get:PropertyName("name")
@set:PropertyName("name")
var userName:String? = null
@get:PropertyName("message")
@set:PropertyName("message")
var userMessage:String? = null
@get:PropertyName("time")
@set:PropertyName("time")
var msgTime:String? = null
constructor(userName:String, userMessage:String, msgTime:String) {
this.userName = userName
this.userMessage = userMessage
this.msgTime = msgTime
}
constructor() {}
}
And you are geeting the following error:
E/RecyclerView: Cannot scroll to position a LayoutManager set. Call setLayoutManager with a non-null argument.
Because you are trying to scroll to last position which actually does not exist since there are no items displayed in your RecyclerView
.
来源:https://stackoverflow.com/questions/57882307/i-am-trying-to-get-the-correct-reference-to-my-firebase-database-child-and-set-t