title: Android studio RecyclerView onCreateViewHolder layout inflation is so slow
body: <p>I have a root recyclerview and each item is populated with this layout:</p>
  <pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
  &lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
      xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
      android:layout_width=&quot;match_parent&quot;
      android:layout_height=&quot;wrap_content&quot;
      android:orientation=&quot;vertical&quot;
      &gt;
  
          &lt;TextView
              android:id=&quot;@+id/headerText&quot;
              android:layout_width=&quot;match_parent&quot;
              android:layout_height=&quot;wrap_content&quot;
              android:background=&quot;@drawable/accent_gradient&quot;
              android:ellipsize=&quot;end&quot;
              android:maxLines=&quot;1&quot;
              android:padding=&quot;8dp&quot;
              android:paddingStart=&quot;16dp&quot;
              android:text=&quot;My original&quot;
              android:textColor=&quot;@color/colorWhite&quot;
              android:textSize=&quot;14sp&quot; /&gt;
  
      &lt;androidx.recyclerview.widget.RecyclerView
          android:id=&quot;@+id/rootRecycler&quot;
          android:layout_width=&quot;match_parent&quot;
          android:layout_height=&quot;wrap_content&quot;
          app:layoutManager=&quot;androidx.recyclerview.widget.LinearLayoutManager&quot;
          /&gt;
  &lt;/LinearLayout&gt;
  </code></pre>
  <p>As you can see, there is another recylcerview within each item. I wanted to achieve the effect of sectioned recyclerview with headers. (So Header &gt; List Header &gt; List)</p>
  <p>Now each recyclerview is populated with this layout view:</p>
  <pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
  &lt;RelativeLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
      xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
      android:layout_width=&quot;match_parent&quot;
      android:layout_height=&quot;wrap_content&quot;
      &gt;
          &lt;TextView
              android:layout_toStartOf=&quot;@id/relativeLayout3&quot;
              android:layout_marginStart=&quot;16dp&quot;
              android:layout_marginEnd=&quot;16dp&quot;
              android:id=&quot;@+id/foodName_fv&quot;
              android:layout_width=&quot;match_parent&quot;
              android:layout_height=&quot;wrap_content&quot;
              android:paddingTop=&quot;8dp&quot;
              android:text=&quot;Food name&quot;
              android:ellipsize=&quot;end&quot;
              android:maxLines=&quot;1&quot;
              android:textColor=&quot;@color/colorBlack&quot;
              android:textSize=&quot;18sp&quot;
              android:transitionName=&quot;Food_Name&quot;/&gt;
  
          &lt;TextView
              android:layout_below=&quot;@id/foodName_fv&quot;
              android:layout_marginStart=&quot;16dp&quot;
              android:layout_marginEnd=&quot;16dp&quot;
              android:id=&quot;@+id/foodGrams_fv&quot;
              android:layout_width=&quot;wrap_content&quot;
              android:layout_height=&quot;wrap_content&quot;
              android:paddingTop=&quot;8dp&quot;
              android:paddingBottom=&quot;8dp&quot;
              android:text=&quot;Grams&quot;
              android:textColor=&quot;@color/colorLightGrey&quot;
              android:textSize=&quot;15sp&quot; /&gt;
  
      &lt;LinearLayout
          android:id=&quot;@+id/relativeLayout3&quot;
          android:layout_width=&quot;wrap_content&quot;
          android:layout_height=&quot;wrap_content&quot;
          android:layout_marginEnd=&quot;16dp&quot;
          android:orientation=&quot;vertical&quot;
          android:layout_alignParentEnd=&quot;true&quot;
          &gt;
  
          &lt;TextView
              android:id=&quot;@+id/foodCalories_fv&quot;
              android:layout_width=&quot;wrap_content&quot;
              android:layout_height=&quot;wrap_content&quot;
              android:layout_marginTop=&quot;8dp&quot;
              android:text=&quot;Calories&quot;
              android:textColor=&quot;@color/colorBlack&quot;
              android:textSize=&quot;18sp&quot;
              android:transitionName=&quot;Food_Cal&quot;/&gt;
  
          &lt;TextView
              android:layout_gravity=&quot;center&quot;
              android:id=&quot;@+id/calText_fv&quot;
              android:layout_width=&quot;wrap_content&quot;
              android:layout_height=&quot;wrap_content&quot;
              android:layout_marginTop=&quot;8dp&quot;
  
              android:paddingBottom=&quot;8dp&quot;
              android:text=&quot;@string/calText_fv&quot;
              android:textColor=&quot;@color/colorLightGrey&quot;
              android:textSize=&quot;14sp&quot; /&gt;
      &lt;/LinearLayout&gt;
  
  &lt;/RelativeLayout&gt;
  </code></pre>
  <p>This is a fairly simple layout but for some odd reason the child recyclerview takes soo much time to inflate these rows. I did some testings and it took (on average) 1200 ms to load 300 rows!</p>
  <p>Now the weirdest thing is that before this code i had a plain listview (without any sections and headers, just a big list) and it loaded all these rows very fast. I have'nt changed nothing but this code (Converting it from listview with an adapter to recyclerview with an adapter) so it looks pretty strange to me, but i dont know i might be missing something here.</p>
  <p>This is the onCreateViewHolder method:</p>
  <pre><code>    @NonNull
      @Override
      public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
          View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.food_view, parent, false);
          return new ViewHolder(view);
      }
  </code></pre>
  <p>In conclusion the child recyclerview takes too much time to do this work. And yes I am aware i can do &quot;Lazy loading&quot; but I want to figure out why the hell is it so slow?</p>
  <p><strong>EDIT 1:</strong>
  Tried implementing it in a fresh new project, thought something with the broke somehow, but its still gave same results, also tried on my actual phone and not an emulator and still slow. I really want to figure out this one already because it seems very illogical.</p>
  <p><strong>EDIT 2:</strong>
  Posting the adapters code for hamza khan:</p>
  <p>Code for the root recyclerview:</p>
  <pre><code>import android.content.Context;
  import android.view.LayoutInflater;
  import android.view.View;
  import android.view.ViewGroup;
  import android.widget.TextView;
  
  import java.util.ArrayList;
  
  import androidx.annotation.NonNull;
  import androidx.recyclerview.widget.RecyclerView;
  
  public class SelectFoodRootRecyclerAdapter extends RecyclerView.Adapter&lt;SelectFoodRootRecyclerAdapter.ViewHolder&gt; {
  
      private static final String TAG = &quot;SelectFoodRootRecyclerAdapter&quot;;
  
      private Context mContext;
      private ArrayList&lt;SectionedFoodGroup&gt; items;
      private ArrayList&lt;SelectFoodChildRecyclerAdapter&gt; adapters; //For filter use outside this class
  
      RecyclerView.RecycledViewPool recycledViewPool;
  
  
      public SelectFoodRootRecyclerAdapter(Context mContext) {
          this.mContext = mContext;
  
          items = new ArrayList&lt;&gt;();
          adapters = new ArrayList&lt;&gt;();
  
          recycledViewPool = new RecyclerView.RecycledViewPool();
  
          SectionedFoodGroup section1 = new SectionedFoodGroup(mContext.getString(R.string.myFoods),
                  FoodsDBHelper.getAllFoodRows(Food.DBType.USER_CREATED_FOODS_DB.ordinal()));
  
          SectionedFoodGroup section2 = new SectionedFoodGroup(mContext.getString(R.string.foods),
                  FoodsDBHelper.getAllFoodRows(Food.DBType.REGULAR_FOOD_DB.ordinal()));
  
          addSection(section1);
          addSection(section2);
      }
  
      private void addSection(SectionedFoodGroup sectionedFoodGroup){
          if(sectionedFoodGroup.getFoods().size() &gt; 0){
              items.add(sectionedFoodGroup);
              adapters.add(new SelectFoodChildRecyclerAdapter(mContext, sectionedFoodGroup.getFoods()));
          }
      }
  
      public ArrayList&lt;SelectFoodChildRecyclerAdapter&gt; getAdapters(){
          return adapters;
      }
  
      @NonNull
      @Override
      public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
          View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_sfa_viewholder, parent, false);
          return new ViewHolder(view);
      }
  
      @Override
      public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
  
          SectionedFoodGroup sectionedFoodGroup = items.get(position);
  
          holder.headerText.setText(sectionedFoodGroup.getHeaderName());
  
          holder.foodsRecycler.setAdapter(adapters.get(position));
          holder.foodsRecycler.setRecycledViewPool(recycledViewPool);
      }
  
      @Override
      public int getItemCount() {
          return items != null ? items.size() : 0;
      }
  
      public class ViewHolder extends RecyclerView.ViewHolder {
  
          TextView headerText;
          RecyclerView foodsRecycler;
  
          public ViewHolder(@NonNull View itemView) {
              super(itemView);
              headerText = itemView.findViewById(R.id.headerText);
              foodsRecycler = itemView.findViewById(R.id.rootRecycler);
          }
      }
  }
  </code></pre>
  <p>Code for the child recyclerview (the one containing all the actual rows):</p>
  <pre><code>import android.content.Context;
  import android.view.LayoutInflater;
  import android.view.View;
  import android.view.ViewGroup;
  import android.widget.Filter;
  import android.widget.Filterable;
  import android.widget.TextView;
  
  import java.text.DecimalFormat;
  import java.util.ArrayList;
  
  import androidx.annotation.NonNull;
  import androidx.recyclerview.widget.RecyclerView;
  
  public class SelectFoodChildRecyclerAdapter extends RecyclerView.Adapter&lt;SelectFoodChildRecyclerAdapter.ViewHolder&gt;{
  
      private static final String TAG = &quot;SelectFoodChildRecyclerAdapter&quot;;
  
      private Context mContext;
  
      private ArrayList&lt;Food&gt; original;
      private DecimalFormat decimalFormat;
  
      public SelectFoodChildRecyclerAdapter(Context mContext, ArrayList&lt;Food&gt; foods) {
          this.mContext = mContext;
          this.original = foods;
          decimalFormat = new DecimalFormat(&quot;#.0&quot;);
      }
  
      @NonNull
      @Override
      public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
          View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.food_view, parent, false);
          return new ViewHolder(view);
      }
  
      @Override
      public void onBindViewHolder(@NonNull ViewHolder holder, int foodPos) {
          Food currFood = original.get(foodPos);
  
          holder.foodName.setText(currFood.getName());
  
          float grams = 100;
          if(currFood.getAmount() != 0) grams = (float)currFood.getAmount();
  
          int roundedGrams = (int)Math.round(grams);
          holder.foodGrams.setText(roundedGrams +&quot; &quot;+ mContext.getResources().getString(R.string.gramsWord));
  
          float caloriesToShow = (float)currFood.getCalories();
  
          holder.foodCalories.setText(decimalFormat.format(caloriesToShow));
      }
  
      @Override
      public int getItemCount() {
          return original != null ? original.size() : 0;
      }
  
      public class ViewHolder extends RecyclerView.ViewHolder {
          TextView foodName;
          TextView foodGrams;
          TextView foodCalories;
  
          public ViewHolder(View itemView) {
              super(itemView);
              foodName = itemView.findViewById(R.id.foodName_fv);
              foodGrams = itemView.findViewById(R.id.foodGrams_fv);
              foodCalories = itemView.findViewById(R.id.foodCalories_fv);
          }
      }
  }
  </code></pre>
  <p>The calling activity onCreate method:</p>
  <pre><code>@Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_select_food);
  
          foodsRecyclerView = findViewById(R.id.rootRecycler);
  
          selectFoodRootRecyclerAdapter = new SelectFoodRootRecyclerAdapter(this);
          foodsRecyclerView.setAdapter(selectFoodRootRecyclerAdapter);
  
      }
  </code></pre>
  <p>Again, as you can see all the code is fairly simple..</p>
  <p><strong>EDIT 3:</strong>
  Ok so i've narrowed it down even more. I tried to do just one big recyclerview of the second layout and it worked fast. SOOO the problem must be with the first layout/the root recyclerview adapter code. but everything seems fine with it...</p>
  <p>I really don't know what am I missing here!! Thanks for any kind of help!</p>
  <p>Thanks!</p>