简体   繁体   English

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

[英]No method of RecyclerViewAdapter working except for getItemCount()

I am trying to build chat feature in my android app. 我正在尝试在Android应用中建立聊天功能。 I am using the Recycler view to show the chat history. 我正在使用“回收站”视图来显示聊天记录。 But when I call the RecyclerView adapter, it only calls the constructor and the getItemCount() method which returns 4 (which is correct). 但是,当我调用RecyclerView适配器时,它仅调用构造函数和getItemCount()方法,该方法返回4(正确)。 Can someone please help me. 有人可以帮帮我吗。 Here's the code. 这是代码。

I read that calling the setLayoutManager() after the set adapter method could fix the problem but it didn't work for me. 我读到在设置适配器方法之后调用setLayoutManager()可以解决问题,但对我而言不起作用。

Already tried this RecyclerView not calling onCreateViewHolder or onBindView 已经尝试过此RecyclerView而不调用onCreateViewHolder或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格式

    <?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>

Try setting LayoutManager before setting the adapter 在设置适配器之前尝试设置LayoutManager

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

Setup your RecyclerView in onCreate() , not in the ValueEventListener callback: 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()));

Then in the ValueEventListener callback just add the messages to your list and call mMessageAdapter.notifyDatasetChanged() : 然后在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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM