1 /* 2 * Copyright (C) 2021 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 17 package com.android.car.ui.recyclerview; 18 19 import static com.android.car.ui.core.CarUi.MIN_TARGET_API; 20 21 import static java.lang.annotation.RetentionPolicy.SOURCE; 22 23 import android.annotation.SuppressLint; 24 import android.annotation.TargetApi; 25 import android.content.Context; 26 import android.util.AttributeSet; 27 import android.view.View; 28 import android.view.View.OnLayoutChangeListener; 29 import android.view.View.OnTouchListener; 30 import android.view.ViewGroup; 31 import android.view.ViewParent; 32 import android.view.ViewTreeObserver; 33 34 import androidx.annotation.IdRes; 35 import androidx.annotation.IntDef; 36 import androidx.annotation.NonNull; 37 import androidx.annotation.Nullable; 38 import androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup; 39 import androidx.recyclerview.widget.LinearLayoutManager; 40 import androidx.recyclerview.widget.OrientationHelper; 41 import androidx.recyclerview.widget.RecyclerView; 42 import androidx.recyclerview.widget.RecyclerView.Adapter; 43 import androidx.recyclerview.widget.RecyclerView.ItemAnimator; 44 import androidx.recyclerview.widget.RecyclerView.ItemDecoration; 45 import androidx.recyclerview.widget.RecyclerView.LayoutManager; 46 import androidx.recyclerview.widget.RecyclerView.OnChildAttachStateChangeListener; 47 import androidx.recyclerview.widget.RecyclerView.OnFlingListener; 48 import androidx.recyclerview.widget.RecyclerView.OnScrollListener; 49 import androidx.recyclerview.widget.RecyclerView.ViewHolder; 50 51 import com.android.car.ui.pluginsupport.PluginFactorySingleton; 52 53 import java.lang.annotation.Retention; 54 55 /** 56 * A class to access the {@link CarUiRecyclerView} methods. The appearance and layout is 57 * customizable by OEM. 58 * <p> 59 * This is the base class for CarUiRecyclerView implementation. 60 * <p> 61 * Rendered views will comply with 62 * <a href="https://source.android.com/devices/automotive/hmi/car_ui/appendix_b">customization guardrails</a> 63 */ 64 @TargetApi(MIN_TARGET_API) 65 @SuppressLint("Instantiatable") 66 public interface CarUiRecyclerView { 67 int SIZE_SMALL = 0; 68 int SIZE_MEDIUM = 1; 69 int SIZE_LARGE = 2; 70 71 /** 72 * Describes the expected relative size of the {@link CarUiRecyclerView}. The list may be 73 * rendered differently for each expected size. 74 */ 75 @Retention(SOURCE) 76 @IntDef({SIZE_SMALL, SIZE_MEDIUM, SIZE_LARGE}) 77 @interface Size {} 78 79 /** 80 * The possible values for setScrollBarPosition. The default value is {@link 81 * CarUiRecyclerViewLayout#LINEAR}. 82 */ 83 @IntDef({ 84 CarUiRecyclerViewLayout.LINEAR, 85 CarUiRecyclerViewLayout.GRID, 86 }) 87 @Retention(SOURCE) 88 @interface CarUiRecyclerViewLayout { 89 /** 90 * Arranges items either horizontally in a single row or vertically in a single column. 91 * This is the default value. 92 */ 93 int LINEAR = 0; 94 95 /** 96 * Arranges items in a Grid. 97 */ 98 int GRID = 1; 99 } 100 101 /** 102 * Interface for a {@link RecyclerView.Adapter} to cap the number of items. 103 * 104 * <p>NOTE: it is still up to the adapter to use maxItems in {@link 105 * RecyclerView.Adapter#getItemCount()}. 106 * 107 * <p>the recommended way would be with: 108 * 109 * <pre>{@code 110 * {@literal@}Override 111 * public int getItemCount() { 112 * return Math.min(super.getItemCount(), mMaxItems); 113 * } 114 * }</pre> 115 */ 116 interface ItemCap { 117 /** 118 * Sets the maximum number of items available in the adapter. A value less than '0' means 119 * the list should not be capped. 120 */ setMaxItems(int maxItems)121 void setMaxItems(int maxItems); 122 /** 123 * A value to pass to {@link #setMaxItems(int)} that indicates there should be no limit. 124 */ 125 int UNLIMITED = -1; 126 } 127 128 /** 129 * The RecyclerView is not currently scrolling. 130 * 131 * @see #getScrollState() 132 */ 133 int SCROLL_STATE_IDLE = 0; 134 135 /** 136 * The RecyclerView is currently being dragged by outside input such as user touch input. 137 * 138 * @see #getScrollState() 139 */ 140 int SCROLL_STATE_DRAGGING = 1; 141 142 /** 143 * The RecyclerView is currently animating to a final position while not under 144 * outside control. 145 * 146 * @see #getScrollState() 147 */ 148 int SCROLL_STATE_SETTLING = 2; 149 150 /** 151 * Equivalent of {@link RecyclerView.OnScrollListener} 152 */ 153 interface OnScrollListener { onScrolled(CarUiRecyclerView recyclerView, int dx, int dy)154 void onScrolled(CarUiRecyclerView recyclerView, int dx, int dy); onScrollStateChanged(CarUiRecyclerView recyclerView, int newState)155 void onScrollStateChanged(CarUiRecyclerView recyclerView, int newState); 156 } 157 158 /** 159 * Adapters that implement this interface will receive the calls 160 */ 161 interface OnAttachListener { onAttachedToCarUiRecyclerView(@onNull CarUiRecyclerView carUiRecyclerView)162 void onAttachedToCarUiRecyclerView(@NonNull CarUiRecyclerView carUiRecyclerView); onDetachedFromCarUiRecyclerView(@onNull CarUiRecyclerView carUiRecyclerView)163 void onDetachedFromCarUiRecyclerView(@NonNull CarUiRecyclerView carUiRecyclerView); 164 } 165 166 /** 167 * Use this method to create an instance of CarUiRecyclerView at runtime. 168 */ create(Context context)169 static CarUiRecyclerView create(Context context) { 170 return PluginFactorySingleton.get(context) 171 .createRecyclerView(context, null); 172 } 173 174 /** 175 * Use this method to create an instance of CarUiRecyclerView at runtime. 176 */ create(Context context, AttributeSet attributeSet)177 static CarUiRecyclerView create(Context context, AttributeSet attributeSet) { 178 return PluginFactorySingleton.get(context) 179 .createRecyclerView(context, attributeSet); 180 } 181 182 /** 183 * see {@link RecyclerView#addItemDecoration(ItemDecoration)} 184 * @deprecated this will fail when there is a oem implementation 185 */ 186 @Deprecated addItemDecoration(@onNull ItemDecoration decor)187 void addItemDecoration(@NonNull ItemDecoration decor); 188 189 /** 190 * see {@link RecyclerView#addItemDecoration(ItemDecoration, int)} 191 * @deprecated this will fail when there is a oem implementation 192 */ 193 @Deprecated addItemDecoration(@onNull ItemDecoration decor, int index)194 void addItemDecoration(@NonNull ItemDecoration decor, int index); 195 196 /** see {@link RecyclerView#addOnChildAttachStateChangeListener} */ addOnChildAttachStateChangeListener(OnChildAttachStateChangeListener listener)197 void addOnChildAttachStateChangeListener(OnChildAttachStateChangeListener listener); 198 199 /** see {@link View#addOnLayoutChangeListener(OnLayoutChangeListener)} */ addOnLayoutChangeListener(OnLayoutChangeListener listener)200 void addOnLayoutChangeListener(OnLayoutChangeListener listener); 201 202 /** see {@link RecyclerView#addOnScrollListener(RecyclerView.OnScrollListener)} */ addOnScrollListener(OnScrollListener scrollListener)203 void addOnScrollListener(OnScrollListener scrollListener); 204 205 /** {@link RecyclerView#clearOnChildAttachStateChangeListeners()} */ clearOnChildAttachStateChangeListeners()206 void clearOnChildAttachStateChangeListeners(); 207 208 /** {@link RecyclerView#clearOnScrollListeners()} */ clearOnScrollListeners()209 void clearOnScrollListeners(); 210 211 /** see {@link LinearLayoutManager#findFirstCompletelyVisibleItemPosition()} */ findFirstCompletelyVisibleItemPosition()212 int findFirstCompletelyVisibleItemPosition(); 213 214 /** see {@link LinearLayoutManager#findFirstVisibleItemPosition()} */ findFirstVisibleItemPosition()215 int findFirstVisibleItemPosition(); 216 217 /** see {@link LinearLayoutManager#findLastCompletelyVisibleItemPosition()} */ findLastCompletelyVisibleItemPosition()218 int findLastCompletelyVisibleItemPosition(); 219 220 /** see {@link LinearLayoutManager#findLastVisibleItemPosition()} */ findLastVisibleItemPosition()221 int findLastVisibleItemPosition(); 222 223 /** 224 * see {@link View#findViewById(int)} 225 * @deprecated this will fail when there is a oem implementation 226 */ 227 @Deprecated findViewById(int id)228 <T extends View> T findViewById(int id); 229 230 /** see {@link RecyclerView#findViewHolderForAdapterPosition(int)} */ findViewHolderForAdapterPosition(int position)231 ViewHolder findViewHolderForAdapterPosition(int position); 232 233 /** see {@link RecyclerView#findViewHolderForAdapterPosition(int)} */ findViewHolderForLayoutPosition(int position)234 ViewHolder findViewHolderForLayoutPosition(int position); 235 236 /** see {@link ViewGroup#focusableViewAvailable(View)} */ focusableViewAvailable(View v)237 void focusableViewAvailable(View v); 238 239 /** see {@link RecyclerView#getAdapter()} */ getAdapter()240 Adapter<?> getAdapter(); 241 242 /** see {@link View#getAlpha()} */ getAlpha()243 float getAlpha(); 244 245 /** 246 * see {@link ViewGroup#getChildAt(int)} 247 * @deprecated this will fail when there is a oem implementation 248 */ 249 @Deprecated 250 @Nullable getChildAt(int index)251 View getChildAt(int index); 252 253 /** 254 * see {@link ViewGroup#getChildCount()} 255 * @deprecated this will fail when there is a oem implementation 256 */ 257 @Deprecated getChildCount()258 int getChildCount(); 259 260 /** 261 * see {@link RecyclerView#getChildLayoutPosition(View)} 262 */ getChildLayoutPosition(View child)263 int getChildLayoutPosition(View child); 264 265 /** see {@link View#getContentDescription()} */ getContentDescription()266 CharSequence getContentDescription(); 267 268 /** see {@link View#getContext()} */ getContext()269 Context getContext(); 270 271 /** see {@link OrientationHelper#getEndAfterPadding()} */ getEndAfterPadding()272 int getEndAfterPadding(); 273 274 /** see {@link View#getHeight()} */ getHeight()275 int getHeight(); 276 277 /** 278 * see {@link RecyclerView#getItemDecorationAt(int)} 279 * @deprecated this will fail when there is a oem implementation 280 */ 281 @Deprecated 282 @Nullable getItemDecorationAt(int index)283 ItemDecoration getItemDecorationAt(int index); 284 285 /** 286 * see {@link RecyclerView#getItemDecorationCount()} 287 * @deprecated this will fail when there is a oem implementation 288 */ 289 @Deprecated getItemDecorationCount()290 int getItemDecorationCount(); 291 292 /** 293 * see {@link RecyclerView#getLayoutManager()} 294 * @deprecated this will fail when there is a oem implementation 295 */ 296 @Deprecated 297 @Nullable getLayoutManager()298 LayoutManager getLayoutManager(); 299 300 /** Use this instead of {@link #getLayoutManager} */ 301 @Nullable getLayoutStyle()302 CarUiLayoutStyle getLayoutStyle(); 303 304 /** {@link RecyclerView#hasFixedSize()} */ hasFixedSize()305 boolean hasFixedSize(); 306 307 /** see {@link View#getPaddingLeft()} */ getPaddingLeft()308 int getPaddingLeft(); 309 310 /** see {@link View#getPaddingRight()} */ getPaddingRight()311 int getPaddingRight(); 312 313 /** see {@link View#getPaddingBottom()} */ getPaddingBottom()314 int getPaddingBottom(); 315 316 /** see {@link View#getPaddingEnd()} */ getPaddingEnd()317 int getPaddingEnd(); 318 319 /** see {@link View#getPaddingStart()} */ getPaddingStart()320 int getPaddingStart(); 321 322 /** see {@link View#getPaddingTop()} */ getPaddingTop()323 int getPaddingTop(); 324 325 /** 326 * see {@link View#getParent()} 327 * @deprecated this will fail when there is a oem implementation 328 */ 329 @Deprecated getParent()330 ViewParent getParent(); 331 332 /** 333 * see {@link LayoutManager#getChildCount()} 334 * Prefer this method over {@link #getChildCount()} 335 */ getRecyclerViewChildCount()336 int getRecyclerViewChildCount(); 337 338 /** 339 * see {@link LayoutManager#getChildAt(int)} 340 * Prefer this method over {@link #getChildAt(int)} 341 */ 342 @Nullable getRecyclerViewChildAt(int index)343 View getRecyclerViewChildAt(int index); 344 345 /** see {@link RecyclerView#getScrollState()} */ getScrollState()346 int getScrollState(); 347 348 /** see {@link OrientationHelper#getStartAfterPadding()} */ getStartAfterPadding()349 int getStartAfterPadding(); 350 351 /** see {@link View#getTag()} */ getTag()352 Object getTag(); 353 354 /** see {@link OrientationHelper#getTotalSpace()} */ getTotalSpace()355 int getTotalSpace(); 356 357 /** 358 * Returns a view that will be attached to the view hierarchy. 359 */ 360 @NonNull getView()361 View getView(); 362 363 /** see {@link View#getViewTreeObserver()} */ getViewTreeObserver()364 ViewTreeObserver getViewTreeObserver(); 365 366 /** 367 * see {@link RecyclerView#invalidateItemDecorations()} 368 * @deprecated this will fail value when there is a oem implementation 369 */ 370 @Deprecated invalidateItemDecorations()371 void invalidateItemDecorations(); 372 373 /** see {@link View#post(Runnable)} */ post(Runnable runnable)374 boolean post(Runnable runnable); 375 376 /** 377 * see {@link RecyclerView#removeItemDecoration(ItemDecoration)} 378 * @deprecated this will fail value when there is a oem implementation 379 */ 380 @Deprecated removeItemDecoration(@onNull ItemDecoration decor)381 void removeItemDecoration(@NonNull ItemDecoration decor); 382 383 /** 384 * see {@link RecyclerView#removeItemDecorationAt(int)} 385 * @deprecated this will fail value when there is a oem implementation 386 */ 387 @Deprecated removeItemDecorationAt(int index)388 void removeItemDecorationAt(int index); 389 390 /** see {@link RecyclerView#removeOnChildAttachStateChangeListener} */ removeOnChildAttachStateChangeListener(OnChildAttachStateChangeListener listener)391 void removeOnChildAttachStateChangeListener(OnChildAttachStateChangeListener listener); 392 393 /** see {@link View#removeOnLayoutChangeListener(OnLayoutChangeListener)} */ removeOnLayoutChangeListener(OnLayoutChangeListener listener)394 void removeOnLayoutChangeListener(OnLayoutChangeListener listener); 395 396 /** see {@link View#requestLayout()} */ requestLayout()397 void requestLayout(); 398 399 /** see {@link RecyclerView#removeOnScrollListener(OnScrollListener)} */ removeOnScrollListener(OnScrollListener scrollListener)400 void removeOnScrollListener(OnScrollListener scrollListener); 401 402 /** see {@link View#requireViewById(int)} */ requireViewById(int id)403 <T extends View> T requireViewById(int id); 404 405 /** see {@link View#scrollBy(int, int)} */ scrollBy(int x, int y)406 void scrollBy(int x, int y); 407 408 /** see {@link RecyclerView#scrollToPosition(int)} */ scrollToPosition(int position)409 void scrollToPosition(int position); 410 411 /** see {@link RecyclerView#setAdapter(Adapter)} */ setAdapter(Adapter<?> adapter)412 void setAdapter(Adapter<?> adapter); 413 414 /** see {@link View#setAlpha(float)} */ setAlpha(float alpha)415 void setAlpha(float alpha); 416 417 /** see {@link RecyclerView#setClipToPadding(boolean)} */ setClipToPadding(boolean enabled)418 void setClipToPadding(boolean enabled); 419 420 /** see {@link View#setContentDescription(CharSequence)} */ setContentDescription(CharSequence contentDescription)421 void setContentDescription(CharSequence contentDescription); 422 423 /** see {@link RecyclerView#setHasFixedSize(boolean)} */ setHasFixedSize(boolean hasFixedSize)424 void setHasFixedSize(boolean hasFixedSize); 425 426 /** 427 * see {@link View#setFadingEdgeLength(int)} 428 * @deprecated this will fail when there is a oem implementation 429 */ 430 @Deprecated setFadingEdgeLength(int length)431 void setFadingEdgeLength(int length); 432 433 /** see {@link RecyclerView#setOnFlingListener(OnFlingListener)} */ setOnFlingListener(OnFlingListener listener)434 void setOnFlingListener(OnFlingListener listener); 435 436 /** see {@link View#setId(int)} */ setId(@dRes int id)437 void setId(@IdRes int id); 438 439 /** 440 * see {@link RecyclerView#setItemAnimator(ItemAnimator)} 441 * @deprecated this will fail when there is a oem implementation 442 */ 443 @Deprecated setItemAnimator(ItemAnimator itemAnimator)444 void setItemAnimator(ItemAnimator itemAnimator); 445 446 /** 447 * see {@link RecyclerView#setLayoutManager(LayoutManager)} 448 * @deprecated this will fail when there is a oem implementation 449 */ 450 @Deprecated setLayoutManager(@ullable LayoutManager layoutManager)451 default void setLayoutManager(@Nullable LayoutManager layoutManager) {} 452 453 /** Use this instead of {@link #setLayoutManager} */ setLayoutStyle(@ullable CarUiLayoutStyle layoutStyle)454 void setLayoutStyle(@Nullable CarUiLayoutStyle layoutStyle); 455 456 /** see {@link View#setOnTouchListener(OnTouchListener)} */ setOnTouchListener(OnTouchListener listener)457 void setOnTouchListener(OnTouchListener listener); 458 459 /** see {@link View#setPadding(int, int, int, int)} */ setPadding(int left, int top, int right, int bottom)460 void setPadding(int left, int top, int right, int bottom); 461 462 /** see {@link View#setPaddingRelative(int, int, int, int)} */ setPaddingRelative(int start, int top, int end, int bottom)463 void setPaddingRelative(int start, int top, int end, int bottom); 464 465 /** Will get called when {@link SpanSizeLookup} changes at runtime. */ setSpanSizeLookup(@onNull SpanSizeLookup spanSizeLookup)466 void setSpanSizeLookup(@NonNull SpanSizeLookup spanSizeLookup); 467 468 /** see {@link View#setTag(Object)} */ setTag(Object tag)469 void setTag(Object tag); 470 471 /** 472 * see {@link View#setVerticalFadingEdgeEnabled(boolean)} 473 * @deprecated this will fail when there is a oem implementation 474 */ 475 @Deprecated setVerticalFadingEdgeEnabled(boolean enabled)476 void setVerticalFadingEdgeEnabled(boolean enabled); 477 478 /** 479 * see {@link View#setVerticalScrollBarEnabled(boolean)} 480 * @deprecated this will fail when there is a oem implementation 481 */ 482 @Deprecated setVerticalScrollBarEnabled(boolean enabled)483 void setVerticalScrollBarEnabled(boolean enabled); 484 485 /** 486 * see {@link View#setVerticalScrollbarPosition(int)} 487 * @deprecated this will fail when there is a oem implementation 488 */ 489 @Deprecated setVerticalScrollbarPosition(int position)490 void setVerticalScrollbarPosition(int position); 491 492 /** see {@link View#setVisibility(int)} */ setVisibility(int visible)493 void setVisibility(int visible); 494 495 /** see {@link RecyclerView#smoothScrollBy(int, int)} */ smoothScrollBy(int dx, int dy)496 void smoothScrollBy(int dx, int dy); 497 498 /** see {@link RecyclerView#smoothScrollToPosition(int) */ smoothScrollToPosition(int position)499 void smoothScrollToPosition(int position); 500 } 501