如何实现 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的主要内容,如果未能解决你的问题,请参考以下文章