title: Getting a RecyclerView to reload items
body: <p>I am currently working on an app, that finds all MP3s on a users phone and then puts them into a list. This works very fine and is very quick, even with many songs. Now I populate a new list with an object for each item of the list to then display it inside my recyclerview. The problem is, that I have 700+ songs on my phone and this blocks the UI thread quite some time. </p>
  
  <p>Now, I want to use the recyclerview to not load all items from the list into the objects all at once but rather only when they are about to be displayed - but I have NO clue over how to do this. Right now, all objects are build and then displayed in a very long scrollview from the recyclerview after the UI thread has been blocked for a good 30 seconds. Can please anyone help me? Here is my code:</p>
  
  <pre><code>namespace Media_Player
  {
      [Activity(Label = "Media_Player", MainLauncher = true)]
      public class MainActivity : Activity
      {
          static public MediaPlayer mediaPlayer;
          List&lt;MP3object&gt; mp3;
          MediaMetadataRetriever reader;
          public static Button btn_StartOrPause, btn_Stop;
          public static TextView txt_CurrentSong;
          public static bool stopIsActive = false, firstStart = true;
          public static Android.Net.Uri CurrentActiveSongUri;
  
          RecyclerView mRecyclerView;
          RecyclerView.LayoutManager mLayoutManager;
          PhotoAlbumAdapter mAdapter;
  
  
          protected override void OnCreate(Bundle savedInstanceState)
          {
              base.OnCreate(savedInstanceState);
              SetContentView(Resource.Layout.test);
  
              reader = new MediaMetadataRetriever();
              PopulateMP3List(ReturnPlayableMp3(true));
              mediaPlayer = new MediaPlayer();
  
              InitRecView();
          }
  
          private void InitRecView()
          {
  
              // Instantiate the adapter and pass in its data source:
              mAdapter = new PhotoAlbumAdapter(mp3);
  
              // Get our RecyclerView layout:
              mRecyclerView = FindViewById&lt;RecyclerView&gt;(Resource.Id.recyclerView);
  
              // Plug the adapter into the RecyclerView:
              mRecyclerView.SetAdapter(mAdapter);
  
              mLayoutManager = new LinearLayoutManager(this);
              mRecyclerView.SetLayoutManager(mLayoutManager);
          }
  
  
          private void PopulateMP3List(List&lt;string&gt; content)
          {
             mp3 = new List&lt;MP3object&gt;();        
             foreach (string obj in content)
             {
                 WriteMetaDataToFileList(obj);        
             }
          }
  
          void WriteMetaDataToFileList(string obj)
          {
              reader.SetDataSource(obj);
  
              //Write Mp3 as object to global list
              MP3object ob = new MP3object();
              {
                  if(reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyTitle) != "" &amp;&amp; reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyTitle) != null)
                  {
                      ob.SongName = reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyTitle);
                  }
                  else
                  {
                      ob.SongName = Resources.GetString(Resource.String.Unknown);
                  }
  
                  if (reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyArtist) != "" &amp;&amp; reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyArtist) != null)
                  {
                      ob.ArtistName = reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyArtist);
                  }
                  else
                  {
                      ob.ArtistName = Resources.GetString(Resource.String.Unknown);
                  }
  
                  if (reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyAlbum) != "" &amp;&amp; reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyAlbum) != null)
                  {
                      ob.AlbumName = reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyAlbum);
                  }
                  else
                  {
                      ob.AlbumName = Resources.GetString(Resource.String.Unknown);
                  }
  
                  if (reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyYear) != "" &amp;&amp; reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyYear) != null)
                  {
                      ob.Year = reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyYear);
                  }
                  else
                  {
                      ob.Year = Resources.GetString(Resource.String.Unknown);
                  }
  
                  if (reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyYear) != "" &amp;&amp; reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyYear) != null)
                  {
                      ob.Year = reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyYear);
                  }
                  else
                  {
                      ob.Year = Resources.GetString(Resource.String.Unknown);
                  }
  
                  ob.Mp3Uri = obj; // can never be unknown!
  
                  ob.DurationInSec = int.Parse(reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyDuration)) / 1000; // can never be unknown, div by 1000 to get sec not millis
              }
              mp3.Add(ob);
  
          }
  
          public List&lt;string&gt; ReturnPlayableMp3(bool sdCard)
          {
              List&lt;string&gt; res = new List&lt;string&gt;();
              string phyle;
              string path1 = null;
  
              if(sdCard) // get mp3 from SD card
              {
                  string baseFolderPath = "";
  
                  try
                  {
                      bool getSDPath = true;
  
                      Context context = Application.Context;
                      Java.IO.File[] dirs = context.GetExternalFilesDirs(null);
  
                      foreach (Java.IO.File folder in dirs)
                      {
                          bool IsRemovable = Android.OS.Environment.InvokeIsExternalStorageRemovable(folder);
                          bool IsEmulated = Android.OS.Environment.InvokeIsExternalStorageEmulated(folder);
  
                          if (getSDPath ? IsRemovable &amp;&amp; !IsEmulated : !IsRemovable &amp;&amp; IsEmulated)
                              baseFolderPath = folder.Path;
                      }
                  }
                  catch (Exception ex)
                  {
                      Console.WriteLine("GetBaseFolderPath caused the following exception: {0}", ex);
                  }
  
                  string xy = baseFolderPath.Remove(18); // This is result after this, but this hard coded solution could be a problem on different phones.: "/storage/05B6-2226/Android/data/Media_Player.Media_Player/files"
  
                  path1 = xy;
                  // path to SD card and MUSIC "/storage/05B6-2226/"
              }
              else // get Mp3 from internal storage
              {
                      path1 = Android.OS.Environment.ExternalStorageDirectory.ToString();
              }
  
              var mp3Files = Directory.EnumerateFiles(path1, "*.mp3", SearchOption.AllDirectories);
  
              foreach (string currentFile in mp3Files)
              {
                  phyle = currentFile;
                  res.Add(phyle);
              }
  
              return res;
          }
  
  
      }
  
      public class PhotoViewHolder : RecyclerView.ViewHolder
      {
          public ImageView Image { get; private set; }
          public TextView Caption { get; private set; }
  
          public PhotoViewHolder(View itemView) : base(itemView)
          {
              // Locate and cache view references:
              Image = itemView.FindViewById&lt;ImageView&gt;(Resource.Id.imageView);
              Caption = itemView.FindViewById&lt;TextView&gt;(Resource.Id.textView);
          }
      }
  
      public class PhotoAlbumAdapter : RecyclerView.Adapter
      {
          public List&lt;MP3object&gt; mp3;
          public PhotoAlbumAdapter(List&lt;MP3object&gt; mp3)
          {
              this.mp3 = mp3;
          }
  
          public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
          {
              View itemView = LayoutInflater.From(parent.Context).
                          Inflate(Resource.Layout.lay, parent, false);
              PhotoViewHolder vh = new PhotoViewHolder(itemView);
              return vh;
          }
  
          public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
          {
              PhotoViewHolder vh = holder as PhotoViewHolder;
              vh.Caption.Text = mp3[position].SongName;
          }
  
          public override int ItemCount
          {
              get { return mp3.Count(); }
          }
      }
  
  
  
  }
  </code></pre>
  
  <p>So getting the list of strings with the locations of the Mp3 works very quickly, but then "WriteMetaDataToFileList(obj)" kicks in, comming from "PopulateMP3List(List content)" and this is what takes so long. What I think I need is for the recyclerview to only build the first 20 objects, and when the user starts scrolling, builds the next 20 objects and attaches them to list for them to also be scrolled. Please help me out here :) </p>