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 */ 14 package android.windowanimationjank; 15 16 import java.util.Random; 17 18 import android.app.Activity; 19 import android.os.Bundle; 20 import android.view.ViewTreeObserver.OnPreDrawListener; 21 import android.widget.Chronometer; 22 import android.widget.RadioButton; 23 import android.widget.Switch; 24 import android.widget.TextView; 25 import android.widget.ToggleButton; 26 27 /* 28 * Activity with arbitrary number of random UI elements, refresh itself constantly. 29 */ 30 public 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 }