Waqas Ahmed Ansari
Waqas Ahmed Ansari

Reputation: 1699

Change Background of RecyclerView Item at specific position

I have a RecyclerView and clicking its item takes to a new Activity. There is a ViewPager with multiple items. On pressing back, I am saving the current item position. What I want to do is when a user presses back while standing on any item in a ViewPager, that item should be highlighted in RecyclerView.

PROBLEM

When item's position is visible, there's no problem. I change background by using following

view = layoutManager.findViewByPosition(Utils.ayat);
if(view != null) {
    LinearLayout parent = (LinearLayout) view.findViewById(R.id.parent);
    parent.setBackgroundColor(Color.GRAY);
}

But if item is not visible, nothing happened and I am not able to change background.

WHAT I'VE DONE SO FAR

  1. Tried to scroll to a position and then change background. RecyclerView is scrolling correctly but findViewByPosition returns null.
  2. I believe from my observations (may be it's wrong) that on programmatically scrolling RecyclerView, the position to which it's been scrolled will be it's last visible item. I tried to do that but with no luck.
  3. As suggested by many, put Thread.sleep(100) and then tried to get position. This didn't work too.

NOTE: I can't do this onBindViewHolder because items to be highlighted are not pre-defined.

Upvotes: 1

Views: 4613

Answers (3)

Palanivelraghul
Palanivelraghul

Reputation: 1971

Try to use RecyclerView.AdapterDataObserver class by calling method of notifyItemChanged(position);

Whenever you are calling notifyItemChanged() method with certain position, it will call AdapterDataObserver class. So, First you need to paste my code what i given below inside to your adapter class. check my example, you will get some idea to achieve your requirement.

RecyclerView.AdapterDataObserver adapterDataObserver = new RecyclerView.AdapterDataObserver() {
    @Override
    public void onItemRangeChanged(int positionStart, int itemCount) {
        super.onItemRangeChanged(positionStart, itemCount);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                LinearLayoutManager manager = (LinearLayoutManager) recyclerView.getLayoutManager();
                manager.scrollToPositionWithOffset(positionStart, 0);
                RecyclerView.ViewHolder rebindViewHolder = recyclerView.findViewHolderForLayoutPosition(positionStart);
                if (rebindViewHolder != null) {
                    onBindViewHolder((ViewHolder) rebindViewHolder, positionStart);
                }
            }
        }, 1000);
    }
};

afterdoing this, in onBindViewHolder method change the background using position. I think this will helps you.

Upvotes: 0

S Haque
S Haque

Reputation: 7271

Have you tried notifyItemChanged(int position)? You can send the highlighted item position to the adapter through a method and call notifyItemChanged(int position). For example,

int highlightPosition = -1;

    public updateHighlightPosition(int position){
      highlightPosition = position;
      notifyItemChanged(position)
    }

    @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
      if(position == highlightPosition ){
         // You can change the background here
      }else{
        // Set default background
      }
  }

Upvotes: 0

etan
etan

Reputation: 593

Instead of changing the background color imperatively when returning to the list, you should store a list of highlighted item (indices) and in onBindViewHolder(...) check if the item is highlighted or not, and update its background accordingly (remember to also clear the background when item not highlighted).

This is generally how you should always do with RecyclerView.

Upvotes: 1

Related Questions