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