1 /*
2  * Copyright (C) 2020 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.rotaryplayground;
18 
19 import android.content.Context;
20 import android.os.Bundle;
21 import android.view.LayoutInflater;
22 import android.view.View;
23 import android.view.ViewGroup;
24 import android.widget.TextView;
25 
26 import androidx.annotation.NonNull;
27 import androidx.annotation.Nullable;
28 import androidx.fragment.app.Fragment;
29 import androidx.recyclerview.widget.LinearLayoutManager;
30 import androidx.recyclerview.widget.RecyclerView;
31 
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.List;
35 
36 /** Fragment to demo scrolling with CarRecyclerView. */
37 public class ScrollFragment extends Fragment {
38 
39     // Item types
40     private static final int TYPE_BUTTONS = 1;
41     private static final int TYPE_TEXT = 2;
42 
43     private View mScrollView;
44 
45     @Override
onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)46     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
47             @Nullable Bundle savedInstanceState) {
48         mScrollView = inflater.inflate(R.layout.rotary_scroll, container, false);
49         initView();
50         return mScrollView;
51     }
52 
initView()53     private void initView() {
54         List<ScrollListItem> items = new ArrayList<>();
55 
56         // List of height for items to be added to the demo.
57         // 0 indicates focusable buttons inflated by R.layout.rotary_scroll.button.
58         // Values > 0 indiciates non-focusable texts inflated by R.layout.rotary_scroll_text.
59         final int[] itemHeights = getResources().getIntArray(R.array.scroll_item_heights);
60 
61         for (int height : itemHeights) {
62             if (height < 0) {
63                 continue;
64             }
65             ScrollListItem item = (height == 0)
66                     ? ScrollListItem.createButtonsItem()
67                     : ScrollListItem.createTextItemWithHeight(height);
68             items.add(item);
69         }
70 
71         // Set adapter
72         Context context = getContext();
73         ScrollListItemAdapter adapter = new ScrollListItemAdapter(context, items);
74         RecyclerView view = (RecyclerView) mScrollView.findViewById(R.id.rotary_scroll_view);
75         view.setAdapter(adapter);
76     }
77 
78     /** The adapter used by RotaryScroll to render ScrollListItems. */
79     private static class ScrollListItemAdapter extends
80             RecyclerView.Adapter<RecyclerView.ViewHolder> {
81 
82         final Context mContext;
83         final List<ScrollListItem> mItems;
84 
ScrollListItemAdapter(Context context, List<ScrollListItem> items)85         ScrollListItemAdapter(Context context, List<ScrollListItem> items) {
86             this.mContext = context;
87             this.mItems = items;
88         }
89 
90         @NonNull
91         @Override
onCreateViewHolder( @onNull ViewGroup viewGroup, int viewType)92         public RecyclerView.ViewHolder onCreateViewHolder(
93                 @NonNull ViewGroup viewGroup, int viewType) {
94             View view;
95             switch (viewType) {
96                 case TYPE_BUTTONS:
97                     view = LayoutInflater.from(mContext).inflate(
98                             R.layout.rotary_scroll_button, viewGroup, false);
99                     return new RecyclerView.ViewHolder(view) {};
100 
101                 case TYPE_TEXT:
102                     view = LayoutInflater.from(mContext).inflate(
103                             R.layout.rotary_scroll_text, viewGroup, false);
104                     return new ScrollTextHolder(view);
105 
106                 default:
107                     throw new IllegalArgumentException("Unexpected viewType: " + viewType);
108             }
109         }
110 
111         @Override
getItemViewType(int position)112         public int getItemViewType(int position) {
113             return mItems.get(position).getType();
114         }
115 
116         @Override
onBindViewHolder(@onNull RecyclerView.ViewHolder viewHolder, int position)117         public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
118             if (getItemViewType(position) == TYPE_TEXT) {
119                 ((ScrollTextHolder) viewHolder).setHeight(mItems.get(position).getHeight());
120             }
121         }
122 
123         @Override
getItemCount()124         public int getItemCount() {
125             return mItems.size();
126         }
127     }
128 
129     /** A ViewHolder for non-focusable ScrollListItems */
130     private static class ScrollTextHolder extends RecyclerView.ViewHolder {
131 
132         @NonNull
133         final TextView mScrollTextView;
134 
ScrollTextHolder(@onNull View itemView)135         ScrollTextHolder(@NonNull View itemView) {
136             super(itemView);
137             mScrollTextView = itemView.findViewById(R.id.scroll_text_view);
138         }
139 
setHeight(int height)140         void setHeight(int height) {
141             mScrollTextView.setHeight(height);
142         }
143     }
144 
145     private static class ScrollListItem {
146 
147         final int mHeight;
148         final int mType;
149 
createTextItemWithHeight(int height)150         static ScrollListItem createTextItemWithHeight(int height) {
151           return new ScrollListItem(TYPE_TEXT, height);
152         }
createButtonsItem()153         static ScrollListItem createButtonsItem() {
154           return new ScrollListItem(TYPE_BUTTONS, 0);
155         }
156 
ScrollListItem(int type, int height)157         ScrollListItem(int type, int height) {
158             this.mType = type;
159             this.mHeight = height;
160         }
161 
getHeight()162         int getHeight() {
163             return mHeight;
164         }
165 
getType()166         int getType() {
167             return mType;
168         }
169     }
170 }
171