【问题标题】:how to implement a SetOnItemClickListener FirebaseRecyclerViewAdapter如何实现 SetOnItemClickListener FirebaseRecyclerViewAdapter
【发布时间】:2016-03-10 16:39:03
【问题描述】:

如何在 Firebase RecyclerView 适配器中实现 SetOnItemClickListener 事件? 我以文档、聊天应用为例:

 private FirebaseRecyclerViewAdapter mAdapter;

RecyclerView recycler = (RecyclerView) findViewById(R.id.messages_recycler);
    recycler.setHasFixedSize(true);
    recycler.setLayoutManager(new LinearLayoutManager(this));

    mAdapter = new FirebaseRecyclerViewAdapter<ChatMessage, ChatMessageViewHolder>(ChatMessage.class, android.R.layout.two_line_list_item, ChatMessageViewHolder.class, mRef) {
        @Override
        public void populateViewHolder(ChatMessageViewHolder chatMessageViewHolder, ChatMessage chatMessage) {
            chatMessageViewHolder.nameText.setText(chatMessage.getName());
            chatMessageViewHolder.messageText.setText(chatMessage.getMessage());
        }
    };
    recycler.setAdapter(mAdapter);

【问题讨论】:

    标签: android firebase firebase-realtime-database firebaseui


    【解决方案1】:

    这是我的解决方案。这对我有用

    ViewHolder 类

    public class StudentViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    
    public TextView textViewName;
    public TextView textViewRoll;
    public TextView textViewAge;
    
    
    public MyViewHolderClickListener mListener;
    
    private String TAG= getClass().getSimpleName();
    
    public static interface MyViewHolderClickListener{
    
        public void onTextViewNameClick(View view, int position);
        public void onTextViewRollClick(View view, int position);
    }
    
    public StudentViewHolder(View itemView) {
        super(itemView);
        textViewName = (TextView) itemView.findViewById(R.id.textViewName);
        textViewRoll = (TextView) itemView.findViewById(R.id.textViewRoll);
        textViewAge = (TextView) itemView.findViewById(R.id.textViewAge);
    
        textViewName.setOnClickListener(this);
        textViewRoll.setOnClickListener(this);
    }
    
    
    public void bindToStudent(Student student){
        if (student == null) {
            return;
        }
    
        textViewName.setText("Name: " +  student.getName());
        textViewRoll.setText( "Roll: " + student.getRoll());
        textViewAge.setText( "Age: " +  student.getAge());
    }
    
    public void setCustomOnClickListener(MyViewHolderClickListener listener  ){
        this.mListener = listener;
    }
    
    @Override
    public void onClick(View view) {
    
        Log.d(TAG, "onClick at " + getAdapterPosition());
        Log.d(TAG, "id: " + view.getId());
    
        if( mListener!= null ){
            switch (view.getId()) {
                case R.id.textViewName:
                    mListener.onTextViewNameClick(view, getAdapterPosition());
                    break;
                case R.id.textViewRoll:
                    mListener.onTextViewRollClick(view, getAdapterPosition());
                    break;
    
                default:
                    break;
            }
    
        }
    
     }
    
    
    
    }
    

    适配器类

    public class StudentListAdapter extends FirebaseRecyclerAdapter<Student, StudentViewHolder> {
    
    Activity parentActivity;
    StudentViewHolder.MyViewHolderClickListener myViewHolderClickListener;
    
    private String TAG = getClass().getSimpleName();
    
    public StudentListAdapter(Activity mActivity, Class<Student> modelClass, int modelLayout, Class<StudentViewHolder> viewHolderClass, Query ref) {
        super(modelClass, modelLayout, viewHolderClass, ref);
        parentActivity = mActivity;
    }
    
    
    @Override
    public StudentViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        StudentViewHolder viewHolder = super.onCreateViewHolder(parent, viewType);
        // adding my MyViewHolderClickListener here
        viewHolder.setCustomOnClickListener(myViewHolderClickListener);
        return viewHolder;
    }
    
    @Override
    protected void populateViewHolder(StudentViewHolder viewHolder, final Student model, final int position) {
    
        Log.d(TAG, model.toString());
        Log.d(TAG, getRef(position).getKey());
    
        // bind view
        viewHolder.bindToStudent(model);
    }
    
    
    public void setMyViewHolderClickListener(StudentViewHolder.MyViewHolderClickListener listener){
        this.myViewHolderClickListener = listener;
    }
    
    
    }
    

    在活动类中

            mAdapter = new StudentListAdapter(this, Student.class, R.layout.list_item, StudentViewHolder.class, studentQuery);
        mAdapter.setMyViewHolderClickListener(new StudentViewHolder.MyViewHolderClickListener() {
            @Override
            public void onTextViewNameClick(View view, int position) {
                Log.d(TAG, "Name Click at " +position);
            }
    
            @Override
            public void onTextViewRollClick(View view, int position) {
                Log.d(TAG, "Roll Click at " +position);
            }
        });
    
        recyclerView.setAdapter(mAdapter);
    

    【讨论】:

      【解决方案2】:

      可能有很多方法可以做到这一点,但这是我刚刚快速尝试过的一种。

      ChatMessageViewHolder 类有一个成员字段,用于保存每条聊天消息的根视图:

      public static class ChatHolder extends RecyclerView.ViewHolder {
          View mView;
      
          public ChatHolder(View itemView) {
              super(itemView);
              mView = itemView;
          }
      

      我们可以使用mView 成员来访问可点击视图。您应该mView 添加一个getter,但我试图在此处尽量减少更改。

      那么在populateView 中,我们可以使用具有额外position 参数的重载并将其与OnClickListener 连接起来,如下所示:

          mRecycleViewAdapter = new FirebaseRecyclerAdapter<Chat, ChatHolder>(Chat.class, R.layout.message, ChatHolder.class, mChatRef) {
              @Override
              public void populateViewHolder(ChatHolder chatView, Chat chat, final int position) {
                  chatView.setName(chat.getName());
                  chatView.setText(chat.getText());
      
                  if (mAuthData != null && chat.getUid().equals(mAuthData.getUid())) {
                      chatView.setIsSender(true);
                  } else {
                      chatView.setIsSender(false);
                  }
      
                  chatView.mView.setOnClickListener(new View.OnClickListener() {
                      @Override
                      public void onClick(View view) {
                          Log.w(TAG, "You clicked on "+position);
                          mRecycleViewAdapter.getRef(position).removeValue();                        
                      }
                  });
              }
          };
      

      这个问题的答案提供了大量的灵感:RecyclerView onClick。只要能确定用户点击的位置,就可以使用mRecycleViewAdapter.getRef(position)sn -p 获取被点击项目的数据库引用。

      更新

      再想一想,我可能会更喜欢这个答案https://stackoverflow.com/a/26196831/209103

          mMessages.addOnItemTouchListener(new RecyclerItemClickListener(this, new RecyclerItemClickListener.OnItemClickListener() {
              @Override
              public void onItemClick(View view, int position) {
                  Log.w(TAG, "You clicked on "+position);
                  mRecycleViewAdapter.getRef(position).removeValue();
              }
          }));
      

      它使用我链接的答案中的RecyclerItemClickListener 帮助类。正如已经说过的:只要您有一个单击/触摸侦听器来告诉您所选项目的位置,它的其余 FirebaseUI 方面将是相同的:调用 adapter.getRef(position) 以获取所选项目的数据库引用项目。

      【讨论】:

      • 弗兰克,非常好!谢谢!他们的两个选项效果很好,但在我看来,第一个更好,虽然更广泛一些。对于其中的“动画效果”,当您单击 Recycler 视图时,该项目在第二次不完美运行。我将“View mView”放在 ChatHolder 类中,并添加了“chatView.mView.setOnClickListener”。为了得到我不像你的位置,我得到了这个:“onClick(视图视图)”中的“recyclerView.getChildPosition(视图)”。再次感谢,对于延迟验证您的答案感到抱歉。
      • 添加“Firebase RecyclerView Adapter”类具有返回相关对象的方法“get Item (position)”。在上面的示例中放入 onClick: String myString = getItem (itemPosition);
      • 像往常一样,你非常有用。你不会相信我是多么喜欢你的回答。
      • 弗兰克,非常感谢。没什么大不了的,但 touchListener 几乎是即时的——这意味着当我点击视图时,就会采取行动。考虑到这一点,我失去了一些材料设计 - 例如,视图上的涟漪效应不再相关,因为触摸立即转换到下一个活动。有什么想法吗?
      • int 位置不应该是最终的。它向我显示警告
      猜你喜欢
      • 2021-01-05
      • 1970-01-01
      • 1970-01-01
      • 2016-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多