【问题标题】:How can I use FirebaseRecyclerAdapter for two Item layouts in a Chat Application如何在聊天应用程序中将 FirebaseRecyclerAdapter 用于两个项目布局
【发布时间】:2016-08-23 23:09:37
【问题描述】:

我正在制作一个使用 firebase 作为其后端的聊天应用程序。 目前我在设置项目布局以在 RecyclerView 中发送和接收消息时遇到问题。 当我对发送和接收消息使用相同的项目布局时,它工作得很好。 但我想将屏幕分成两部分,左侧用于发送消息,右侧用于接收消息。 在制作 FirebaseRecyclerAdapter 对象时,我只能传递一种布局作为其参数。我真的在努力解决这个问题。希望有人能帮助我。

private void loadMessages() {

    mAdapter = new FirebaseRecyclerAdapter<MessageToSend, NewMessageViewHolder>(
            MessageToSend.class,
            R.layout.single_message_new,
            NewMessageViewHolder.class,
            messageRef.child(sender).child(receiver)
    ) {
        @TargetApi(Build.VERSION_CODES.M)
        @Override
        protected void populateViewHolder(NewMessageViewHolder viewHolder, MessageToSend model, int position) {
            if (sender.equals(model.getSender())) {

                viewHolder.outMessage.setTextColor(getResources().getColor(R.color.darkGreen));
            }
            else {
                viewHolder.outMessage.setTextColor(Color.BLACK);
                //viewHolder.outMessage.setGravity(Gravity.RIGHT);
            }
            viewHolder.outMessage.setText(model.getMessage());
            viewHolder.sender.setText(model.getSender());
        }
    };

    mAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
        @Override
        public void onItemRangeInserted(int positionStart, int itemCount) {
            super.onItemRangeInserted(positionStart, itemCount);
            int friendlyMessageCount = mAdapter.getItemCount();
            int lastVisiblePosition = mLinearlayoutManager.findLastCompletelyVisibleItemPosition();
            // If the recycler view is initially being loaded or the user is at the bottom of the list, scroll
            // to the bottom of the list to show the newly added message.
            if (lastVisiblePosition == -1 ||
                    (positionStart >= (friendlyMessageCount - 1) && lastVisiblePosition == (positionStart - 1))) {
                recyclerView.scrollToPosition(positionStart);
            }
        }
    });
    recyclerView.setLayoutManager(mLinearlayoutManager);
    recyclerView.setAdapter(mAdapter);
}

ViewHolder 类

public static class InMessageViewHolder extends RecyclerView.ViewHolder{
    TextView inMessage;
    TextView receiver;
    CircleImageView receiverImage;

    public InMessageViewHolder(View itemView) {
        super(itemView);
        inMessage = (TextView) itemView.findViewById(R.id.textView11);
        receiver = (TextView) itemView.findViewById(R.id.textView12);
    }
} 

【问题讨论】:

    标签: android firebase firebase-realtime-database firebaseui


    【解决方案1】:

    您可以覆盖FirebaseRecyclerAdaptergetItemViewType 来实现此目的:

     // Check if the item at position is sender
     private boolean isSender(int position) {
       sender.equals(getItem(position).getSender());
     }
    
     @Override
     public int getItemViewType(int position) {
         if (isSender(position)) {
             return R.layout.my_sender_layout;
         } else {
             return R.layout.my_receiver_layout;
         }
     }
    

    这将导致RecyclerAdapter 有条件地扩展布局。但是,您仍然只能有一个 ViewHolder 子类,因此您需要确保在实现 public MyViewHolder(View itemView) 时,您的代码已准备好让 itemView 成为两种布局之一,并且如果这些布局具有不同的内容,那么一些 @987654328 @ 调用将返回 null。

    【讨论】:

    • 你能解释一下如何创建方法 isSender() 吗? loadMessages() 中应该是匿名的吗?为了从 isSender 方法返回 bool,应该与传入的位置参数进行比较?
    • 我更新了我的答案以包含一个示例 isSender 方法,
    【解决方案2】:

    你读过https://guides.codepath.com/android/Heterogenous-Layouts-inside-RecyclerView#prerequisite

    此外,为了使用 FirebaseRecyclerAdapter 的少量代码,您可以扩展并提供仅供查看的功能。其他将由 Firebase Query 等超类处理。

    当您覆盖 onCreateViewHolder 时,请注意模型布局可能为 -1

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-22
      相关资源
      最近更新 更多