01hanst
01hanst

Reputation: 597

getAdapterPosition in onCreateViewHolder is always "-1"

in many questions, people say "call OnClickListener in onCreateViewHolder. you don't need call OnClickListener each item in onBindViewHolder"

@Override
  public Viewholder onCreateViewHolder(ViewGroup parent, int viewType) {
     View v = LayoutInflater.from(parent.getContext()).inflate(itemLayout, parent, false);
     final ViewHolder holder = new ViewHolder(v);

     holder.itemView.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
             Log.d(TAG, "position = " + holder.getAdapterPosition());
         }
     });
     return new Viewholder(v);
  }

  @Override
  public void onBindViewHolder(final BoardListViewHolder holder, int position) {

  }

but in Logcat, always show "position = -1"

this is not correct.

why i should call onClickListener in onCreateViewHolder?

Upvotes: 5

Views: 1605

Answers (4)

Akash Sharma
Akash Sharma

Reputation: 286

First return holder instead of return new Viewholder(v) You can have OnClickListener in your ViewHolder and get position by getAdapterPosition()

class ViewHolder extends RecyclerView.ViewHolder{

    public ViewHolder(View itemView) {

        super(itemView);

        itemView.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Log.d(TAG, "position = " + getAdapterPosition());
                //do your stuff here


            }
        });

    }
}

Upvotes: 0

IntelliJ Amiya
IntelliJ Amiya

Reputation: 75798

getAdapterPosition in onCreateViewHolder is always “-1”

You should return holder instead of new Viewholder(v) .

Code Structure

@Override
  public Viewholder onCreateViewHolder(ViewGroup parent, int viewType) {
     View v = LayoutInflater.from(parent.getContext()).inflate(itemLayout, parent, false);
     final ViewHolder holder = new ViewHolder(v);

     holder.itemView.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
             Log.d(TAG, "position = " + holder.getAdapterPosition());
         }
     });
     return holder;
  }

  @Override
  public void onBindViewHolder(final BoardListViewHolder holder, int position) {

  }

Upvotes: 5

terencey
terencey

Reputation: 3332

Because you're returning a new ViewHolder instead of the one you set the click listener on.

Instead of return new Viewholder(v), you should return holder;

A clearer way of setting click listeners can be

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(
                R.layout.layout_item, parent, false));
}

public class ViewHolder extends RecyclerView.ViewHolder {

    private ImageView image;

    public ViewHolder(View itemView) {
        super(itemView);

        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // do what you need to do. getAdapterPosition() is useful here
            }
        });
    }
}

Upvotes: 2

Patryk Goworowski
Patryk Goworowski

Reputation: 281

onCreateViewHolder is used to inflate the layout resource only and you shouldn't put any methods related to your holder items here.

Instead, you have to use onBindViewHolder to get the value of holder.getAdapterPosition or set onClickListeners etc. there.

Upvotes: 2

Related Questions