1b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam/* 2b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * Copyright (C) 2015 The Android Open Source Project 3b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * 4b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * Licensed under the Apache License, Version 2.0 (the "License"); 5b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * you may not use this file except in compliance with the License. 6b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * You may obtain a copy of the License at 7b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * 8b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * http://www.apache.org/licenses/LICENSE-2.0 9b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * 10b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * Unless required by applicable law or agreed to in writing, software 11b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * distributed under the License is distributed on an "AS IS" BASIS, 12b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * See the License for the specific language governing permissions and 14b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * limitations under the License. 15b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam */ 16b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 17b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lampackage com.android.setupwizardlib.view; 18b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 19b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport android.content.Context; 20b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport android.content.res.TypedArray; 21b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport android.os.Build; 22b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport android.support.v7.widget.RecyclerView; 23b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport android.util.AttributeSet; 24b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport android.view.LayoutInflater; 25b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport android.view.View; 26b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport android.view.ViewGroup; 27b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport android.view.accessibility.AccessibilityEvent; 28b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 295a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lamimport com.android.setupwizardlib.DividerItemDecoration; 30b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport com.android.setupwizardlib.R; 31b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport com.android.setupwizardlib.annotations.VisibleForTesting; 32b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 33b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam/** 34b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * A RecyclerView that can display a header item at the start of the list. The header can be set by 35b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * {@code app:suwHeader} in XML. Note that the header will not be inflated until a layout manager 36b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * is set. 37b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam */ 38b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lampublic class HeaderRecyclerView extends RecyclerView { 39b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 405a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam private static class HeaderViewHolder extends ViewHolder 415a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam implements DividerItemDecoration.DividedViewHolder { 42b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 43b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public HeaderViewHolder(View itemView) { 44b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam super(itemView); 45b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 465a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam 475a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam @Override 485a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam public boolean isDividerAllowedAbove() { 495a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam return false; 505a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam } 515a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam 525a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam @Override 535a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam public boolean isDividerAllowedBelow() { 545a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam return false; 555a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam } 56b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 57b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 58b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam /** 59b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * An adapter that can optionally add one header item to the RecyclerView. 60b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam */ 61b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public static class HeaderAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { 62b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 635a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam private static final int HEADER_VIEW_TYPE = Integer.MAX_VALUE; 645a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam 65b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam private RecyclerView.Adapter mAdapter; 66b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam private View mHeader; 675a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam 685a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam private final AdapterDataObserver mObserver = new AdapterDataObserver() { 695a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam 705a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam @Override 715a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam public void onChanged() { 725a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam notifyDataSetChanged(); 735a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam } 745a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam 755a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam @Override 765a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam public void onItemRangeChanged(int positionStart, int itemCount) { 775a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam notifyItemRangeChanged(positionStart, itemCount); 785a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam } 795a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam 805a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam @Override 815a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam public void onItemRangeInserted(int positionStart, int itemCount) { 825a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam notifyItemRangeInserted(positionStart, itemCount); 835a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam } 845a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam 855a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam @Override 865a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) { 875a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam // Why is there no notifyItemRangeMoved? 885a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam notifyDataSetChanged(); 895a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam } 905a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam 915a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam @Override 925a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam public void onItemRangeRemoved(int positionStart, int itemCount) { 935a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam notifyItemRangeRemoved(positionStart, itemCount); 945a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam } 955a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam }; 96b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 97b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public HeaderAdapter(RecyclerView.Adapter adapter) { 98b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam mAdapter = adapter; 995a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam mAdapter.registerAdapterDataObserver(mObserver); 100b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam setHasStableIds(mAdapter.hasStableIds()); 101b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 102b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 103b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam @Override 104b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 105b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam if (viewType == HEADER_VIEW_TYPE) { 106b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam return new HeaderViewHolder(mHeader); 107b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } else { 108b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam return mAdapter.onCreateViewHolder(parent, viewType); 109b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 110b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 111b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 112b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam @Override 113b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam @SuppressWarnings("unchecked") 114b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public void onBindViewHolder(ViewHolder holder, int position) { 115b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam if (mHeader != null) { 116b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam position--; 117b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 118b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam if (position >= 0) { 119b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam mAdapter.onBindViewHolder(holder, position); 120b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 121b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 122b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 123b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam @Override 124b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public int getItemViewType(int position) { 125b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam if (mHeader != null) { 126b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam position--; 127b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 128b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam if (position < 0) { 129b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam return HEADER_VIEW_TYPE; 130b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 131b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam return mAdapter.getItemViewType(position); 132b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 133b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 134b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam @Override 135b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public int getItemCount() { 136b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam int count = mAdapter.getItemCount(); 137b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam if (mHeader != null) { 138b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam count++; 139b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 140b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam return count; 141b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 142b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 143b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam @Override 144b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public long getItemId(int position) { 145b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam if (mHeader != null) { 146b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam position--; 147b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 148b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam if (position < 0) { 149b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam return Long.MAX_VALUE; 150b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 151b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam return mAdapter.getItemId(position); 152b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 153b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 154b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public void setHeader(View header) { 155b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam mHeader = header; 156b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 157b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 158b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam @VisibleForTesting 159b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public RecyclerView.Adapter getWrappedAdapter() { 160b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam return mAdapter; 161b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 162b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 163b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 164b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam private View mHeader; 165b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam private int mHeaderRes; 166b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 167b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public HeaderRecyclerView(Context context) { 168b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam super(context); 169b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam init(null, 0); 170b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 171b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 172b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public HeaderRecyclerView(Context context, AttributeSet attrs) { 173b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam super(context, attrs); 174b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam init(attrs, 0); 175b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 176b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 177b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public HeaderRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) { 178b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam super(context, attrs, defStyleAttr); 179b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam init(attrs, defStyleAttr); 180b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 181b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 182b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam private void init(AttributeSet attrs, int defStyleAttr) { 183b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam final TypedArray a = getContext().obtainStyledAttributes(attrs, 184b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam R.styleable.SuwHeaderRecyclerView, defStyleAttr, 0); 185b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam mHeaderRes = a.getResourceId(R.styleable.SuwHeaderRecyclerView_suwHeader, 0); 186b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam a.recycle(); 187b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 188b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 189b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam @Override 190b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public void onInitializeAccessibilityEvent(AccessibilityEvent event) { 191b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam super.onInitializeAccessibilityEvent(event); 192b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 193b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam // Decoration-only headers should not count as an item for accessibility, adjust the 194b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam // accessibility event to account for that. 195b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam final int numberOfHeaders = mHeader != null ? 1 : 0; 196b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam event.setItemCount(event.getItemCount() - numberOfHeaders); 197b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam event.setFromIndex(Math.max(event.getFromIndex() - numberOfHeaders, 0)); 198b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 199b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam event.setToIndex(Math.max(event.getToIndex() - numberOfHeaders, 0)); 200b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 201b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 202b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 203b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam /** 204b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * Gets the header view of this RecyclerView, or {@code null} if there are no headers. 205b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam */ 206b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public View getHeader() { 207b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam return mHeader; 208b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 209b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 21038a3832bf55aeb5dc24904d4d1ddf391dffa7d7bMaurice Lam /** 21138a3832bf55aeb5dc24904d4d1ddf391dffa7d7bMaurice Lam * Set the view to use as the header of this recycler view. 21238a3832bf55aeb5dc24904d4d1ddf391dffa7d7bMaurice Lam * Note: This must be called before setAdapter. 21338a3832bf55aeb5dc24904d4d1ddf391dffa7d7bMaurice Lam */ 21438a3832bf55aeb5dc24904d4d1ddf391dffa7d7bMaurice Lam public void setHeader(View header) { 21538a3832bf55aeb5dc24904d4d1ddf391dffa7d7bMaurice Lam mHeader = header; 21638a3832bf55aeb5dc24904d4d1ddf391dffa7d7bMaurice Lam } 21738a3832bf55aeb5dc24904d4d1ddf391dffa7d7bMaurice Lam 218b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam @Override 219b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public void setLayoutManager(LayoutManager layout) { 220b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam super.setLayoutManager(layout); 221b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam if (layout != null && mHeader == null && mHeaderRes != 0) { 222b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam // Inflating a child view requires the layout manager to be set. Check here to see if 223b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam // any header item is specified in XML and inflate them. 224b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam final LayoutInflater inflater = LayoutInflater.from(getContext()); 225b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam mHeader = inflater.inflate(mHeaderRes, this, false); 226b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 227b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 228b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 229b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam @Override 230b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public void setAdapter(Adapter adapter) { 231b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam if (mHeader != null && adapter != null) { 232b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam final HeaderAdapter headerAdapter = new HeaderAdapter(adapter); 233b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam headerAdapter.setHeader(mHeader); 234b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam adapter = headerAdapter; 235b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 236b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam super.setAdapter(adapter); 237b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 238b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam} 239