java 在 onCreateViewHolder 中获取 View 的位置

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29840394/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 16:00:01  来源:igfitidea点击:

Getting position of View in onCreateViewHolder

javaandroidandroid-viewandroid-recyclerviewandroid-viewholder

提问by Thomas Mohr

I am using a RecyclerView with a single row layout with an ImageView and a TextView.

我正在使用带有 ImageView 和 TextView 的单行布局的 RecyclerView。

I want to implement a OnClickListener for the View and not for seperate ViewHolder objects. How can i get the position of the view in the Adapter?

我想为 View 实现 OnClickListener 而不是为单独的 ViewHolder 对象。如何在适配器中获取视图的位置?

Right now i'm deleting comments on click, but i cannot select the clicked View. I added a TODO in the appropriate line.

现在我正在删除点击评论,但我无法选择点击的视图。我在适当的行中添加了一个 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);
        }
    }
}

回答by yigit

You cannotuse the positionparameter of onBindViewHolderin a callback. If a new item is added above, RecyclerView will notrebind your item so the position is obsolete. Instead, RecyclerView provides a getAdapterPositionmethod on the ViewHolder.

不能在回调中使用position参数onBindViewHolder。如果上面添加了新项目, RecyclerView将不会重新绑定您的项目,因此该位置已过时。相反,RecyclerViewgetAdapterPosition在 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;
}

I've added position != RecyclerView.NO_POSITIONcheck because when item is removed, RecyclerView will fade out the View so it may still be clicked by the user but its adapter position will return NO_POSITION.

我添加了position != RecyclerView.NO_POSITION检查,因为当删除项目时, RecyclerView 将淡出视图,因此用户可能仍会单击它,但其适配器位置将返回NO_POSITION

回答by Kakashi

you can create a method to update position in your class.

您可以创建一个方法来更新您班级中的位置。

in my case I need to attach watcherand get the position to update arraylist. here is the example:

就我而言,我需要附加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())
    }

}

and in your onCreateViewHolderyou can attach watcher to edittext

并且在你的onCreateViewHolder你可以附加观察者edittext

 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RVPaymentMethodAdapter.ViewHolder {
     ....
     bla bla
     ....
     theWatcher = DodolWatcher() <-- this is the trick
     amount.addTextChangedListener(theWatcher)
 }

and you will able to update position in your bindViewHolderlike this:

你将能够bindViewHolder像这样更新位置:

override fun onBindViewHolder(viewHolder: RVPaymentMethodAdapter.ViewHolder, position: Int) {
     theWatcher.updatePosition(viewHolder.adapterPosition)  <-- this is the trick
 }

回答by Hossein Hajizadeh

override getItemViewType method in your Adapter:

在您的适配器中覆盖 getItemViewType 方法:

@Override
public int getItemViewType(int position) {
    //...
    return position;
}

Now viewType is 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);
    }

for example

例如

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);
    }

}