37

I have a RecyclerView with a bunch of custom views which may change height after a while, because they contain ImageViews which load their image asynchronously. The RecyclerView does not pick up on this layout change, although I call forceLayout on the ImageView, and the RecyclerView is initialized with setHasFixedSize(false). All container-parents of the ImageView have set android:layout_height="wrap_content".

How can I make the RecyclerView update its layout? With good'ol ListView this was not a problem.

manfcas
  • 1,933
  • 7
  • 28
  • 47
Nilzor
  • 18,082
  • 22
  • 100
  • 167
  • How do you load the image data? Is the asynchronous loading from a `Loader`? From an `AsyncTask`? Is the data maintained in a `Cursor`? I'm asking to understand how you're maintaining data state. – ugo Sep 30 '14 at 15:40
  • I'm something similar to AsyncTask which has a callback (https://github.com/koush/ion). In the callback I've tried calling forceLayout – Nilzor Nov 04 '14 at 13:50
  • Bring your code here. How you set your adapter to the RecyclerView and where and on which thread you notifyDataSetChanged(). – Eftekhari Dec 07 '15 at 15:36
  • I have the same issue with 23.1.0 support lib version. I just set a new layout manager on the recycler view. – Thomas R. May 04 '16 at 12:04

5 Answers5

23

You can use the notifyDataSetChanged in the Adapter for the RecyclerView if all your images change at the same time or notifyItemChanged(int position) if only one of the items has changed. This will tell the RecyclerView to rebind the particular View.

manfcas
  • 1,933
  • 7
  • 28
  • 47
Barad
  • 239
  • 1
  • 1
  • 3
  • Watch out for this issue, as currently calling notifyDataSetChanged might throw an exception. https://code.google.com/p/android/issues/detail?id=77846 – gswierczynski Nov 04 '14 at 23:39
  • This will update the entire recyclerview. If it uses up the entire screen on a tablet with images, that will result in a significant performance issue that will be noticeable to users. You should avoid updating the entire recyclerview when only a small section of the layout changes. – Johann Jun 13 '15 at 06:57
11

Google has finally fixed this in support library v23.2. Issue is fixed by updating this line in build.gradle after updating your support repository with the SDK Manager:

compile 'com.android.support:recyclerview-v7:23.2.0'
Nilzor
  • 18,082
  • 22
  • 100
  • 167
  • hey @Nilzor can please help me with this https://stackoverflow.com/questions/49952965/recyclerview-horizontal-scrolling-to-left –  May 18 '18 at 11:29
5

Call the notifyDataSetChanged() or notifyItemChanged(int position) methods of the RecyclerView.Adapter from the MAIN THREAD. Calling it from an AsyncTask may result in the main thread not updating the ImageViews. Its most convenient to have a callback method in the activity/fragment work as a listener, and have it called by the AsyncTask in onPostExecute()

fawaad
  • 341
  • 6
  • 12
Edwin Muigai
  • 51
  • 1
  • 4
2
int wantedPosition = 25; // Whatever position you're looking for
int firstPosition = linearLayoutManager.findFirstVisibleItemPosition(); // This is the same as child #0
int wantedChild = wantedPosition - firstPosition;

if (wantedChild < 0 || wantedChild >= linearLayoutManager.getChildCount()) {
    Log.w(TAG, "Unable to get view for desired position, because it's not being displayed on screen.");
    return;
}

View wantedView = linearLayoutManager.getChildAt(wantedChild);
mlayoutOver =(LinearLayout)wantedView.findViewById(R.id.layout_over);
mlayoutPopup = (LinearLayout)wantedView.findViewById(R.id.layout_popup);

mlayoutOver.setVisibility(View.INVISIBLE);
mlayoutPopup.setVisibility(View.VISIBLE);

This code is worked for me.

Ken Y-N
  • 14,644
  • 21
  • 71
  • 114
Libin Thomas
  • 1,132
  • 13
  • 17
0

I had the same problem, I just set a fix width and height for the ImageView. Try that and see where you get. You can also use a lib for this, I use Square Picasso and I got it working with RecyclerView.

PaulNunezM
  • 3,217
  • 3
  • 14
  • 10
  • 1
    Fixed with and height is not an option. The design requires height to be determined by the image height. – Nilzor Nov 04 '14 at 13:50