RecyclerView - get Position inside Activity rather than RecyclerViewAdapter

爷,独闯天下 提交于 2019-12-03 17:24:47

You can achieve this by creating an interface inside your adapter for an itemclicklistener and then you can set onItemClickListener from your MainActivity.

Somewhere inside your RecyclerViewAdapter you would need the following:

private onRecyclerViewItemClickListener mItemClickListener;

 public void setOnItemClickListener(onRecyclerViewItemClickListener mItemClickListener) {
        this.mItemClickListener = mItemClickListener;
    }

    public interface onRecyclerViewItemClickListener {
        void onItemClickListener(View view, int position);
    }

Then inside your ViewHolder (which I've added as an inner class inside my adapter), you would apply the listener to the components you'd like the user to click, like so:

class RecyclerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public ImageView imageview;

        RecyclerViewHolder(View view) {
            super(view);
            this.imageview = (ImageView) view
                    .findViewById(R.id.image);
            imageview.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            if (mItemClickListener != null) {
                mItemClickListener.onItemClickListener(v, getAdapterPosition());
            }
        }
    }

This example shows an onClickListener being applied to the image inside a ViewHolder.

recyclerView.setAdapter(adapter);// set adapter on recyclerview
            adapter.notifyDataSetChanged();// Notify the adapter
            adapter.setOnItemClickListener(new RecyclerViewAdapter.onRecyclerViewItemClickListener() {
                @Override
                public void onItemClickListener(View view, int position) { 
//perform click logic here (position is passed)
                    }
                });

To implement this code, you would setOnItemClickListener to your adapter inside MainActivity as shown above.

EDIT

Because the View is getting passed into the OnItemClickListener, you can perform a switch statement inside the listener to ensure that the right logic is being performed to the right component. All you would need to do is take the logic from the MyMethod function and copy and paste it to the component you wish it to be applied to.

Example:

recyclerView.setAdapter(adapter);// set adapter on recyclerview
                adapter.notifyDataSetChanged();// Notify the adapter
                adapter.setOnItemClickListener(new RecyclerViewAdapter.onRecyclerViewItemClickListener() {
                    @Override
                    public void onItemClickListener(View view, int position) { 
        Switch (view.getId()) {
            case R.id.letter:
               //logic for TextView with ID Letter here
            break;
            case R.id.firstname:
               //logic for TextView with ID firstname here
            break;
            ....
            //the same can be applied to other components in Row_Layout.xml
        }
                        }
                    });

You would also need to change something inside the ViewHolder. instead of applying the OnClickListener to an ImageView, you would need to apply to the whole row like so:

 RecyclerViewHolder(View view) {
                super(view);
                this.imageview = (ImageView) view
                        .findViewById(R.id.image);
                view.setOnClickListener(this);
            }

EDIT 2

Explanation:

So, with every RecyclerView. You need three components, The RecyclerView, RecyclerViewAdapter and the RecyclerViewHolder. These are what define the actual components the user sees (RecyclerView) and the Items within that View. The Adapter is where everything is pieced together and the Logic is implemented. The ins and outs of these components are nicely explained by Bill Phillips with the article RecyclerView Part 1: Fundamentals For ListView Experts over at Big Nerd Ranch.

But to further explain the logic behind the click events, it's basically utilizing an interface to pass information from the RecyclerViewAdapter to the RecyclerViewHolder to your MainActivity. So if you follow the life-cycle of the RecyclerView adapter, it'll make sense.

The adapter is initialized inside your MainActivity, the adapter's constructor would then be called with the information being passed. The components would then be passed into the adapter via the OnCreateViewHolder method. This itself tells the adapter, that's how you would like the list to look like. The components in that layout, would then need to be individually initialized, that's where the ViewHolder comes into play. As you can see like any other components you would initialize in your Activities, you do the same in the ViewHolder but because the RecyclerViewAdapter inflates the ViewHolder you can happily use them within your adapter as shown by Zeeshan Shabbir. But, for this example you would like multiple components to have various logic applied to each individual one in your MainActivity class.

