在 onCreateViewHolder 中获取 View 的位置
Getting position of View in onCreateViewHolder
我正在使用具有单行布局的 RecyclerView 以及一个 ImageView 和一个 TextView。
我想为视图而不是单独的 ViewHolder 对象实现 OnClickListener。如何获取视图在适配器中的位置?
现在我正在删除点击评论,但我不能 select 点击视图。我在适当的行中添加了一个 TODO。
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);
}
}
}
您不能在回调中使用onBindViewHolder
的position
参数。
如果上面添加了新项目,RecyclerView 不会 重新绑定您的项目,因此位置 obsolete。
相反,RecyclerView 在 ViewHolder 上提供了一个 getAdapterPosition
方法。
@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;
}
我已经添加了 position != RecyclerView.NO_POSITION
检查,因为当项目被移除时,RecyclerView 将淡出视图,所以它可能仍然被用户点击但它的适配器位置将 return NO_POSITION
.
覆盖适配器中的 getItemViewType 方法:
@Override
public int getItemViewType(int position) {
//...
return position;
}
现在 viewType 是位置
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
int position=viewType; //position
//your code
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recursive, parent, false);
return new ViewHolder(view);
}
例如
public class BrandBtnAdapter extends RecyclerView.Adapter<BrandBtnAdapter.MyViewHolder>
{
//............
@Override
public int getItemViewType(int position)
{
//...
return position;
}
@Override
public BrandBtnAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
int position = viewType; //position
final View itemView = mInflater.inflate(mResource, parent, false);
return new BrandBtnAdapter.MyViewHolder(itemView);
}
}
您可以创建一个方法来更新 class 中的位置。
在我的例子中,我需要附加 watcher
并获取要更新的位置 arraylist
。这是示例:
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())
}
}
并且在您的 onCreateViewHolder
中,您可以将观察者附加到 edittext
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RVPaymentMethodAdapter.ViewHolder {
....
bla bla
....
theWatcher = DodolWatcher() <-- this is the trick
amount.addTextChangedListener(theWatcher)
}
您将能够像这样更新 bindViewHolder
中的位置:
override fun onBindViewHolder(viewHolder: RVPaymentMethodAdapter.ViewHolder, position: Int) {
theWatcher.updatePosition(viewHolder.adapterPosition) <-- this is the trick
}
我正在使用具有单行布局的 RecyclerView 以及一个 ImageView 和一个 TextView。
我想为视图而不是单独的 ViewHolder 对象实现 OnClickListener。如何获取视图在适配器中的位置?
现在我正在删除点击评论,但我不能 select 点击视图。我在适当的行中添加了一个 TODO。
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);
}
}
}
您不能在回调中使用onBindViewHolder
的position
参数。
如果上面添加了新项目,RecyclerView 不会 重新绑定您的项目,因此位置 obsolete。
相反,RecyclerView 在 ViewHolder 上提供了一个 getAdapterPosition
方法。
@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;
}
我已经添加了 position != RecyclerView.NO_POSITION
检查,因为当项目被移除时,RecyclerView 将淡出视图,所以它可能仍然被用户点击但它的适配器位置将 return NO_POSITION
.
覆盖适配器中的 getItemViewType 方法:
@Override
public int getItemViewType(int position) {
//...
return position;
}
现在 viewType 是位置
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
int position=viewType; //position
//your code
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recursive, parent, false);
return new ViewHolder(view);
}
例如
public class BrandBtnAdapter extends RecyclerView.Adapter<BrandBtnAdapter.MyViewHolder>
{
//............
@Override
public int getItemViewType(int position)
{
//...
return position;
}
@Override
public BrandBtnAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
int position = viewType; //position
final View itemView = mInflater.inflate(mResource, parent, false);
return new BrandBtnAdapter.MyViewHolder(itemView);
}
}
您可以创建一个方法来更新 class 中的位置。
在我的例子中,我需要附加 watcher
并获取要更新的位置 arraylist
。这是示例:
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())
}
}
并且在您的 onCreateViewHolder
中,您可以将观察者附加到 edittext
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RVPaymentMethodAdapter.ViewHolder {
....
bla bla
....
theWatcher = DodolWatcher() <-- this is the trick
amount.addTextChangedListener(theWatcher)
}
您将能够像这样更新 bindViewHolder
中的位置:
override fun onBindViewHolder(viewHolder: RVPaymentMethodAdapter.ViewHolder, position: Int) {
theWatcher.updatePosition(viewHolder.adapterPosition) <-- this is the trick
}