除了getItemCount()之外,没有RecyclerViewAdapter的任何方法

时间:2019-07-12 07:59:58

标签: android firebase android-recyclerview

我正在尝试在我的Android应用中建立聊天功能。我正在使用“回收站”视图来显示聊天记录。但是,当我调用RecyclerView适配器时,它仅调用构造函数和getItemCount()方法,该方法返回4(正确)。有人可以帮帮我吗。这是代码。

我了解到,在设置适配器方法之后调用setLayoutManager()可以解决问题,但对我不起作用。

已经尝试过此RecyclerView not calling onCreateViewHolder or onBindView

    public class MessageListActivity extends AppCompatActivity {

    private static final int ACTIVITY_NUM = 1;


    private RecyclerView mMessageRecycler;
    private MessageListAdapter mMessageAdapter;
    private Button mSendButton;
    private EditText mTextbox;

    List<Message> messageList = new ArrayList<>();

    private ChatListItem chat;
    Context context;

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

        Intent i = getIntent();
        chat = (ChatListItem) i.getSerializableExtra("CHAT");

        mMessageRecycler = (RecyclerView) findViewById(R.id.reyclerview_message_list);

        mSendButton = (Button) findViewById(R.id.button_chatbox_send);
        mTextbox = (EditText) findViewById(R.id.edittext_chatbox);

        sendMessage(mSendButton);

        //creating bottom navigation view
        setupBottomNavigationView();

        DatabaseReference mRef = FirebaseDatabase.getInstance().getReference().child("Chat").child(chat.getChatId());
        mRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                Iterable<DataSnapshot> children = dataSnapshot.getChildren();
                for(DataSnapshot child: children){

                    messageList.add(child.getValue(Message.class));
                }

                Log.d("testing0 ListActivity", messageList.toString());

                mMessageAdapter = new MessageListAdapter(MessageListActivity.this, messageList);
                mMessageRecycler.setAdapter(mMessageAdapter);
                mMessageRecycler.setLayoutManager(new LinearLayoutManager(getBaseContext()));

            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

    }

    /**
     * BottomNavigationView setup
     */
    private void setupBottomNavigationView() {
        Log.d("MessageListActivity", "setupBottomNavigationView: setting up BottomNavigationView");
        BottomNavigationView bottomNavigationView = findViewById(R.id.bottomNavViewBar);
        BottomNavigationViewHelper.enableNavigation(MessageListActivity.this,bottomNavigationView);
        Menu menu = bottomNavigationView.getMenu();
        MenuItem menuItem = menu.getItem(ACTIVITY_NUM);
        menuItem.setChecked(true);
    }

    private void sendMessage(Button button){
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String content = mTextbox.getText().toString().trim();
                if (content.length() > 0) {

                    Message newMessage = new Message();
                    newMessage.setTextMessage(mTextbox.getText().toString());
                    newMessage.setIdSender(chat.getCustomerPhone());
                    newMessage.setIdReceiver(chat.getDriverPhone());
                    newMessage.setTimestamp(System.currentTimeMillis());
                    FirebaseDatabase.getInstance().getReference().child("Chat").child(chat.getChatId()).push().setValue(newMessage);

                    mTextbox.setText("");
                }
            }
        });

    }

}

    public class MessageListAdapter extends RecyclerView.Adapter {

    private static final int VIEW_TYPE_MESSAGE_SENT = 1;
    private static final int VIEW_TYPE_MESSAGE_RECEIVED = 2;

    private Context mContext;
    //private List<BaseMessage> mMessageList;
    private List<Message> mMessageList;

    //get current user
    private String phone_Number;
    private FirebaseAuth mauth = FirebaseAuth.getInstance();
    private FirebaseUser user = mauth.getCurrentUser();

    public MessageListAdapter(Context context, List<Message> messageList) {

        Log.d("testing3 messageAdapter", "inside constructor");

        mContext = context;
        mMessageList = messageList;
    }

    @Override
    public int getItemCount() {

        Log.d("testing4 messageAdapter", String.valueOf(mMessageList.size()));

        return mMessageList.size();
    }


    // Determines the appropriate ViewType according to the sender of the message.
    @Override
    public int getItemViewType(int position) {

        Log.d("testing0 messageAdaper", "inside messageListAdapter");

        Message message = (Message) mMessageList.get(position);

        phone_Number = user.getPhoneNumber();

        if (message.getIdSender().equals(phone_Number)) {
            // If the current user is the sender of the message
            return VIEW_TYPE_MESSAGE_SENT;
        } else {
            // If some other user sent the message
            return VIEW_TYPE_MESSAGE_RECEIVED;
        }
    }

    // Inflates the appropriate layout according to the ViewType.
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view;

        Log.d("testing1 messageAdapter", "inside onCreateViewHolder");

        if (viewType == VIEW_TYPE_MESSAGE_SENT) {
            view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.item_message_sent, parent, false);
            return new SentMessageHolder(view);
        } else if (viewType == VIEW_TYPE_MESSAGE_RECEIVED) {
            view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.item_message_received, parent, false);
            return new ReceivedMessageHolder(view);
        }

        return null;
    }

    // Passes the message object to a ViewHolder so that the contents can be bound to UI.
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        Message message = (Message) mMessageList.get(position);

        Log.d("testing2 messageAdaper", "inside onBindViewHolder");

        switch (holder.getItemViewType()) {
            case VIEW_TYPE_MESSAGE_SENT:
                ((SentMessageHolder) holder).bind(message);
                break;
            case VIEW_TYPE_MESSAGE_RECEIVED:
                ((ReceivedMessageHolder) holder).bind(message);
        }
    }

    private class SentMessageHolder extends RecyclerView.ViewHolder {
        TextView messageText, timeText;

        SentMessageHolder(View itemView) {
            super(itemView);

            messageText = (TextView) itemView.findViewById(R.id.text_message_body);
            timeText = (TextView) itemView.findViewById(R.id.text_message_time);
        }

        void bind(Message message) {
            messageText.setText(message.getTextMessage());

            // Format the stored timestamp into a readable String using method.
            timeText.setText(new SimpleDateFormat("hh:mm KK").format(new Date(message.getTimestamp())));

        }
    }

    private class ReceivedMessageHolder extends RecyclerView.ViewHolder {
        TextView messageText, timeText;

        ReceivedMessageHolder(View itemView) {
            super(itemView);

            messageText = (TextView) itemView.findViewById(R.id.text_message_body);
            timeText = (TextView) itemView.findViewById(R.id.text_message_time);
        }

        void bind(Message message) {

            messageText.setText(message.getTextMessage());
            timeText.setText(new SimpleDateFormat("hh:mm KK").format(new Date(message.getTimestamp())));
        }
    }