That's where we create the click listener as a global variable (so it can be accessed by both the ViewHolder and the Adapter) the adapter's job in this case is to ensure the listener exists by creating an Interface you can initialize the listener through.

 public interface onRecyclerViewItemClickListener {
    void onItemClickListener(View view, int position);
 }

After you've defined the information you would like the interface to hold (E.G. the component and it's position), you can then create a function in which the adapter will call to apply the logic from your Activity (same way you would called View.OnClickListener) but by creating a setOnItemClickListener, you can customize it.

public void setOnItemClickListener(onRecyclerViewItemClickListener mItemClickListener) {
        this.mItemClickListener = mItemClickListener;
    }

This function then needs onRecyclerViewItemClickListener variable passed to it, as seen in your MainActivity. new RecyclerViewAdapter.onRecyclerViewItemClickListener() in this case it's the interface you created before with the method inside that would need to be implemented hence the

@Override
                public void onItemClickListener(View view, int position) {
                }

is called.

All the ViewHolder does in this scenario is pass the information (The components it's self and the position) into the onItemClickListener with the components attached (inside the onClick function) to finalize the actual click functionality.

if you would like me to update the explanation in anyway, let me know.

I think you are stuck with handling multiple clicks on ReceylerView if that is the case then let me share you the a code snippet from my project. That's how i handle the click in RecyclerView

public class ExploreItemAdapter extends RecyclerView.Adapter<ExploreItemAdapter.ViewHolder> {
private WSResponseDTO<Data> wsResponseDTO;

public ExploreItemAdapter(WSResponseDTO<Data> wsResponseDTO) {
    this.wsResponseDTO = wsResponseDTO;
}

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

@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
    holder.tvCompanyName.setText(wsResponseDTO.getData().getPosts().get(position).getStoreInfo().getStoreName());
    holder.tvBranchName.setText("(" + wsResponseDTO.getData().getPosts().get(position).getStoreInfo().getBranchName() + ")");
    holder.tvLikes.setText(wsResponseDTO.getData().getPosts().get(position).getPost().getFavoriteCount() + "");
    holder.tvShares.setText(wsResponseDTO.getData().getPosts().get(position).getPost().getShareCount() + "");
    holder.validity.setText(wsResponseDTO.getData().getPosts().get(position).getPost().getValidFrom() + "-" +
            wsResponseDTO.getData().getPosts().get(position).getPost().getValidTo());
    holder.sTime.setText(wsResponseDTO.getData().getPosts().get(position).getPost().getTime());
    holder.tvTitle.setText(wsResponseDTO.getData().getPosts().get(position).getPost().getHeading());
    holder.cardView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Toast.makeText(view.getContext(), "card is touched", Toast.LENGTH_SHORT).show();
            view.getContext().startActivity(new Intent(view.getContext(), ConsumerDetailOfferActivity.class).putExtra("post", wsResponseDTO.getData().getPosts().get(position)));
        }
    });
}

@Override
public int getItemCount() {
    return wsResponseDTO.getData().getPosts().size();
}

public class ViewHolder extends RecyclerView.ViewHolder {
    @BindView(R.id.card_explore)
    CardView cardView;
    @BindView(R.id.tv_company_name)
    TextView tvCompanyName;
    @BindView(R.id.tv_branch_name)
    TextView tvBranchName;
    @BindView(R.id.tv_title)
    TextView tvTitle;
    @BindView(R.id.tv_like_count)
    TextView tvLikes;
    @BindView(R.id.tv_share_count)
    TextView tvShares;
    @BindView(R.id.tv_validity)
    TextView validity;
    @BindView(R.id.tv_sTime)
    TextView sTime;


    public ViewHolder(View itemView) {
        super(itemView);
        ButterKnife.bind(this, itemView);
    }
}
}

you can set click listener to any item in bindViewHolder() like i did for cardView I hope this will help some.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!