[java] RecyclerView - Get view at particular position

I have an activity with a RecyclerView and an ImageView. I am using the RecyclerView to show a list of images horizontally. When I click on an image in the RecyclerView the ImageView in the activity should show a bigger picture of the image. So far everything works fine.

Now there are two more ImageButtons in the activity: imageButton_left and imageButton_right. When I click on imageButton_left, the image in the ImageView should turn left and also, the thumbnail in the RecyclerView should reflect this change. Similar is the case with imageButton_right.

I am able to rotate the ImageView. But, how can I rotate the thumbnail in the RecyclerView? How can I get the ViewHolder's ImageView?

Code:

Activity XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp" />


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/original_image"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:scaleType="fitXY"
            android:src="@drawable/image_not_available_2" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:gravity="center_horizontal"
            android:orientation="horizontal">


            <ImageButton
                android:id="@+id/imageButton_left"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginRight="20dp"
                android:background="@drawable/rotate_left_icon" />

            <ImageButton
                android:id="@+id/imageButton_right"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/rotate_right_icon" />

        </LinearLayout>
    </LinearLayout>
</LinearLayout>

My Activity Code:

public class SecondActivity extends AppCompatActivity implements IRecyclerViewClickListener {


    RecyclerView mRecyclerView;
    LinearLayoutManager mLayoutManager;
    RecyclerViewAdapter mRecyclerViewAdapter;
    List<String> urls = new ArrayList<String>();
    ImageView mOriginalImageView;
    ImageButton mLeftRotate, mRightRotate;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        urls.clear();

        mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        mLayoutManager = new LinearLayoutManager(this, android.support.v7.widget.LinearLayoutManager.HORIZONTAL, false);
        mLayoutManager.setOrientation(android.support.v7.widget.LinearLayoutManager.HORIZONTAL);
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerViewAdapter = new RecyclerViewAdapter(this, urls);
        mRecyclerView.setAdapter(mRecyclerViewAdapter);

        mOriginalImageView = (ImageView) findViewById(R.id.original_image);
        mLeftRotate = (ImageButton) findViewById(R.id.imageButton_left);
        mLeftRotate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mOriginalImageView.setRotation(mOriginalImageView.getRotation() - 90);
            }
        });


        mRightRotate = (ImageButton) findViewById(R.id.imageButton_right);
        mRightRotate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mOriginalImageView.setRotation(mOriginalImageView.getRotation() + 90);
            }
        });

        Intent intent = getIntent();
        if (intent != null) {

            String portfolio = intent.getStringExtra("portfolio");

            try {

                JSONArray jsonArray = new JSONArray(portfolio);

                for (int i = 0; i < jsonArray.length(); i++) {

                    JSONObject jsonObject = jsonArray.getJSONObject(i);

                    String url = jsonObject.getString("url");
                    urls.add(url);
                }

                Log.d(Const.DEBUG, "URLs: " + urls.toString());

                mRecyclerViewAdapter.notifyDataSetChanged();

            } catch (Exception e) {
                e.printStackTrace();
            }

        }

    }


    @Override
    public void onItemClick(int position) {
        Picasso.with(this).load(urls.get(position)).into(mOriginalImageView);
    }
}

My Custom Adapter for RecyclerView:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {

    Context context;
    List<String> mUrls = new ArrayList<String>();

    IRecyclerViewClickListener mIRecyclerViewClickListener;

    public int position;

    public int getPosition() {
        return position;
    }

    public void setPosition(int position) {
        this.position = position;
    }



    public RecyclerViewAdapter(Context context, List<String> urls) {
        this.context = context;
        this.mUrls.clear();
        this.mUrls = urls;

        Log.d(Const.DEBUG, "Urls Size: " + urls.size());
        Log.d(Const.DEBUG, urls.toString());

        if (context instanceof IRecyclerViewClickListener)
            mIRecyclerViewClickListener = (IRecyclerViewClickListener) context;
        else
            Log.d(Const.DEBUG, "Implement IRecyclerViewClickListener in Activity");
    }

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

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Picasso.with(context).load(mUrls.get(position)).into(holder.mImageView);
    }

    @Override
    public int getItemCount() {
        return mUrls.size();
    }


    public void rotateThumbnail() {


    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        public ImageView mImageView;
        public View v;

        public ViewHolder(View v) {
            super(v);
            v.setTag(getAdapterPosition());
            v.setOnClickListener(this);
            this.mImageView = (ImageView) v.findViewById(R.id.image);
        }

        @Override
        public void onClick(View v) {
            this.v = v;
            mIRecyclerViewClickListener.onItemClick(getAdapterPosition());
        }
    }


}

