1<?xml version="1.0" encoding="utf-8"?> 2<!-- 3 ~ Copyright (C) 2020 The Android Open Source Project 4 ~ 5 ~ Licensed under the Apache License, Version 2.0 (the "License"); 6 ~ you may not use this file except in compliance with the License. 7 ~ You may obtain a copy of the License at 8 ~ 9 ~ http://www.apache.org/licenses/LICENSE-2.0 10 ~ 11 ~ Unless required by applicable law or agreed to in writing, software 12 ~ distributed under the License is distributed on an "AS IS" BASIS, 13 ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ~ See the License for the specific language governing permissions and 15 ~ limitations under the License. 16 --> 17<LinearLayout 18 xmlns:android="http://schemas.android.com/apk/res/android" 19 xmlns:app="http://schemas.android.com/apk/res-auto" 20 android:layout_width="match_parent" 21 android:layout_height="match_parent" 22 android:orientation="vertical"> 23 24 <com.android.car.ui.FocusArea 25 android:layout_margin="16dp" 26 android:layout_width="match_parent" 27 android:layout_height="wrap_content" 28 android:orientation="vertical"> 29 <EditText 30 android:layout_width="match_parent" 31 android:layout_height="wrap_content" 32 android:singleLine="true"> 33 </EditText> 34 </com.android.car.ui.FocusArea> 35 36 <HorizontalScrollView 37 android:layout_width="match_parent" 38 android:layout_height="wrap_content"> 39 <LinearLayout 40 android:layout_width="match_parent" 41 android:layout_height="wrap_content"> 42 43 <!-- A FocusArea with some buttons. 44 Upon nudging into this area, the default focus should land on the first 45 button in this container. Rotating the rotary controller clockwise will move the 46 focus from top to bottom. Counterclockwise to move the focus from bottom to up. 47 Nudge any direction to leave this focus area. The disabled button is skipped. --> 48 <com.android.car.ui.FocusArea 49 android:id="@+id/card_normal" 50 android:background="@color/card_background_color" 51 android:layout_margin="16dp" 52 android:layout_width="@dimen/card_width" 53 android:layout_height="match_parent" 54 android:padding="@dimen/card_padding" 55 android:orientation="vertical"> 56 <TextView 57 android:layout_height="@dimen/description_height" 58 android:layout_width="match_parent" 59 android:text="@string/card_normal_text" /> 60 <Button 61 android:layout_width="match_parent" 62 android:layout_height="50dp" 63 android:onClick="onRotaryButtonClick" 64 android:tag="test_button" 65 android:text="Button" /> 66 67 <!-- This button is disabled and is not focusable by RotaryService. 68 The RotaryService can see disabled views but it can't focus them. Android 69 doesn't allow disabled views to be focused. 70 The focus will skip this button when rotating the rotary countroller. --> 71 <Button 72 android:background="@color/button_disabled_background_color" 73 android:layout_width="match_parent" 74 android:layout_height="50dp" 75 android:onClick="onRotaryButtonClick" 76 android:enabled="false" 77 android:tag="test_button" 78 android:text="Disabled" /> 79 <Button 80 android:layout_width="match_parent" 81 android:layout_height="50dp" 82 android:onClick="onRotaryButtonClick" 83 android:tag="test_button" 84 android:text="Button" /> 85 <Button 86 android:layout_width="match_parent" 87 android:layout_height="50dp" 88 android:onClick="onRotaryButtonClick" 89 android:tag="test_button" 90 android:text="Button" /> 91 </com.android.car.ui.FocusArea> 92 93 <!-- A FocusArea where all elements are disabled. Elements that are disabled 94 (android:enabled="false") or not focusable (android:focusable="false") are 95 discoverable by the RotaryService, but the RotaryService will not focus them. 96 When no elements is focusable, nudging left and right from the adjacent cards 97 will cause focus to appear to skip this card --> 98 <com.android.car.ui.FocusArea 99 android:id="@+id/card_disabled" 100 android:background="@color/card_disabled_background_color" 101 android:layout_margin="16dp" 102 android:layout_width="@dimen/card_width" 103 android:layout_height="match_parent" 104 android:padding="@dimen/card_padding" 105 android:orientation="vertical"> 106 <TextView 107 android:layout_height="@dimen/description_height" 108 android:layout_width="match_parent" 109 android:text="@string/card_disabled_text" /> 110 <Button 111 android:layout_width="match_parent" 112 android:layout_height="50dp" 113 android:onClick="onRotaryButtonClick" 114 android:enabled="false" 115 android:tag="test_button" 116 android:text="Disabled" /> 117 <Button 118 android:layout_width="match_parent" 119 android:layout_height="50dp" 120 android:onClick="onRotaryButtonClick" 121 android:enabled="false" 122 android:tag="test_button" 123 android:text="Disabled" /> 124 <Button 125 android:layout_width="match_parent" 126 android:layout_height="50dp" 127 android:onClick="onRotaryButtonClick" 128 android:enabled="false" 129 android:tag="test_button" 130 android:text="Disabled" /> 131 <Button 132 android:layout_width="match_parent" 133 android:layout_height="50dp" 134 android:onClick="onRotaryButtonClick" 135 android:enabled="false" 136 android:tag="test_button" 137 android:text="Disabled" /> 138 </com.android.car.ui.FocusArea> 139 140 <!-- A FocusArea that contains a button with a default focus attribute. 141 Upon nudging into this area, the focus will land on the button with the default 142 focus attribute. Rotating the rotary controller clockwise will move the focus 143 from top to bottom. Counterclockwise to move the focus from bottom to up. 144 Nudge any direction to leave this focus area. --> 145 <com.android.car.ui.FocusArea 146 android:id="@+id/card_with_default_focus" 147 android:background="@color/card_background_color" 148 android:layout_margin="16dp" 149 android:layout_width="@dimen/card_width" 150 android:layout_height="match_parent" 151 android:padding="@dimen/card_padding" 152 android:orientation="vertical" 153 app:defaultFocus="@+id/default_focus"> 154 <TextView 155 android:layout_height="@dimen/description_height" 156 android:layout_width="match_parent" 157 android:text="@string/card_with_default_focus_text" /> 158 <Button 159 android:layout_width="match_parent" 160 android:layout_height="50dp" 161 android:onClick="onRotaryButtonClick" 162 android:tag="test_button" 163 android:text="Button" /> 164 <Button 165 android:id="@+id/default_focus" 166 android:layout_width="match_parent" 167 android:layout_height="50dp" 168 android:onClick="onRotaryButtonClick" 169 android:tag="test_button" 170 android:text="Button (Default)" /> 171 <Button 172 android:layout_width="match_parent" 173 android:layout_height="50dp" 174 android:onClick="onRotaryButtonClick" 175 android:tag="test_button" 176 android:text="Button" /> 177 <Button 178 android:layout_width="match_parent" 179 android:layout_height="50dp" 180 android:onClick="onRotaryButtonClick" 181 android:tag="test_button" 182 android:text="Button" /> 183 </com.android.car.ui.FocusArea> 184 185 <!-- A FocusArea with buttons in a circle. 186 Rotating clockwise moves the focus from A -> B -> C -> D -> E -> F -> G -> H, 187 and reverse counterclockwise. --> 188 <com.android.car.ui.FocusArea 189 android:id="@+id/card_that_wraps_around" 190 android:background="@color/card_background_color" 191 android:layout_margin="16dp" 192 android:layout_width="@dimen/card_width" 193 android:layout_height="match_parent" 194 android:padding="@dimen/card_padding" 195 android:orientation="vertical" 196 app:wrapAround="true"> 197 <TextView 198 android:layout_height="@dimen/description_height" 199 android:layout_width="match_parent" 200 android:text="@string/card_that_wraps_around_text" /> 201 <androidx.constraintlayout.widget.ConstraintLayout 202 android:layout_width="match_parent" 203 android:layout_height="match_parent"> 204 <View 205 android:id="@+id/circle_center" 206 android:layout_width="wrap_content" 207 android:layout_height="wrap_content" 208 app:layout_constraintBottom_toBottomOf="parent" 209 app:layout_constraintLeft_toLeftOf="parent" 210 app:layout_constraintRight_toRightOf="parent" 211 app:layout_constraintTop_toTopOf="parent" /> 212 <Button 213 android:id="@+id/button_a" 214 android:layout_width="wrap_content" 215 android:layout_height="wrap_content" 216 android:nextFocusForward="@+id/button_b" 217 android:padding="20dp" 218 android:text="A" 219 app:layout_constraintCircle="@id/circle_center" 220 app:layout_constraintCircleAngle="0" 221 app:layout_constraintCircleRadius="90dp" 222 /> 223 <Button 224 android:id="@+id/button_b" 225 android:layout_width="wrap_content" 226 android:layout_height="wrap_content" 227 android:nextFocusForward="@+id/button_c" 228 android:padding="20dp" 229 android:text="B" 230 app:layout_constraintCircle="@id/circle_center" 231 app:layout_constraintCircleAngle="45" 232 app:layout_constraintCircleRadius="90dp" 233 /> 234 <Button 235 android:id="@+id/button_c" 236 android:layout_width="wrap_content" 237 android:layout_height="wrap_content" 238 android:nextFocusForward="@+id/button_d" 239 android:padding="20dp" 240 android:text="C" 241 app:layout_constraintCircle="@id/circle_center" 242 app:layout_constraintCircleAngle="90" 243 app:layout_constraintCircleRadius="90dp" 244 /> 245 <Button 246 android:id="@+id/button_d" 247 android:layout_width="wrap_content" 248 android:layout_height="wrap_content" 249 android:nextFocusForward="@+id/button_e" 250 android:padding="20dp" 251 android:text="D" 252 app:layout_constraintCircle="@id/circle_center" 253 app:layout_constraintCircleAngle="135" 254 app:layout_constraintCircleRadius="90dp" 255 /> 256 <Button 257 android:id="@+id/button_e" 258 android:layout_width="wrap_content" 259 android:layout_height="wrap_content" 260 android:nextFocusForward="@+id/button_f" 261 android:padding="20dp" 262 android:text="E" 263 app:layout_constraintCircle="@id/circle_center" 264 app:layout_constraintCircleAngle="180" 265 app:layout_constraintCircleRadius="90dp" 266 /> 267 <Button 268 android:id="@+id/button_f" 269 android:layout_width="wrap_content" 270 android:layout_height="wrap_content" 271 android:nextFocusForward="@+id/button_g" 272 android:padding="20dp" 273 android:text="F" 274 app:layout_constraintCircle="@id/circle_center" 275 app:layout_constraintCircleAngle="225" 276 app:layout_constraintCircleRadius="90dp" 277 /> 278 <Button 279 android:id="@+id/button_g" 280 android:layout_width="wrap_content" 281 android:layout_height="wrap_content" 282 android:nextFocusForward="@+id/button_h" 283 android:padding="20dp" 284 android:text="G" 285 app:layout_constraintCircle="@id/circle_center" 286 app:layout_constraintCircleAngle="270" 287 app:layout_constraintCircleRadius="90dp" 288 /> 289 <Button 290 android:id="@+id/button_h" 291 android:layout_width="wrap_content" 292 android:layout_height="wrap_content" 293 android:padding="20dp" 294 android:text="H" 295 app:layout_constraintCircle="@id/circle_center" 296 app:layout_constraintCircleAngle="315" 297 app:layout_constraintCircleRadius="90dp" 298 /> 299 </androidx.constraintlayout.widget.ConstraintLayout> 300 </com.android.car.ui.FocusArea> 301 <!-- A FocusArea to demonstrate how to update a view properly. 302 Don't remove the focused view, otherwise Android framework will focus on another 303 view (the default focus view, or the first focusable view in the view tree), and 304 the user will see the focus highlight jump away unexpectedly. Some workarounds: 305 1. Don't remove the view. You may achieve the desired behavior by updating the 306 source image of focused view. 307 2. Delegate the view focus to its container, therefore removing the view won't 308 affect the focus 309 3. Make another view request focus explicitly after Android framework adjusts the 310 focus. 311 Don't disable the focused view, otherwise Android framework will focus on another 312 view. A workaround is to use a custom state to replace android:state_disabled so 313 that it appears disabled but is not disabled actually. 314 --> 315 <com.android.car.ui.FocusArea 316 android:id="@+id/focus_area5" 317 android:background="@color/card_background_color" 318 android:layout_margin="16dp" 319 android:layout_width="@dimen/card_width" 320 android:layout_height="match_parent" 321 android:padding="@dimen/card_padding" 322 android:orientation="vertical"> 323 <Button 324 android:id="@+id/button_5a" 325 android:layout_width="match_parent" 326 android:layout_height="50dp" 327 android:text="focus jumps" /> 328 <Button 329 android:id="@+id/button_5b" 330 android:layout_width="wrap_content" 331 android:layout_height="wrap_content" 332 android:layout_gravity="center" 333 android:background="@drawable/ic_play_arrow"/> 334 <FrameLayout 335 android:id="@+id/button_5c_container" 336 android:layout_width="match_parent" 337 android:layout_height="50dp" 338 android:focusable="true"> 339 <Button 340 android:id="@+id/button_5c" 341 android:layout_width="match_parent" 342 android:layout_height="match_parent" 343 android:text="focus stays" /> 344 </FrameLayout> 345 <Button 346 android:id="@+id/button_5d" 347 android:layout_width="match_parent" 348 android:layout_height="50dp" 349 android:text="focus returns" /> 350 <Button 351 android:id="@+id/button_5e" 352 android:layout_width="wrap_content" 353 android:layout_height="wrap_content" 354 android:layout_gravity="center" 355 android:background="@drawable/button_background"/> 356 <com.android.car.rotaryplayground.CustomButton 357 android:id="@+id/button_5f" 358 android:layout_width="wrap_content" 359 android:layout_height="wrap_content" 360 android:layout_gravity="center" 361 android:background="@drawable/custom_button_background"/> 362 </com.android.car.ui.FocusArea> 363 </LinearLayout> 364 </HorizontalScrollView> 365</LinearLayout> 366