【问题标题】:Firebase valueEventListener and RecyclerView adapter's notifyItemChanged not working in the same activityFirebase valueEventListener 和 RecyclerView 适配器的 notifyItemChanged 不在同一个活动中工作
【发布时间】:2018-03-16 18:23:55
【问题描述】:

在尝试构建短信应用时,我添加了一个从 onCreate() 调用的 Firebase 值事件侦听器(...callFirebase() 函数),在我意识到我的 RecyclerView 停止之前,这一切对我来说都很好当我按下发送按钮时更新自身(..messageAdapter.notifyItemInserted(messageList.size()-1))。一旦我在 onCreate() 中注释 callFirebase() 行,RecyclerView 就会开始正常工作。请看代码,让我知道我做错了。

package com.siddhantkushwaha.www.raven;

import android.content.Intent;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.EditText;

import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.ValueEventListener;

import java.util.ArrayList;

public class chat_room extends AppCompatActivity {

    private FloatingActionButton sendButton;
    private EditText chatEditText;
    private String uid_1;
    private String uid_2;
    private ArrayList<Message> messageList;
    private MessageAdapter messageAdapter;
    private RecyclerView recyclerView;
    private String threadId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat_room);

        Intent intent = getIntent();
        uid_1 = intent.getStringExtra("sender");
        uid_2 = intent.getStringExtra("receiver");

        sendButton = findViewById(R.id.sendButton);
        chatEditText = findViewById(R.id.chatEditText);

        recyclerView = findViewById(R.id.messageRecyclerView);
        recyclerView.setHasFixedSize(true);

        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        messageList = new ArrayList();
        messageAdapter = new MessageAdapter(this, messageList, uid_1);
        recyclerView.setAdapter(messageAdapter);

        callFirebase();
    }

    private void callFirebase() {

        threadId = null;
        Util.getDatabase().getInstance().getReference(PathUtil.pathToThreadsList(uid_1) + "/" + uid_2).addListenerForSingleValueEvent(

                new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {

                        if(dataSnapshot.getValue() != null) {

                            threadId = dataSnapshot.getValue().toString();
                            System.out.println(threadId);
                        }
                    }

                    @Override
                    public void onCancelled(DatabaseError databaseError) {

                    }
                }
        );
    }

    @Override
    protected void onStart() {
        super.onStart();
    }

    public void sendButtonClicked(View view) {
        sendMessage();
    }

    private void sendMessage() {

        String text_message = chatEditText.getText().toString();
        if(text_message.length() == 0)
            return;
        messageList.add(new Message(text_message, uid_1, uid_2));
        messageAdapter.notifyItemInserted(messageList.size()-1);
        recyclerView.smoothScrollToPosition(messageAdapter.getItemCount());
        chatEditText.setText("");

        if(threadId != null) {

            addToThread(new Message(text_message, uid_1, uid_2));
        }
        else {

            createThread(new Message(text_message, uid_1, uid_2));

        }
    }

    private void createThread(Message _message) {

         String thread_key = Util.getDatabase().getInstance().getReference(PathUtil.pathToThreadsRoot()).push().getKey();
         Util.getDatabase().getInstance().getReference(PathUtil.pathToThreadDetails(thread_key)).setValue(new ThreadDetails(uid_1, uid_2));
         Util.getDatabase().getInstance().getReference(PathUtil.pathToThreadMessageList(thread_key)).push().setValue(_message);
         Util.getDatabase().getInstance().getReference(PathUtil.pathToThreadsList(uid_1) + "/" + uid_2).setValue(thread_key);
         Util.getDatabase().getInstance().getReference(PathUtil.pathToThreadsList(uid_2) + "/" + uid_1).setValue(thread_key);

         threadId = thread_key;
    }

    private void addToThread(Message _message) {
        Util.getDatabase().getInstance().getReference(PathUtil.pathToThreadMessageList(threadId)).push().setValue(_message);
    }
 }

【问题讨论】:

    标签: java android firebase firebase-realtime-database android-recyclerview


    【解决方案1】:

    发生这种情况是因为您在onDataChange() 方法内为threadId 变量分配了一个值,并且您试图在该方法之外使用它。仅将变量声明为全局变量并不能解决您的问题,因为 onDataChange() 方法具有异步行为,这意味着即使在您尝试从数据库中获取数据之前也会调用它。一个快速的解决方法是仅在该方法中使用该变量,或者使用我在 post 中回答的最后一部分。我还建议您查看此video

    【讨论】:

      猜你喜欢
      • 2018-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-01
      • 1970-01-01
      • 2019-11-11
      • 1970-01-01
      相关资源
      最近更新 更多