This question is related to java android android-recyclerview widget position

The answer is


You can simply use "findViewHolderForAdapterPosition" method of recycler view and you will get a viewHolder object from that then typecast that viewholder into your adapter viewholder so you can directly access your viewholder's views

following is the sample code for kotlin

 val viewHolder = recyclerView.findViewHolderForAdapterPosition(position)
 val textview=(viewHolder as YourViewHolder).yourTextView

If you guys are having null with every attempt to get a view with any int position, try to add a new constructor parameter to your adapter like this for example:

class RecyclerViewTableroAdapter(
private val fichas: Array<MFicha?>,
private val activity: View.OnClickListener,
private val indicesGanadores:MutableList<Int>
) : RecyclerView.Adapter<RecyclerViewTableroAdapter.ViewHolder>() {
//CODE 
}

I added indicesGanadores to color my cardview background if my game is won.

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
//CODE
if(indicesGanadores.contains(position)){
        holder.cardViewFicha.setCardBackgroundColor((activity as MainActivity).resources.getColor(R.color.DarkGreen))
    }
//MORE CODE
}  

If I don't have to color my background yet I just send an empty mutable list like this:

binding.recyclerViewMain.adapter = RecyclerViewTableroAdapter(fichasTablero, this@MainActivity, mutableListOf<Int>())

Happy coding!...


You can as well do this, this will help when you want to modify a view after clicking a recyclerview position item

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

            View v =  rv_notifications.getChildViewHolder(view).itemView;
            TextView content = v.findViewById(R.id.tv_content);
            content.setText("Helloo");

        }

You can make ArrayList of ViewHolder :

 ArrayList<MyViewHolder> myViewHolders = new ArrayList<>();
 ArrayList<MyViewHolder> myViewHolders2 = new ArrayList<>();

and, all store ViewHolder(s) in the list like :

 @Override
    public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) {
        final String str = arrayList.get(position);

        myViewHolders.add(position,holder);
}

and add/remove other ViewHolder in the ArrayList as per your requirement.


Keep in mind that you have to wait until adapter will added to list, then you can try to getting view by position

final int i = 0;
recyclerView.setAdapter(adapter);
recyclerView.post(new Runnable() {
    @Override
    public void run() {
        View view = recyclerView.getLayoutManager().findViewByPosition(i);
    }
});

You can get a view for a particular position on a recyclerview using the following

int position = 2;
RecyclerView.ViewHolder viewHolder = recyclerview.findViewHolderForItemId(position);
View view = viewHolder.itemView;
ImageView imageView = (ImageView)view.findViewById(R.id.imageView);

You can use use both

recyclerViewInstance.findViewHolderForAdapterPosition(adapterPosition) and recyclerViewInstance.findViewHolderForLayoutPosition(layoutPosition). Be sure that RecyclerView view uses two type of positions

Adapter position : Position of an item in the adapter. This is the position from the Adapter's perspective. Layout position : Position of an item in the latest layout calculation. This is the position from the LayoutManager's perspective. You should use getAdapterPosition() for findViewHolderForAdapterPosition(adapterPosition) and getLayoutPosition() for findViewHolderForLayoutPosition(layoutPosition).

Take a member variable to hold previously selected item position in recyclerview adapter and other member variable to check whether user is clicking for first time or not.

