18faffcd819c6272f9e6537d563c8492854787968Chris Craik/*
28faffcd819c6272f9e6537d563c8492854787968Chris Craik * Copyright (C) 2016 The Android Open Source Project
38faffcd819c6272f9e6537d563c8492854787968Chris Craik *
48faffcd819c6272f9e6537d563c8492854787968Chris Craik * Licensed under the Apache License, Version 2.0 (the "License");
58faffcd819c6272f9e6537d563c8492854787968Chris Craik * you may not use this file except in compliance with the License.
68faffcd819c6272f9e6537d563c8492854787968Chris Craik * You may obtain a copy of the License at
78faffcd819c6272f9e6537d563c8492854787968Chris Craik *
88faffcd819c6272f9e6537d563c8492854787968Chris Craik *      http://www.apache.org/licenses/LICENSE-2.0
98faffcd819c6272f9e6537d563c8492854787968Chris Craik *
108faffcd819c6272f9e6537d563c8492854787968Chris Craik * Unless required by applicable law or agreed to in writing, software
118faffcd819c6272f9e6537d563c8492854787968Chris Craik * distributed under the License is distributed on an "AS IS" BASIS,
128faffcd819c6272f9e6537d563c8492854787968Chris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138faffcd819c6272f9e6537d563c8492854787968Chris Craik * See the License for the specific language governing permissions and
148faffcd819c6272f9e6537d563c8492854787968Chris Craik * limitations under the License.
158faffcd819c6272f9e6537d563c8492854787968Chris Craik */
168faffcd819c6272f9e6537d563c8492854787968Chris Craik
178faffcd819c6272f9e6537d563c8492854787968Chris Craikpackage com.example.android.supportv7.widget;
188faffcd819c6272f9e6537d563c8492854787968Chris Craik
198faffcd819c6272f9e6537d563c8492854787968Chris Craikimport android.graphics.Color;
201e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craikimport android.os.Parcelable;
21def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport android.view.LayoutInflater;
22def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport android.view.ViewGroup;
23def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport android.widget.TextView;
24def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikas
25ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.annotation.NonNull;
26ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.recyclerview.widget.DividerItemDecoration;
27ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.recyclerview.widget.LinearLayoutManager;
28ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.recyclerview.widget.RecyclerView;
298faffcd819c6272f9e6537d563c8492854787968Chris Craik
308faffcd819c6272f9e6537d563c8492854787968Chris Craikimport com.example.android.supportv7.Cheeses;
318faffcd819c6272f9e6537d563c8492854787968Chris Craikimport com.example.android.supportv7.R;
328faffcd819c6272f9e6537d563c8492854787968Chris Craik
338faffcd819c6272f9e6537d563c8492854787968Chris Craikimport java.util.ArrayList;
348faffcd819c6272f9e6537d563c8492854787968Chris Craikimport java.util.Arrays;
358faffcd819c6272f9e6537d563c8492854787968Chris Craik
368faffcd819c6272f9e6537d563c8492854787968Chris Craik/**
378faffcd819c6272f9e6537d563c8492854787968Chris Craik * A sample nested RecyclerView activity.
388faffcd819c6272f9e6537d563c8492854787968Chris Craik */
398faffcd819c6272f9e6537d563c8492854787968Chris Craikpublic class NestedRecyclerViewActivity extends BaseLayoutManagerActivity<LinearLayoutManager> {
408faffcd819c6272f9e6537d563c8492854787968Chris Craik    @Override
418faffcd819c6272f9e6537d563c8492854787968Chris Craik    protected LinearLayoutManager createLayoutManager() {
428faffcd819c6272f9e6537d563c8492854787968Chris Craik        return new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
438faffcd819c6272f9e6537d563c8492854787968Chris Craik    }
448faffcd819c6272f9e6537d563c8492854787968Chris Craik
458faffcd819c6272f9e6537d563c8492854787968Chris Craik    @Override
468faffcd819c6272f9e6537d563c8492854787968Chris Craik    protected void onRecyclerViewInit(RecyclerView recyclerView) {
478faffcd819c6272f9e6537d563c8492854787968Chris Craik        recyclerView.addItemDecoration(
488faffcd819c6272f9e6537d563c8492854787968Chris Craik                new DividerItemDecoration(this, mLayoutManager.getOrientation()));
498faffcd819c6272f9e6537d563c8492854787968Chris Craik    }
508faffcd819c6272f9e6537d563c8492854787968Chris Craik
518faffcd819c6272f9e6537d563c8492854787968Chris Craik    static class InnerAdapter extends RecyclerView.Adapter<InnerAdapter.ViewHolder> {
528faffcd819c6272f9e6537d563c8492854787968Chris Craik        public static class ViewHolder extends RecyclerView.ViewHolder {
531e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik            TextView mTextView;
548faffcd819c6272f9e6537d563c8492854787968Chris Craik
558faffcd819c6272f9e6537d563c8492854787968Chris Craik            public ViewHolder(TextView itemView) {
568faffcd819c6272f9e6537d563c8492854787968Chris Craik                super(itemView);
578faffcd819c6272f9e6537d563c8492854787968Chris Craik                mTextView = itemView;
588faffcd819c6272f9e6537d563c8492854787968Chris Craik            }
598faffcd819c6272f9e6537d563c8492854787968Chris Craik        }
608faffcd819c6272f9e6537d563c8492854787968Chris Craik
618faffcd819c6272f9e6537d563c8492854787968Chris Craik        private String[] mData;
628faffcd819c6272f9e6537d563c8492854787968Chris Craik
631e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik        InnerAdapter(String[] data) {
648faffcd819c6272f9e6537d563c8492854787968Chris Craik            mData = data;
658faffcd819c6272f9e6537d563c8492854787968Chris Craik        }
668faffcd819c6272f9e6537d563c8492854787968Chris Craik
678faffcd819c6272f9e6537d563c8492854787968Chris Craik        @Override
688faffcd819c6272f9e6537d563c8492854787968Chris Craik        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
698faffcd819c6272f9e6537d563c8492854787968Chris Craik            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
708faffcd819c6272f9e6537d563c8492854787968Chris Craik            TextView textView = (TextView) inflater.inflate(R.layout.nested_item, parent, false);
718faffcd819c6272f9e6537d563c8492854787968Chris Craik            textView.setMinimumWidth(300);
728faffcd819c6272f9e6537d563c8492854787968Chris Craik            textView.setMinimumHeight(300);
738faffcd819c6272f9e6537d563c8492854787968Chris Craik            return new ViewHolder(textView);
748faffcd819c6272f9e6537d563c8492854787968Chris Craik        }
758faffcd819c6272f9e6537d563c8492854787968Chris Craik
768faffcd819c6272f9e6537d563c8492854787968Chris Craik        @Override
778faffcd819c6272f9e6537d563c8492854787968Chris Craik        public void onBindViewHolder(ViewHolder holder, int position) {
788faffcd819c6272f9e6537d563c8492854787968Chris Craik            holder.mTextView.setText(mData[position]);
798faffcd819c6272f9e6537d563c8492854787968Chris Craik            boolean even = position % 2 == 0;
808faffcd819c6272f9e6537d563c8492854787968Chris Craik            holder.mTextView.setBackgroundColor(even ? Color.TRANSPARENT : 0x2fffffff);
818faffcd819c6272f9e6537d563c8492854787968Chris Craik        }
828faffcd819c6272f9e6537d563c8492854787968Chris Craik
838faffcd819c6272f9e6537d563c8492854787968Chris Craik        @Override
848faffcd819c6272f9e6537d563c8492854787968Chris Craik        public int getItemCount() {
858faffcd819c6272f9e6537d563c8492854787968Chris Craik            return mData.length;
868faffcd819c6272f9e6537d563c8492854787968Chris Craik        }
878faffcd819c6272f9e6537d563c8492854787968Chris Craik    }
888faffcd819c6272f9e6537d563c8492854787968Chris Craik
898faffcd819c6272f9e6537d563c8492854787968Chris Craik    static class OuterAdapter extends RecyclerView.Adapter<OuterAdapter.ViewHolder> {
908faffcd819c6272f9e6537d563c8492854787968Chris Craik        public static class ViewHolder extends RecyclerView.ViewHolder {
918faffcd819c6272f9e6537d563c8492854787968Chris Craik            private final RecyclerView mRecyclerView;
928faffcd819c6272f9e6537d563c8492854787968Chris Craik            public ViewHolder(RecyclerView itemView) {
938faffcd819c6272f9e6537d563c8492854787968Chris Craik                super(itemView);
948faffcd819c6272f9e6537d563c8492854787968Chris Craik                mRecyclerView = itemView;
958faffcd819c6272f9e6537d563c8492854787968Chris Craik            }
968faffcd819c6272f9e6537d563c8492854787968Chris Craik        }
978faffcd819c6272f9e6537d563c8492854787968Chris Craik
988faffcd819c6272f9e6537d563c8492854787968Chris Craik        ArrayList<InnerAdapter> mAdapters = new ArrayList<>();
991e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik        ArrayList<Parcelable> mSavedStates = new ArrayList<>();
1008faffcd819c6272f9e6537d563c8492854787968Chris Craik        RecyclerView.RecycledViewPool mSharedPool = new RecyclerView.RecycledViewPool();
1018faffcd819c6272f9e6537d563c8492854787968Chris Craik
1021e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik        OuterAdapter(String[] data) {
1038faffcd819c6272f9e6537d563c8492854787968Chris Craik            int currentCharIndex = 0;
1048faffcd819c6272f9e6537d563c8492854787968Chris Craik            char currentChar = data[0].charAt(0);
1058faffcd819c6272f9e6537d563c8492854787968Chris Craik            for (int i = 1; i <= data.length; i++) {
1068faffcd819c6272f9e6537d563c8492854787968Chris Craik                if (i == data.length || data[i].charAt(0) != currentChar) {
1078faffcd819c6272f9e6537d563c8492854787968Chris Craik                    mAdapters.add(new InnerAdapter(
1088faffcd819c6272f9e6537d563c8492854787968Chris Craik                            Arrays.copyOfRange(data, currentCharIndex, i - 1)));
1091e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik                    mSavedStates.add(null);
1108faffcd819c6272f9e6537d563c8492854787968Chris Craik                    if (i < data.length) {
1118faffcd819c6272f9e6537d563c8492854787968Chris Craik                        currentChar = data[i].charAt(0);
1128faffcd819c6272f9e6537d563c8492854787968Chris Craik                        currentCharIndex = i;
1138faffcd819c6272f9e6537d563c8492854787968Chris Craik                    }
1148faffcd819c6272f9e6537d563c8492854787968Chris Craik                }
1158faffcd819c6272f9e6537d563c8492854787968Chris Craik            }
1168faffcd819c6272f9e6537d563c8492854787968Chris Craik        }
1178faffcd819c6272f9e6537d563c8492854787968Chris Craik
1188faffcd819c6272f9e6537d563c8492854787968Chris Craik        @Override
1198faffcd819c6272f9e6537d563c8492854787968Chris Craik        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
1208faffcd819c6272f9e6537d563c8492854787968Chris Craik            RecyclerView rv = new RecyclerView(parent.getContext());
1218faffcd819c6272f9e6537d563c8492854787968Chris Craik            rv.setLayoutManager(new LinearLayoutManager(parent.getContext(),
1228faffcd819c6272f9e6537d563c8492854787968Chris Craik                    LinearLayoutManager.HORIZONTAL, false));
1238faffcd819c6272f9e6537d563c8492854787968Chris Craik            rv.setRecycledViewPool(mSharedPool);
1248faffcd819c6272f9e6537d563c8492854787968Chris Craik            return new ViewHolder(rv);
1258faffcd819c6272f9e6537d563c8492854787968Chris Craik        }
1268faffcd819c6272f9e6537d563c8492854787968Chris Craik
1278faffcd819c6272f9e6537d563c8492854787968Chris Craik        @Override
1288faffcd819c6272f9e6537d563c8492854787968Chris Craik        public void onBindViewHolder(ViewHolder holder, int position) {
1291e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik            // Note: would be equally valid to replace adapter content instead of swapping adapter
1300ceae57ee14da826c31a66c67e70f7f17108d5caChris Craik            holder.mRecyclerView.swapAdapter(mAdapters.get(position), true);
1311e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik
1321e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik            Parcelable savedState = mSavedStates.get(position);
1331e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik            if (savedState != null) {
1341e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik                holder.mRecyclerView.getLayoutManager().onRestoreInstanceState(savedState);
1351e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik                mSavedStates.set(position, null);
1361e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik            }
1371e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik        }
1381e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik
1391e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik        @Override
1408a11e6829c522aa1efcc903afa4c01d337082eabChris Craik        public void onViewRecycled(@NonNull ViewHolder holder) {
1411e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik            mSavedStates.set(holder.getAdapterPosition(),
1421e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik                    holder.mRecyclerView.getLayoutManager().onSaveInstanceState());
1438faffcd819c6272f9e6537d563c8492854787968Chris Craik        }
1448faffcd819c6272f9e6537d563c8492854787968Chris Craik
1458faffcd819c6272f9e6537d563c8492854787968Chris Craik        @Override
1468faffcd819c6272f9e6537d563c8492854787968Chris Craik        public int getItemCount() {
1478faffcd819c6272f9e6537d563c8492854787968Chris Craik            return mAdapters.size();
1488faffcd819c6272f9e6537d563c8492854787968Chris Craik        }
1498faffcd819c6272f9e6537d563c8492854787968Chris Craik    }
1508faffcd819c6272f9e6537d563c8492854787968Chris Craik
151e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas    @Override
1528faffcd819c6272f9e6537d563c8492854787968Chris Craik    protected RecyclerView.Adapter createAdapter() {
1538faffcd819c6272f9e6537d563c8492854787968Chris Craik        return new OuterAdapter(Cheeses.sCheeseStrings);
1548faffcd819c6272f9e6537d563c8492854787968Chris Craik    }
1558faffcd819c6272f9e6537d563c8492854787968Chris Craik}
156