• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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.chassis.car.ui.plugin.recyclerview;
18 
19 import static androidx.recyclerview.widget.RecyclerView.VERTICAL;
20 
21 import android.content.Context;
22 import android.view.View;
23 
24 import androidx.annotation.NonNull;
25 import androidx.annotation.Nullable;
26 import androidx.recyclerview.widget.GridLayoutManager;
27 import androidx.recyclerview.widget.LinearLayoutManager;
28 import androidx.recyclerview.widget.RecyclerView;
29 import androidx.recyclerview.widget.RecyclerView.OnChildAttachStateChangeListener;
30 import androidx.recyclerview.widget.RecyclerView.ViewHolder;
31 
32 import com.android.car.ui.plugin.oemapis.recyclerview.AdapterOEMV1;
33 import com.android.car.ui.plugin.oemapis.recyclerview.LayoutStyleOEMV1;
34 import com.android.car.ui.plugin.oemapis.recyclerview.OnChildAttachStateChangeListenerOEMV1;
35 import com.android.car.ui.plugin.oemapis.recyclerview.RecyclerViewAttributesOEMV1;
36 import com.android.car.ui.plugin.oemapis.recyclerview.RecyclerViewOEMV2;
37 import com.android.car.ui.plugin.oemapis.recyclerview.ViewHolderOEMV1;
38 import com.android.car.ui.recyclerview.CarUiRecyclerView;
39 import com.android.car.ui.recyclerview.CarUiRecyclerViewImpl;
40 import com.android.car.ui.recyclerview.RecyclerViewAdapterV1;
41 
42 import java.util.ArrayList;
43 import java.util.List;
44 
45 /**
46  *  Adapts a {@link RecyclerViewAdapterV1} into a {@link RecyclerViewOEMV2}.
47  */
48 public class RecyclerViewAdapterProxyV2 implements RecyclerViewOEMV2 {
49     private Context mPluginContext;
50     private CarUiRecyclerViewImpl mRecyclerView;
51 
RecyclerViewAdapterProxyV2(Context pluginContext, CarUiRecyclerViewImpl recyclerView, RecyclerViewAttributesOEMV1 recyclerViewAttributesOEMV1)52     public RecyclerViewAdapterProxyV2(Context pluginContext, CarUiRecyclerViewImpl recyclerView,
53             RecyclerViewAttributesOEMV1 recyclerViewAttributesOEMV1) {
54         mPluginContext = pluginContext;
55         mRecyclerView = recyclerView;
56         setLayoutStyle(recyclerViewAttributesOEMV1.getLayoutStyle());
57     }
58 
59     @NonNull
60     private final List<OnScrollListenerOEMV2> mScrollListeners = new ArrayList<>();
61 
62     @NonNull
63     private final CarUiRecyclerView.OnScrollListener mOnScrollListener =
64             new CarUiRecyclerView.OnScrollListener() {
65                 @Override
66                 public void onScrolled(@NonNull CarUiRecyclerView recyclerView, int dx, int dy) {
67                     for (OnScrollListenerOEMV2 listener : mScrollListeners) {
68                         listener.onScrolled(RecyclerViewAdapterProxyV2.this, dx, dy);
69                     }
70                 }
71 
72                 @Override
73                 public void onScrollStateChanged(@NonNull CarUiRecyclerView recyclerView,
74                         int newState) {
75                     for (OnScrollListenerOEMV2 listener : mScrollListeners) {
76                         listener.onScrollStateChanged(RecyclerViewAdapterProxyV2.this,
77                                 toInternalScrollState(newState));
78                     }
79                 }
80             };
81     @NonNull
82     private final List<OnChildAttachStateChangeListenerOEMV1> mOnChildAttachStateChangeListeners =
83             new ArrayList<>();
84 
85     @NonNull
86     private final OnChildAttachStateChangeListener mOnChildAttachStateChangeListener =
87             new OnChildAttachStateChangeListener() {
88                 @Override
89                 public void onChildViewAttachedToWindow(@NonNull View view) {
90                     for (OnChildAttachStateChangeListenerOEMV1 listener :
91                             mOnChildAttachStateChangeListeners) {
92                         listener.onChildViewAttachedToWindow(view);
93                     }
94                 }
95 
96                 @Override
97                 public void onChildViewDetachedFromWindow(@NonNull View view) {
98                     for (OnChildAttachStateChangeListenerOEMV1 listener :
99                             mOnChildAttachStateChangeListeners) {
100                         listener.onChildViewDetachedFromWindow(view);
101                     }
102                 }
103             };
104 
toInternalScrollState(int state)105     private static int toInternalScrollState(int state) {
106         /* default to RecyclerView.SCROLL_STATE_IDLE */
107         int internalState = RecyclerViewOEMV2.SCROLL_STATE_IDLE;
108         switch (state) {
109             case RecyclerView.SCROLL_STATE_DRAGGING:
110                 internalState = RecyclerViewOEMV2.SCROLL_STATE_DRAGGING;
111                 break;
112             case RecyclerView.SCROLL_STATE_SETTLING:
113                 internalState = RecyclerViewOEMV2.SCROLL_STATE_SETTLING;
114                 break;
115         }
116         return internalState;
117     }
118 
119 
120     @Override
setAdapter(AdapterOEMV1<V> adapterOEMV1)121     public <V extends ViewHolderOEMV1> void setAdapter(AdapterOEMV1<V> adapterOEMV1) {
122         if (adapterOEMV1 == null) {
123             mRecyclerView.setAdapter(null);
124         } else {
125             mRecyclerView.setAdapter(new RVAdapterWrapper(adapterOEMV1));
126         }
127     }
128 
129     @Override
addOnScrollListener(@onNull OnScrollListenerOEMV2 onScrollListenerOEMV2)130     public void addOnScrollListener(@NonNull OnScrollListenerOEMV2 onScrollListenerOEMV2) {
131         if (mScrollListeners.isEmpty()) {
132             mRecyclerView.addOnScrollListener(mOnScrollListener);
133         }
134         mScrollListeners.add(onScrollListenerOEMV2);
135     }
136 
137     @Override
removeOnScrollListener(@onNull OnScrollListenerOEMV2 onScrollListenerOEMV2)138     public void removeOnScrollListener(@NonNull OnScrollListenerOEMV2 onScrollListenerOEMV2) {
139         mScrollListeners.remove(onScrollListenerOEMV2);
140         if (mScrollListeners.isEmpty()) {
141             mRecyclerView.removeOnScrollListener(mOnScrollListener);
142         }
143     }
144 
145     @Override
clearOnScrollListeners()146     public void clearOnScrollListeners() {
147         if (!mScrollListeners.isEmpty()) {
148             mScrollListeners.clear();
149             mRecyclerView.clearOnScrollListeners();
150         }
151     }
152 
153     @Override
scrollToPosition(int i)154     public void scrollToPosition(int i) {
155         mRecyclerView.scrollToPosition(i);
156     }
157 
158     @Override
smoothScrollBy(int i, int i1)159     public void smoothScrollBy(int i, int i1) {
160         mRecyclerView.smoothScrollBy(i, i1);
161     }
162 
163     @Override
smoothScrollToPosition(int i)164     public void smoothScrollToPosition(int i) {
165         mRecyclerView.smoothScrollToPosition(i);
166     }
167 
168     @Override
setHasFixedSize(boolean b)169     public void setHasFixedSize(boolean b) {
170         mRecyclerView.setHasFixedSize(b);
171     }
172 
173     @Override
hasFixedSize()174     public boolean hasFixedSize() {
175         return mRecyclerView.hasFixedSize();
176     }
177 
178     @Nullable
179     private LayoutStyleOEMV1 mLayoutStyle;
180     @Override
setLayoutStyle(LayoutStyleOEMV1 layoutStyleOEMV1)181     public void setLayoutStyle(LayoutStyleOEMV1 layoutStyleOEMV1) {
182         mLayoutStyle = layoutStyleOEMV1;
183 
184         int orientation = layoutStyleOEMV1 == null ? VERTICAL : layoutStyleOEMV1.getOrientation();
185         boolean reverseLayout = layoutStyleOEMV1 != null && layoutStyleOEMV1.getReverseLayout();
186 
187         if (layoutStyleOEMV1 == null
188                 || layoutStyleOEMV1.getLayoutType() == LayoutStyleOEMV1.LAYOUT_TYPE_LINEAR) {
189             mRecyclerView.setLayoutManager(new LinearLayoutManager(mPluginContext,
190                     orientation,
191                     reverseLayout));
192         } else {
193             GridLayoutManager glm = new GridLayoutManager(mPluginContext,
194                     layoutStyleOEMV1.getSpanCount(),
195                     orientation,
196                     reverseLayout);
197             glm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
198                 @Override
199                 public int getSpanSize(int position) {
200                     return layoutStyleOEMV1.getSpanSize(position);
201                 }
202             });
203             mRecyclerView.setLayoutManager(glm);
204         }
205     }
206 
207     @Override
getLayoutStyle()208     public LayoutStyleOEMV1 getLayoutStyle() {
209         return mLayoutStyle;
210     }
211 
212     @Override
getView()213     public View getView() {
214         return mRecyclerView.getView();
215     }
216 
217     @Override
setPadding(int i, int i1, int i2, int i3)218     public void setPadding(int i, int i1, int i2, int i3) {
219         mRecyclerView.setPadding(i, i1, i2, i3);
220     }
221 
222     @Override
setPaddingRelative(int i, int i1, int i2, int i3)223     public void setPaddingRelative(int i, int i1, int i2, int i3) {
224         mRecyclerView.setPaddingRelative(i, i1, i2, i3);
225     }
226 
227     @Override
setClipToPadding(boolean b)228     public void setClipToPadding(boolean b) {
229         mRecyclerView.setClipToPadding(b);
230     }
231 
232     @Override
findFirstCompletelyVisibleItemPosition()233     public int findFirstCompletelyVisibleItemPosition() {
234         return mRecyclerView.findFirstCompletelyVisibleItemPosition();
235     }
236 
237     @Override
findFirstVisibleItemPosition()238     public int findFirstVisibleItemPosition() {
239         return mRecyclerView.findFirstVisibleItemPosition();
240     }
241 
242     @Override
findLastCompletelyVisibleItemPosition()243     public int findLastCompletelyVisibleItemPosition() {
244         return mRecyclerView.findLastVisibleItemPosition();
245     }
246 
247     @Override
findLastVisibleItemPosition()248     public int findLastVisibleItemPosition() {
249         return mRecyclerView.findLastVisibleItemPosition();
250     }
251 
252     @Override
getScrollState()253     public int getScrollState() {
254         return toInternalScrollState(mRecyclerView.getScrollState());
255     }
256 
257     @Override
setContentDescription(CharSequence charSequence)258     public void setContentDescription(CharSequence charSequence) {
259         mRecyclerView.setContentDescription(charSequence);
260     }
261 
262     @Override
setAlpha(float v)263     public void setAlpha(float v) {
264         mRecyclerView.setAlpha(v);
265     }
266 
267     @Override
getEndAfterPadding()268     public int getEndAfterPadding() {
269         return mRecyclerView.getEndAfterPadding();
270     }
271 
272     @Override
getStartAfterPadding()273     public int getStartAfterPadding() {
274         return mRecyclerView.getStartAfterPadding();
275     }
276 
277     @Override
getTotalSpace()278     public int getTotalSpace() {
279         return mRecyclerView.getTotalSpace();
280     }
281 
282     @Override
getRecyclerViewChildCount()283     public int getRecyclerViewChildCount() {
284         return mRecyclerView.getRecyclerViewChildCount();
285     }
286 
287     @Override
getRecyclerViewChildAt(int i)288     public View getRecyclerViewChildAt(int i) {
289         return mRecyclerView.getRecyclerViewChildAt(i);
290     }
291 
292     @Override
getRecyclerViewChildPosition(View view)293     public int getRecyclerViewChildPosition(View view) {
294         return mRecyclerView.getRecyclerViewChildPosition(view);
295     }
296 
297     @Override
findViewHolderForAdapterPosition(int position)298     public ViewHolderOEMV1 findViewHolderForAdapterPosition(int position) {
299         ViewHolder viewHolder = mRecyclerView.findViewHolderForAdapterPosition(position);
300         if (viewHolder instanceof RVAdapterWrapper.ViewHolderWrapper) {
301             return ((RVAdapterWrapper.ViewHolderWrapper) viewHolder).getViewHolder();
302         }
303         return null;
304     }
305 
306     @Override
findViewHolderForLayoutPosition(int position)307     public ViewHolderOEMV1 findViewHolderForLayoutPosition(int position) {
308         ViewHolder viewHolder = mRecyclerView.findViewHolderForLayoutPosition(position);
309         if (viewHolder instanceof RVAdapterWrapper.ViewHolderWrapper) {
310             return ((RVAdapterWrapper.ViewHolderWrapper) viewHolder).getViewHolder();
311         }
312         return null;
313     }
314 
315     @Override
addOnChildAttachStateChangeListener( OnChildAttachStateChangeListenerOEMV1 listener)316     public void addOnChildAttachStateChangeListener(
317             OnChildAttachStateChangeListenerOEMV1 listener) {
318         if (listener == null) {
319             return;
320         }
321         if (mOnChildAttachStateChangeListeners.isEmpty()) {
322             mRecyclerView.addOnChildAttachStateChangeListener(mOnChildAttachStateChangeListener);
323         }
324         mOnChildAttachStateChangeListeners.add(listener);
325     }
326 
327     @Override
removeOnChildAttachStateChangeListener( OnChildAttachStateChangeListenerOEMV1 listener)328     public void removeOnChildAttachStateChangeListener(
329             OnChildAttachStateChangeListenerOEMV1 listener) {
330         if (listener == null) {
331             return;
332         }
333         mOnChildAttachStateChangeListeners.remove(listener);
334         if (mOnChildAttachStateChangeListeners.isEmpty()) {
335             mRecyclerView.removeOnChildAttachStateChangeListener(mOnChildAttachStateChangeListener);
336         }
337     }
338 
339     @Override
clearOnChildAttachStateChangeListener()340     public void clearOnChildAttachStateChangeListener() {
341         if (!mOnChildAttachStateChangeListeners.isEmpty()) {
342             mOnChildAttachStateChangeListeners.clear();
343             mRecyclerView.clearOnChildAttachStateChangeListeners();
344         }
345     }
346 
347     @Override
getChildLayoutPosition(View view)348     public int getChildLayoutPosition(View view) {
349         return mRecyclerView.getChildLayoutPosition(view);
350     }
351 
352     @Override
getDecoratedStart(View view)353     public int getDecoratedStart(View view) {
354         return mRecyclerView.getDecoratedStart(view);
355     }
356 
357     @Override
getDecoratedEnd(View view)358     public int getDecoratedEnd(View view) {
359         return mRecyclerView.getDecoratedEnd(view);
360     }
361 
362     @Override
getDecoratedMeasuredHeight(View view)363     public int getDecoratedMeasuredHeight(View view) {
364         return mRecyclerView.getDecoratedMeasuredHeight(view);
365     }
366 
367     @Override
getDecoratedMeasuredWidth(View view)368     public int getDecoratedMeasuredWidth(View view) {
369         return mRecyclerView.getDecoratedMeasuredWidth(view);
370     }
371 
372     @Override
getDecoratedMeasurementInOther(View view)373     public int getDecoratedMeasurementInOther(View view) {
374         return mRecyclerView.getDecoratedMeasurementInOther(view);
375     }
376 
377     @Override
getDecoratedMeasurement(View view)378     public int getDecoratedMeasurement(View view) {
379         return mRecyclerView.getDecoratedMeasurement(view);
380     }
381 
382     @Override
findViewByPosition(int i)383     public View findViewByPosition(int i) {
384         return mRecyclerView.findViewByPosition(i);
385     }
386 
387     @Override
isComputingLayout()388     public boolean isComputingLayout() {
389         return !mRecyclerView.isLayoutCompleted();
390     }
391 
392     @Override
addOnLayoutCompleteListener(@ullable Runnable runnable)393     public void addOnLayoutCompleteListener(@Nullable Runnable runnable) {
394         mRecyclerView.addOnLayoutCompleteListener(runnable);
395     }
396 
397     @Override
removeOnLayoutCompleteListener(@ullable Runnable runnable)398     public void removeOnLayoutCompleteListener(@Nullable Runnable runnable) {
399         mRecyclerView.removeOnLayoutCompleteListener(runnable);
400     }
401 
402     @Override
scrollToPositionWithOffset(int i, int i1)403     public void scrollToPositionWithOffset(int i, int i1) {
404         mRecyclerView.scrollToPositionWithOffset(i, i1);
405     }
406 }
407