Sample code and screen shots are attached for more information at the bottom.

public class MainActivity extends AppCompatActivity {     

private RecyclerView mRecyclerList = null;    
private RecyclerAdapter adapter = null;    

@Override    
protected void onCreate(Bundle savedInstanceState) {    
    super.onCreate(savedInstanceState);    
    setContentView(R.layout.activity_main);    

    mRecyclerList = (RecyclerView) findViewById(R.id.recyclerList);    
}    

@Override    
protected void onStart() {    
    RecyclerView.LayoutManager layoutManager = null;    
    String[] daysArray = new String[15];    
    String[] datesArray = new String[15];    

    super.onStart();    
    for (int i = 0; i < daysArray.length; i++){    
        daysArray[i] = "Sunday";    
        datesArray[i] = "12 Feb 2017";    
    }    

    adapter = new RecyclerAdapter(mRecyclerList, daysArray, datesArray);    
    layoutManager = new LinearLayoutManager(MainActivity.this);    
    mRecyclerList.setAdapter(adapter);    
    mRecyclerList.setLayoutManager(layoutManager);    
}    
}    


public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyCardViewHolder>{          

private final String TAG = "RecyclerAdapter";        
private Context mContext = null;        
private TextView mDaysTxt = null, mDateTxt = null;    
private LinearLayout mDateContainerLayout = null;    
private String[] daysArray = null, datesArray = null;    
private RecyclerView mRecyclerList = null;    
private int previousPosition = 0;    
private boolean flagFirstItemSelected = false;    

public RecyclerAdapter(RecyclerView mRecyclerList, String[] daysArray, String[] datesArray){    
    this.mRecyclerList = mRecyclerList;    
    this.daysArray = daysArray;    
    this.datesArray = datesArray;    
}    

@Override    
public MyCardViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {    
    LayoutInflater layoutInflater = null;    
    View view = null;    
    MyCardViewHolder cardViewHolder = null;    
    mContext = parent.getContext();    
    layoutInflater = LayoutInflater.from(mContext);    
    view = layoutInflater.inflate(R.layout.date_card_row, parent, false);    
    cardViewHolder = new MyCardViewHolder(view);    
    return cardViewHolder;    
}    

@Override    
public void onBindViewHolder(MyCardViewHolder holder, final int position) {    
    mDaysTxt = holder.mDaysTxt;    
    mDateTxt = holder.mDateTxt;    
    mDateContainerLayout = holder.mDateContainerLayout;    

    mDaysTxt.setText(daysArray[position]);    
    mDateTxt.setText(datesArray[position]);    

    if (!flagFirstItemSelected){    
        mDateContainerLayout.setBackgroundColor(Color.GREEN);    
        flagFirstItemSelected = true;    
    }else {    
        mDateContainerLayout.setBackground(null);    
    }    
}    

@Override    
public int getItemCount() {    
    return daysArray.length;    
}    

class MyCardViewHolder extends RecyclerView.ViewHolder{    
    TextView mDaysTxt = null, mDateTxt = null;    
    LinearLayout mDateContainerLayout = null;    
    LinearLayout linearLayout = null;    
    View view = null;    
    MyCardViewHolder myCardViewHolder = null;    

    public MyCardViewHolder(View itemView) {    
        super(itemView);    
        mDaysTxt = (TextView) itemView.findViewById(R.id.daysTxt);    
        mDateTxt = (TextView) itemView.findViewById(R.id.dateTxt);    
        mDateContainerLayout = (LinearLayout) itemView.findViewById(R.id.dateContainerLayout);    

        mDateContainerLayout.setOnClickListener(new View.OnClickListener() {    
            @Override    
            public void onClick(View v) {    
                LinearLayout linearLayout = null;    
                View view = null;    

                if (getAdapterPosition() == previousPosition){    
                    view = mRecyclerList.findViewHolderForAdapterPosition(previousPosition).itemView;    
                    linearLayout = (LinearLayout) view.findViewById(R.id.dateContainerLayout);    
                    linearLayout.setBackgroundColor(Color.GREEN);    
                    previousPosition = getAdapterPosition();    

                }else {    
                    view = mRecyclerList.findViewHolderForAdapterPosition(previousPosition).itemView;    
                    linearLayout = (LinearLayout) view.findViewById(R.id.dateContainerLayout);    
                    linearLayout.setBackground(null);    

                    view = mRecyclerList.findViewHolderForAdapterPosition(getAdapterPosition()).itemView;    
                    linearLayout = (LinearLayout) view.findViewById(R.id.dateContainerLayout);    
                    linearLayout.setBackgroundColor(Color.GREEN);    
                    previousPosition = getAdapterPosition();    
                }    
            }    
        });    
    }    
}       

} first element selected second element selected and previously selected item becomes unselected fifth element selected and previously selected item becomes unselected


