blob: 8fdd4b90c23ee09963146fcda3b1627e0f491328 [file] [log] [blame]
Chris Craik58d30ae2016-10-12 11:10:36 -07001/*
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 */
16package com.android.test.uibench;
17
18import android.content.Context;
19import android.content.res.Resources;
20import android.graphics.Color;
21import android.graphics.drawable.GradientDrawable;
22import android.graphics.drawable.InsetDrawable;
Aurimas Liutikas1d6c6da2018-04-03 17:08:29 -070023import androidx.recyclerview.widget.LinearLayoutManager;
24import androidx.recyclerview.widget.RecyclerView;
Chris Craik58d30ae2016-10-12 11:10:36 -070025import android.view.View;
26import android.view.ViewGroup;
27
28import com.android.test.uibench.recyclerview.RvCompatListActivity;
29
30import java.util.ArrayList;
31import java.util.concurrent.TimeUnit;
32
33public 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}