1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 * in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the License
10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 * or implied. See the License for the specific language governing permissions and limitations under
12 * the License.
13 */
14package android.windowanimationjank;
15
16import java.util.Random;
17
18import android.app.Activity;
19import android.os.Bundle;
20import android.view.ViewTreeObserver.OnPreDrawListener;
21import android.widget.Chronometer;
22import android.widget.RadioButton;
23import android.widget.Switch;
24import android.widget.TextView;
25import android.widget.ToggleButton;
26
27/*
28 * Activity with arbitrary number of random UI elements, refresh itself constantly.
29 */
30public class ElementLayoutActivity extends Activity implements OnPreDrawListener {
31    public final static String NUM_ELEMENTS_KEY = "num_elements";
32
33    private final static int DEFAULT_NUM_ELEMENTS = 100;
34    private final static int BACKGROUND_COLOR = 0xfffff000;
35    private final static int INDICATOR_COLOR = 0xffff0000;
36
37    private FlowLayout mLayout;
38    // Use the constant seed in order to get predefined order of elements.
39    private Random mRandom = new Random(0);
40    // Blinker indicator for visual feedback that Activity is currently updating.
41    private TextView mIndicator;
42    private static float mIndicatorState;
43
44    @Override
45    protected void onCreate(final Bundle savedInstanceState) {
46        super.onCreate(savedInstanceState);
47        setContentView(R.layout.flowlayout);
48
49        mLayout = (FlowLayout)findViewById(R.id.root_flow_layout);
50        mLayout.setBackgroundColor(BACKGROUND_COLOR);
51
52        mIndicator = new TextView(this);
53        mLayout.addView(mIndicator);
54        mIndicator.setText("***\n***");
55        mIndicator.setBackgroundColor(BACKGROUND_COLOR);
56        mIndicatorState = 0.0f;
57
58        // Need constantly invalidate view in order to get max redraw rate.
59        mLayout.getViewTreeObserver().addOnPreDrawListener(this);
60
61        // Read requested number of elements in layout.
62        int numElements = getIntent().getIntExtra(NUM_ELEMENTS_KEY, DEFAULT_NUM_ELEMENTS);
63
64        for (int i = 0; i < numElements; ++i) {
65            switch (mRandom.nextInt(5)) {
66            case 0:
67                createRadioButton();
68                break;
69            case 1:
70                createToggleButton();
71                break;
72            case 2:
73                createSwitch();
74                break;
75            case 3:
76                createTextView();
77                break;
78            case 4:
79                createChronometer();
80                break;
81            }
82        }
83
84        setContentView(mLayout);
85    }
86
87    private void createTextView() {
88        TextView textView = new TextView(this);
89        int lineCnt = mRandom.nextInt(4);
90        StringBuffer buffer = new StringBuffer();
91        for (int i = 0; i < lineCnt; ++i) {
92            if (i != 0) {
93                buffer.append("\n");
94            }
95            buffer.append("Line:" + mRandom.nextInt());
96        }
97        textView.setText(buffer);
98        mLayout.addView(textView);
99    }
100
101    private void createRadioButton() {
102        RadioButton button = new RadioButton(this);
103        button.setText("RadioButton:" + mRandom.nextInt());
104        mLayout.addView(button);
105    }
106
107    private void createToggleButton() {
108        ToggleButton button = new ToggleButton(this);
109        button.setChecked(mRandom.nextBoolean());
110        mLayout.addView(button);
111    }
112
113    private void createSwitch() {
114        Switch button = new Switch(this);
115        button.setChecked(mRandom.nextBoolean());
116        mLayout.addView(button);
117    }
118
119    private void createChronometer() {
120        Chronometer chronometer = new Chronometer(this);
121        chronometer.setBase(mRandom.nextLong());
122        mLayout.addView(chronometer);
123        chronometer.start();
124    }
125
126    @Override
127    protected void onResume() {
128        super.onResume();
129    }
130
131    @Override
132    protected void onPause() {
133        super.onPause();
134    }
135
136    @Override
137    public boolean onPreDraw() {
138        // Interpolate indicator color
139        int background = 0xff000000;
140        for (int i = 0; i < 3; ++i) {
141            int shift = 8 * i;
142            int colorB = (BACKGROUND_COLOR >> shift) & 0xff;
143            int colorI = (INDICATOR_COLOR >> shift) & 0xff;
144            int color = (int)((float)colorB * (1.0f - mIndicatorState) +
145                    (float)colorI * mIndicatorState);
146            if (color > 255) {
147                color = 255;
148            }
149            background |= (color << shift);
150        }
151
152        mIndicator.setBackgroundColor(background);
153        mIndicatorState += (3 / 60.0f);  // around 3 times per second
154        mIndicatorState = mIndicatorState - (int)mIndicatorState;
155
156        mLayout.postInvalidate();
157        return true;
158    }
159}