XML

    <?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.widget.ConstraintLayout
    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"
    tools:context=".MessageActivity.MessageListActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/reyclerview_message_list"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent">
    </androidx.recyclerview.widget.RecyclerView>

    <!-- A horizontal line between the chatbox and RecyclerView -->
    <View
        android:layout_width="0dp"
        android:layout_height="2dp"
        android:background="#dfdfdf"
        android:layout_marginBottom="0dp"
        app:layout_constraintBottom_toTopOf="@+id/layout_chatbox"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>

    <LinearLayout
        android:id="@+id/layout_chatbox"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:minHeight="48dp"
        android:background="#ffffff"
        app:layout_constraintBottom_toTopOf="@id/navBarContainer"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent">

        <EditText
            android:id="@+id/edittext_chatbox"
            android:hint="Enter message"
            android:background="@android:color/transparent"
            android:layout_gravity="center"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:maxLines="6"/>

        <Button
            android:id="@+id/button_chatbox_send"
            android:text="SEND"
            android:textSize="14dp"
            android:background="?attr/selectableItemBackground"
            android:clickable="true"
            android:layout_width="64dp"
            android:layout_height="48dp"
            android:gravity="center"
            android:layout_gravity="bottom" />

    </LinearLayout>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/navBarContainer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent">

        <include layout="@layout/layout_navbar" />


    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

2 个答案:

答案 0 :(得分:0)

在设置适配器之前尝试设置LayoutManager

mMessageRecycler.setLayoutManager(new LinearLayoutManager(MessageListActivity.this,RecyclerView.VERTICAL,false));
mMessageRecycler.setAdapter(mMessageAdapter);

答案 1 :(得分:0)

onCreate()中而不是在ValueEventListener回调中设置RecyclerView:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    mMessageAdapter = new MessageListAdapter(MessageListActivity.this, messageList);
    mMessageRecycler.setAdapter(mMessageAdapter);
    mMessageRecycler.setLayoutManager(new LinearLayoutManager(getBaseContext()));

然后在ValueEventListener回调中,只需将消息添加到列表中并调用mMessageAdapter.notifyDatasetChanged()

@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
    Iterable<DataSnapshot> children = dataSnapshot.getChildren();
    for(DataSnapshot child: children){
        messageList.add(child.getValue(Message.class));
    }

    Log.d("testing0 ListActivity", messageList.toString());
    mMessageAdapter.notifyDatasetChanged();
}