To get specific view from recycler view list OR show error at edittext of recycler view.

private void popupErrorMessageAtPosition(int itemPosition) {

    RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(itemPosition);
    View view = viewHolder.itemView;
    EditText etDesc = (EditText) view.findViewById(R.id.et_description);
    etDesc.setError("Error message here !");
}

You can use below

mRecyclerview.getChildAt(pos);

To get a View from a specific position of recyclerView you need to call findViewHolderForAdapterPosition(position) on recyclerView object that will return RecyclerView.ViewHolder

from the returned RecyclerView.ViewHolder object with itemView you can access all Views at that particular position

RecyclerView.ViewHolder rv_view = recyclerView.findViewHolderForAdapterPosition(position);

ImageView iv_wish = rv_view.itemView.findViewById(R.id.iv_item);

This is what you're looking for.

I had this problem too. And like you, the answer is very hard to find. But there IS an easy way to get the ViewHolder from a specific position (something you'll probably do a lot in the Adapter).

myRecyclerView.findViewHolderForAdapterPosition(pos);

NOTE: If the View has been recycled, this will return null. Thanks to Michael for quickly catching my important omission.


If you want the View, make sure to access the itemView property of the ViewHolder like so: myRecyclerView.findViewHolderForAdapterPosition(pos).itemView;


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to android

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How to implement a simple scenario the OO way My eclipse won't open, i download the bundle pack it keeps saying error log getting " (1) no such column: _id10 " error java doesn't run if structure inside of onclick listener Cannot retrieve string(s) from preferences (settings) strange error in my Animation Drawable how to put image in a bundle and pass it to another activity FragmentActivity to Fragment A failure occurred while executing com.android.build.gradle.internal.tasks

Examples related to android-recyclerview

Failed to resolve: com.android.support:cardview-v7:26.0.0 android CardView background color always white Changing background color of selected item in recyclerview Simple Android grid example using RecyclerView with GridLayoutManager (like the old GridView) Simple Android RecyclerView example Android Horizontal RecyclerView scroll Direction Margin between items in recycler view Android How to add a recyclerView inside another recyclerView RecyclerView - Get view at particular position Recyclerview inside ScrollView not scrolling smoothly

Examples related to widget

How do I center text vertically and horizontally in Flutter? RecyclerView - Get view at particular position How to make the Facebook Like Box responsive? How to make a GridLayout fit screen size How to pass parameters to a Script tag? Is there an easy way to strike through text in an app widget? Android widget: How to change the text of a button Failed binder transaction when putting an bitmap dynamically in a widget How to clear the Entry widget after a button is pressed in Tkinter? Textarea that can do syntax highlighting on the fly?

Examples related to position

How does the "position: sticky;" property work? React Native absolute positioning horizontal centre RecyclerView - Get view at particular position RecyclerView - How to smooth scroll to top of item on a certain position? How to find index of STRING array in Java from a given value? Insert node at a certain position in a linked list C++ How to position the Button exactly in CSS Float a DIV on top of another DIV Iframe positioning css - position div to bottom of containing div