Home | History | Annotate | Download | only in uibench
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.android.test.uibench;
     17 
     18 import android.content.Context;
     19 import android.content.res.Resources;
     20 import android.graphics.Color;
     21 import android.graphics.drawable.GradientDrawable;
     22 import android.graphics.drawable.InsetDrawable;
     23 import android.support.v7.widget.LinearLayoutManager;
     24 import android.support.v7.widget.RecyclerView;
     25 import android.view.View;
     26 import android.view.ViewGroup;
     27 
     28 import com.android.test.uibench.recyclerview.RvCompatListActivity;
     29 
     30 import java.util.ArrayList;
     31 import java.util.concurrent.TimeUnit;
     32 
     33 public class SlowNestedRecyclerViewActivity extends RvCompatListActivity {
     34     private static final int OUTER_ITEM_COUNT = 100;
     35     private static final int INNER_ITEM_COUNT = 20;
     36 
     37     private static final long INNER_ITEM_CREATE_NS = TimeUnit.MILLISECONDS.toNanos(6);
     38     private static final long INNER_ITEM_BIND_NS = TimeUnit.MILLISECONDS.toNanos(1);
     39     private static final long INNER_ITEM_ATTACH_NS = TimeUnit.MILLISECONDS.toNanos(1);
     40 
     41     private static final long OUTER_ITEM_CREATE_NS = TimeUnit.MILLISECONDS.toNanos(3);
     42     private static final long OUTER_ITEM_BIND_NS = TimeUnit.MILLISECONDS.toNanos(1);
     43     private static final long OUTER_ITEM_ATTACH_NS = TimeUnit.MILLISECONDS.toNanos(1);
     44 
     45     private SizeData mSizeData;
     46 
     47     private static class SizeData {
     48         final int innerItemWidth;
     49         final int innerItemHeight;
     50         final int headerHeight;
     51 
     52         SizeData(Resources resources) {
     53             innerItemWidth = (int) (resources.getDisplayMetrics().widthPixels / 3.3f);
     54             innerItemHeight = (int) (innerItemWidth * 1.6f);
     55             headerHeight = (int) (resources.getDisplayMetrics().heightPixels * 0.5f);
     56         }
     57     }
     58 
     59     private SizeData getSizeData(Resources resources) {
     60         if (mSizeData == null) {
     61             mSizeData = new SizeData(resources);
     62         }
     63         return mSizeData;
     64     }
     65 
     66     @Override
     67     protected RecyclerView.LayoutManager createLayoutManager(Context context) {
     68         return new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
     69     }
     70 
     71     @Override
     72     protected RecyclerView.Adapter createAdapter() {
     73         return new OuterAdapter();
     74     }
     75 
     76     private class InnerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
     77         @Override
     78         public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
     79             final long start = System.nanoTime();
     80 
     81             final float density = parent.getResources().getDisplayMetrics().density;
     82             View view = new View(parent.getContext()) {
     83                 @Override
     84                 protected void onAttachedToWindow() {
     85                     final long start = System.nanoTime();
     86                     super.onAttachedToWindow();
     87                     while (System.nanoTime() - start < INNER_ITEM_ATTACH_NS);
     88                 }
     89             };
     90 
     91             SizeData sizeData = getSizeData(parent.getResources());
     92             view.setMinimumWidth(sizeData.innerItemWidth);
     93             view.setMinimumHeight(sizeData.innerItemHeight);
     94 
     95             GradientDrawable bg = new GradientDrawable();
     96             bg.setCornerRadius(10 * density);
     97             bg.setColor(Color.BLACK);
     98             final int pad = (int)(10 * density);
     99             view.setPadding(pad, pad, pad, pad);
    100             view.setBackgroundDrawable(new InsetDrawable(bg, pad));
    101             RecyclerView.ViewHolder holder = new RecyclerView.ViewHolder(view) {};
    102 
    103             while (System.nanoTime() - start < INNER_ITEM_CREATE_NS);
    104             return holder;
    105         }
    106 
    107         @Override
    108         public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    109             final long start = System.nanoTime();
    110             while (System.nanoTime() - start < INNER_ITEM_BIND_NS);
    111         }
    112 
    113         @Override
    114         public int getItemCount() { return INNER_ITEM_COUNT; }
    115     }
    116 
    117     private class OuterAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    118         static final int TYPE_HEADER = 0;
    119         static final int TYPE_RECYCLER = 1;
    120 
    121         ArrayList<InnerAdapter> mAdapters = new ArrayList<>();
    122         RecyclerView.RecycledViewPool mSharedPool = new RecyclerView.RecycledViewPool();
    123 
    124         OuterAdapter() {
    125             for (int i = 0; i < OUTER_ITEM_COUNT; i++) {
    126                 mAdapters.add(new InnerAdapter());
    127             }
    128         }
    129 
    130         @Override
    131         public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    132             SizeData sizeData = getSizeData(parent.getResources());
    133             if (viewType == TYPE_HEADER) {
    134                 View view = new View(parent.getContext());
    135                 view.setMinimumHeight(sizeData.headerHeight);
    136                 return new RecyclerView.ViewHolder(view) {};
    137             } else {
    138                 final long start = System.nanoTime();
    139 
    140                 RecyclerView rv = new RecyclerView(parent.getContext()) {
    141                     @Override
    142                     protected void onAttachedToWindow() {
    143                         final long start = System.nanoTime();
    144                         super.onAttachedToWindow();
    145                         while (System.nanoTime() - start < OUTER_ITEM_ATTACH_NS);
    146 
    147                     }
    148                 };
    149 
    150                 rv.setLayoutParams(new RecyclerView.LayoutParams(
    151                         ViewGroup.LayoutParams.MATCH_PARENT, sizeData.innerItemHeight));
    152                 rv.setLayoutManager(new LinearLayoutManager(parent.getContext(),
    153                         LinearLayoutManager.HORIZONTAL, false));
    154                 rv.setRecycledViewPool(mSharedPool);
    155                 RecyclerView.ViewHolder holder = new RecyclerView.ViewHolder(rv) {};
    156 
    157                 while (System.nanoTime() - start < OUTER_ITEM_CREATE_NS);
    158                 return holder;
    159             }
    160         }
    161 
    162         @Override
    163         public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    164             if (getItemViewType(position) == TYPE_RECYCLER) {
    165                 final long start = System.nanoTime();
    166                 ((RecyclerView)holder.itemView).setAdapter(mAdapters.get(position));
    167                 while (System.nanoTime() - start < OUTER_ITEM_BIND_NS);
    168             }
    169         }
    170 
    171         @Override
    172         public int getItemViewType(int position) {
    173             return position == 0 ? TYPE_HEADER : TYPE_RECYCLER;
    174         }
    175 
    176         @Override
    177         public int getItemCount() {
    178             return mAdapters.size();
    179         }
    180     }
    181 }
    182