如何实现 SetOnItemClickListener FirebaseRecyclerViewAdapter

Posted

技术标签:

【中文标题】如何实现 SetOnItemClickListener FirebaseRecyclerViewAdapter【英文标题】:how to implement a 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);

【问题讨论】:

【参考方案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://***.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 位置不应该是最终的。它向我显示警告

以上是关于如何实现 SetOnItemClickListener FirebaseRecyclerViewAdapter的主要内容,如果未能解决你的问题,请参考以下文章

如何快速自己实现Map

API 面试四连杀:接口如何设计?安全如何保证?签名如何实现?防重如何实现?

delphi 中如何实现对象之间的数据共享

C#如何实现进程单例运行

Android如何实现弹幕效果

如何实现两个div之间的连线,我现在有这个需求,请问如何实现