Ich verwende eine RecyclerView mit einem einzeiligen Layout mit einer ImageView und einer TextView.
Ich möchte einen OnClickListener für die View implementieren und nicht für separate ViewHolder-Objekte. Wie kann ich die Position der Ansicht im Adapter ermitteln?
Im Moment lösche ich Kommentare zu click, aber ich kann die angeklickte Ansicht nicht auswählen. Ich habe in der entsprechenden Zeile ein TODO hinzugefügt.
public class CommentAdapter extends RecyclerView.Adapter<CommentAdapter.ViewHolder> {
/** List of Comment objects */
private List<Comment> mCommentList;
/** Database with Comment objects */
private CommentsDataSource mDataSource;
/**
* Construcutor for CommentAdapter
*
* @param commentList List of Comment objects
* @param dataSource Database with Comment objects
*/
public CommentAdapter(List<Comment> commentList, CommentsDataSource dataSource) {
this.mCommentList = commentList;
this.mDataSource = dataSource;
}
/**
* Add Comment objects to RecyclerView
*
* @param position The position where the Comment object is added
* @param comment Comment Object
*/
public void add(int position, Comment comment) {
mCommentList.add(position, comment);
notifyItemInserted(position);
}
/**
* Remove Comment objects from RecyclerView
*
* @param comment Comment Object
*/
public void remove(Comment comment) {
int position = mCommentList.indexOf(comment);
// Avoid double tap remove
if (position != -1) {
mCommentList.remove(position);
mDataSource.deleteComment(comment);
notifyItemRemoved(position);
}
}
@Override
public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
final View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.single_line_row, parent, false);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO get position
remove(mCommentList.get(getItemCount() - 1));
}
});
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
final Comment comment = mCommentList.get(position);
holder.comment.setText(comment.getComment());
}
@Override
public int getItemCount() {
return mCommentList.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
/** ImageView icon */
public ImageView icon;
/** TextView comment */
public TextView comment;
/**
* Constructor for ViewHolder
*
* @param itemView Layout for each row of RecyclerView
*/
public ViewHolder(final View itemView) {
super(itemView);
icon = (ImageView) itemView.findViewById(R.id.icon);
comment = (TextView) itemView.findViewById(R.id.comment);
}
}
}
Sie können den position
-Parameter von onBindViewHolder
nicht in einem Rückruf verwenden . Wenn ein neuer Artikel oben hinzugefügt wird, bindet RecyclerView Ihren Artikel nicht , sodass die Position veraltet ist . Stattdessen bietet RecyclerView eine getAdapterPosition
-Methode für den ViewHolder.
@Override
public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
final View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.single_line_row, parent, false);
final ViewHolder holder = new ViewHolder(view);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final int position = holder.getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
remove(mCommentList.get(position));
}
}
});
return holder;
}
Ich habe das Kontrollkästchen position != RecyclerView.NO_POSITION
Hinzugefügt, da RecyclerView beim Entfernen des Elements die Ansicht ausblenden wird, sodass der Benutzer möglicherweise weiterhin darauf klickt, die Adapterposition jedoch NO_POSITION
Zurückgibt.
sie können eine Methode zum Aktualisieren der Position in Ihrer Klasse erstellen.
in meinem Fall muss ich watcher
anhängen und die Position erhalten, um arraylist
zu aktualisieren. Hier ist das Beispiel:
class DodolWatcher bla bla {
private var position: Int = 0
fun updatePosition(pos:Int)
{
position = pos
}
override fun onTextChanged(charSequence: CharSequence, i: Int, i2: Int, i3: Int) {
Log.d("test", position.toString())
}
}
und in Ihrer onCreateViewHolder
können Sie Watcher an edittext
anhängen
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RVPaymentMethodAdapter.ViewHolder {
....
bla bla
....
theWatcher = DodolWatcher() <-- this is the trick
amount.addTextChangedListener(theWatcher)
}
und Sie können die Position in Ihrer bindViewHolder
folgendermaßen aktualisieren:
override fun onBindViewHolder(viewHolder: RVPaymentMethodAdapter.ViewHolder, position: Int) {
theWatcher.updatePosition(viewHolder.adapterPosition) <-- this is the trick
}