NestedRecyclerViewActivity.java revision 0ceae57ee14da826c31a66c67e70f7f17108d5ca
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;
218faffcd819c6272f9e6537d563c8492854787968Chris Craikimport android.support.v7.widget.DividerItemDecoration;
228faffcd819c6272f9e6537d563c8492854787968Chris Craikimport android.support.v7.widget.LinearLayoutManager;
238faffcd819c6272f9e6537d563c8492854787968Chris Craikimport android.support.v7.widget.RecyclerView;
248faffcd819c6272f9e6537d563c8492854787968Chris Craikimport android.view.LayoutInflater;
258faffcd819c6272f9e6537d563c8492854787968Chris Craikimport android.view.ViewGroup;
268faffcd819c6272f9e6537d563c8492854787968Chris Craikimport android.widget.TextView;
278faffcd819c6272f9e6537d563c8492854787968Chris Craik
288faffcd819c6272f9e6537d563c8492854787968Chris Craikimport com.example.android.supportv7.Cheeses;
298faffcd819c6272f9e6537d563c8492854787968Chris Craikimport com.example.android.supportv7.R;
308faffcd819c6272f9e6537d563c8492854787968Chris Craik
318faffcd819c6272f9e6537d563c8492854787968Chris Craikimport java.util.ArrayList;
328faffcd819c6272f9e6537d563c8492854787968Chris Craikimport java.util.Arrays;
338faffcd819c6272f9e6537d563c8492854787968Chris Craik
348faffcd819c6272f9e6537d563c8492854787968Chris Craik/**
358faffcd819c6272f9e6537d563c8492854787968Chris Craik * A sample nested RecyclerView activity.
368faffcd819c6272f9e6537d563c8492854787968Chris Craik */
378faffcd819c6272f9e6537d563c8492854787968Chris Craikpublic class NestedRecyclerViewActivity extends BaseLayoutManagerActivity<LinearLayoutManager> {
388faffcd819c6272f9e6537d563c8492854787968Chris Craik    @Override
398faffcd819c6272f9e6537d563c8492854787968Chris Craik    protected LinearLayoutManager createLayoutManager() {
408faffcd819c6272f9e6537d563c8492854787968Chris Craik        return new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
418faffcd819c6272f9e6537d563c8492854787968Chris Craik    }
428faffcd819c6272f9e6537d563c8492854787968Chris Craik
438faffcd819c6272f9e6537d563c8492854787968Chris Craik    @Override
448faffcd819c6272f9e6537d563c8492854787968Chris Craik    protected void onRecyclerViewInit(RecyclerView recyclerView) {
458faffcd819c6272f9e6537d563c8492854787968Chris Craik        recyclerView.addItemDecoration(
468faffcd819c6272f9e6537d563c8492854787968Chris Craik                new DividerItemDecoration(this, mLayoutManager.getOrientation()));
478faffcd819c6272f9e6537d563c8492854787968Chris Craik    }
488faffcd819c6272f9e6537d563c8492854787968Chris Craik
498faffcd819c6272f9e6537d563c8492854787968Chris Craik    static class InnerAdapter extends RecyclerView.Adapter<InnerAdapter.ViewHolder> {
508faffcd819c6272f9e6537d563c8492854787968Chris Craik        public static class ViewHolder extends RecyclerView.ViewHolder {
511e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik            TextView mTextView;
528faffcd819c6272f9e6537d563c8492854787968Chris Craik
538faffcd819c6272f9e6537d563c8492854787968Chris Craik            public ViewHolder(TextView itemView) {
548faffcd819c6272f9e6537d563c8492854787968Chris Craik                super(itemView);
558faffcd819c6272f9e6537d563c8492854787968Chris Craik                mTextView = itemView;
568faffcd819c6272f9e6537d563c8492854787968Chris Craik            }
578faffcd819c6272f9e6537d563c8492854787968Chris Craik        }
588faffcd819c6272f9e6537d563c8492854787968Chris Craik
598faffcd819c6272f9e6537d563c8492854787968Chris Craik        private String[] mData;
608faffcd819c6272f9e6537d563c8492854787968Chris Craik
611e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik        InnerAdapter(String[] data) {
628faffcd819c6272f9e6537d563c8492854787968Chris Craik            mData = data;
638faffcd819c6272f9e6537d563c8492854787968Chris Craik        }
648faffcd819c6272f9e6537d563c8492854787968Chris Craik
658faffcd819c6272f9e6537d563c8492854787968Chris Craik        @Override
668faffcd819c6272f9e6537d563c8492854787968Chris Craik        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
678faffcd819c6272f9e6537d563c8492854787968Chris Craik            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
688faffcd819c6272f9e6537d563c8492854787968Chris Craik            TextView textView = (TextView) inflater.inflate(R.layout.nested_item, parent, false);
698faffcd819c6272f9e6537d563c8492854787968Chris Craik            textView.setMinimumWidth(300);
708faffcd819c6272f9e6537d563c8492854787968Chris Craik            textView.setMinimumHeight(300);
718faffcd819c6272f9e6537d563c8492854787968Chris Craik            return new ViewHolder(textView);
728faffcd819c6272f9e6537d563c8492854787968Chris Craik        }
738faffcd819c6272f9e6537d563c8492854787968Chris Craik
748faffcd819c6272f9e6537d563c8492854787968Chris Craik        @Override
758faffcd819c6272f9e6537d563c8492854787968Chris Craik        public void onBindViewHolder(ViewHolder holder, int position) {
768faffcd819c6272f9e6537d563c8492854787968Chris Craik            holder.mTextView.setText(mData[position]);
778faffcd819c6272f9e6537d563c8492854787968Chris Craik            boolean even = position % 2 == 0;
788faffcd819c6272f9e6537d563c8492854787968Chris Craik            holder.mTextView.setBackgroundColor(even ? Color.TRANSPARENT : 0x2fffffff);
798faffcd819c6272f9e6537d563c8492854787968Chris Craik        }
808faffcd819c6272f9e6537d563c8492854787968Chris Craik
818faffcd819c6272f9e6537d563c8492854787968Chris Craik        @Override
828faffcd819c6272f9e6537d563c8492854787968Chris Craik        public int getItemCount() {
838faffcd819c6272f9e6537d563c8492854787968Chris Craik            return mData.length;
848faffcd819c6272f9e6537d563c8492854787968Chris Craik        }
858faffcd819c6272f9e6537d563c8492854787968Chris Craik    }
868faffcd819c6272f9e6537d563c8492854787968Chris Craik
878faffcd819c6272f9e6537d563c8492854787968Chris Craik    static class OuterAdapter extends RecyclerView.Adapter<OuterAdapter.ViewHolder> {
888faffcd819c6272f9e6537d563c8492854787968Chris Craik        public static class ViewHolder extends RecyclerView.ViewHolder {
898faffcd819c6272f9e6537d563c8492854787968Chris Craik            private final RecyclerView mRecyclerView;
908faffcd819c6272f9e6537d563c8492854787968Chris Craik            public ViewHolder(RecyclerView itemView) {
918faffcd819c6272f9e6537d563c8492854787968Chris Craik                super(itemView);
928faffcd819c6272f9e6537d563c8492854787968Chris Craik                mRecyclerView = itemView;
938faffcd819c6272f9e6537d563c8492854787968Chris Craik            }
948faffcd819c6272f9e6537d563c8492854787968Chris Craik        }
958faffcd819c6272f9e6537d563c8492854787968Chris Craik
968faffcd819c6272f9e6537d563c8492854787968Chris Craik        ArrayList<InnerAdapter> mAdapters = new ArrayList<>();
971e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik        ArrayList<Parcelable> mSavedStates = new ArrayList<>();
988faffcd819c6272f9e6537d563c8492854787968Chris Craik        RecyclerView.RecycledViewPool mSharedPool = new RecyclerView.RecycledViewPool();
998faffcd819c6272f9e6537d563c8492854787968Chris Craik
1001e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik        OuterAdapter(String[] data) {
1018faffcd819c6272f9e6537d563c8492854787968Chris Craik            int currentCharIndex = 0;
1028faffcd819c6272f9e6537d563c8492854787968Chris Craik            char currentChar = data[0].charAt(0);
1038faffcd819c6272f9e6537d563c8492854787968Chris Craik            for (int i = 1; i <= data.length; i++) {
1048faffcd819c6272f9e6537d563c8492854787968Chris Craik                if (i == data.length || data[i].charAt(0) != currentChar) {
1058faffcd819c6272f9e6537d563c8492854787968Chris Craik                    mAdapters.add(new InnerAdapter(
1068faffcd819c6272f9e6537d563c8492854787968Chris Craik                            Arrays.copyOfRange(data, currentCharIndex, i - 1)));
1071e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik                    mSavedStates.add(null);
1088faffcd819c6272f9e6537d563c8492854787968Chris Craik                    if (i < data.length) {
1098faffcd819c6272f9e6537d563c8492854787968Chris Craik                        currentChar = data[i].charAt(0);
1108faffcd819c6272f9e6537d563c8492854787968Chris Craik                        currentCharIndex = i;
1118faffcd819c6272f9e6537d563c8492854787968Chris Craik                    }
1128faffcd819c6272f9e6537d563c8492854787968Chris Craik                }
1138faffcd819c6272f9e6537d563c8492854787968Chris Craik            }
1148faffcd819c6272f9e6537d563c8492854787968Chris Craik        }
1158faffcd819c6272f9e6537d563c8492854787968Chris Craik
1168faffcd819c6272f9e6537d563c8492854787968Chris Craik        @Override
1178faffcd819c6272f9e6537d563c8492854787968Chris Craik        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
1188faffcd819c6272f9e6537d563c8492854787968Chris Craik            RecyclerView rv = new RecyclerView(parent.getContext());
1198faffcd819c6272f9e6537d563c8492854787968Chris Craik            rv.setLayoutManager(new LinearLayoutManager(parent.getContext(),
1208faffcd819c6272f9e6537d563c8492854787968Chris Craik                    LinearLayoutManager.HORIZONTAL, false));
1218faffcd819c6272f9e6537d563c8492854787968Chris Craik            rv.setRecycledViewPool(mSharedPool);
1228faffcd819c6272f9e6537d563c8492854787968Chris Craik            return new ViewHolder(rv);
1238faffcd819c6272f9e6537d563c8492854787968Chris Craik        }
1248faffcd819c6272f9e6537d563c8492854787968Chris Craik
1258faffcd819c6272f9e6537d563c8492854787968Chris Craik        @Override
1268faffcd819c6272f9e6537d563c8492854787968Chris Craik        public void onBindViewHolder(ViewHolder holder, int position) {
1271e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik            // Note: would be equally valid to replace adapter content instead of swapping adapter
1280ceae57ee14da826c31a66c67e70f7f17108d5caChris Craik            holder.mRecyclerView.swapAdapter(mAdapters.get(position), true);
1291e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik
1301e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik            Parcelable savedState = mSavedStates.get(position);
1311e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik            if (savedState != null) {
1321e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik                holder.mRecyclerView.getLayoutManager().onRestoreInstanceState(savedState);
1331e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik                mSavedStates.set(position, null);
1341e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik            }
1351e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik        }
1361e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik
1371e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik        @Override
1381e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik        public void onViewRecycled(ViewHolder holder) {
1391e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik            mSavedStates.set(holder.getAdapterPosition(),
1401e0a453dff8d7bb7a966d006541454c770d1ed05Chris Craik                    holder.mRecyclerView.getLayoutManager().onSaveInstanceState());
1418faffcd819c6272f9e6537d563c8492854787968Chris Craik        }
1428faffcd819c6272f9e6537d563c8492854787968Chris Craik
1438faffcd819c6272f9e6537d563c8492854787968Chris Craik        @Override
1448faffcd819c6272f9e6537d563c8492854787968Chris Craik        public int getItemCount() {
1458faffcd819c6272f9e6537d563c8492854787968Chris Craik            return mAdapters.size();
1468faffcd819c6272f9e6537d563c8492854787968Chris Craik        }
1478faffcd819c6272f9e6537d563c8492854787968Chris Craik    }
1488faffcd819c6272f9e6537d563c8492854787968Chris Craik
1498faffcd819c6272f9e6537d563c8492854787968Chris Craik    protected RecyclerView.Adapter createAdapter() {
1508faffcd819c6272f9e6537d563c8492854787968Chris Craik        return new OuterAdapter(Cheeses.sCheeseStrings);
1518faffcd819c6272f9e6537d563c8492854787968Chris Craik    }
1528faffcd819c6272f9e6537d563c8492854787968Chris Craik}
153