1a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam/* 2a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam * Copyright (C) 2015 The Android Open Source Project 3a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam * 4a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam * Licensed under the Apache License, Version 2.0 (the "License"); 5a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam * you may not use this file except in compliance with the License. 6a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam * You may obtain a copy of the License at 7a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam * 8a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam * http://www.apache.org/licenses/LICENSE-2.0 9a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam * 10a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam * Unless required by applicable law or agreed to in writing, software 11a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam * distributed under the License is distributed on an "AS IS" BASIS, 12a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam * See the License for the specific language governing permissions and 14a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam * limitations under the License. 15a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam */ 16a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam 17a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lampackage com.android.setupwizardlib.items; 18a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam 19a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lamimport android.content.res.TypedArray; 205d7bea799d0a1231f16b9e975718035c786da5f3Maurice Lamimport android.graphics.drawable.Drawable; 215d7bea799d0a1231f16b9e975718035c786da5f3Maurice Lamimport android.graphics.drawable.LayerDrawable; 22a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lamimport android.support.v7.widget.RecyclerView; 235d7bea799d0a1231f16b9e975718035c786da5f3Maurice Lamimport android.util.Log; 24a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lamimport android.view.LayoutInflater; 25a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lamimport android.view.View; 26a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lamimport android.view.ViewGroup; 275d7bea799d0a1231f16b9e975718035c786da5f3Maurice Lam 28a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lamimport com.android.setupwizardlib.R; 29a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam 30a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam/** 31a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam * An adapter used with RecyclerView to display an {@link ItemHierarchy}. The item hierarchy used to 32a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam * create this adapter can be inflated by {@link com.android.setupwizardlib.items.ItemInflater} from 33a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam * XML. 34a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam */ 35180360409c9e4e9163c670ff48663244b4057eafMaurice Lampublic class RecyclerItemAdapter extends RecyclerView.Adapter<ItemViewHolder> 36a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam implements ItemHierarchy.Observer { 37a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam 385d7bea799d0a1231f16b9e975718035c786da5f3Maurice Lam private static final String TAG = "RecyclerItemAdapter"; 39a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam 40a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam public interface OnItemSelectedListener { 41a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam void onItemSelected(IItem item); 42a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam } 43a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam 44a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam private final ItemHierarchy mItemHierarchy; 45a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam private OnItemSelectedListener mListener; 46a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam 47a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam public RecyclerItemAdapter(ItemHierarchy hierarchy) { 48a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam mItemHierarchy = hierarchy; 49a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam mItemHierarchy.registerObserver(this); 50a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam } 51a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam 52a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam public IItem getItem(int position) { 53a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam return mItemHierarchy.getItemAt(position); 54a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam } 55a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam 56a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam @Override 57a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam public long getItemId(int position) { 58a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam IItem mItem = getItem(position); 59a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam if (mItem instanceof AbstractItem) { 60b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam final int id = ((AbstractItem) mItem).getId(); 61b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam return id > 0 ? id : RecyclerView.NO_ID; 62a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam } else { 63a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam return RecyclerView.NO_ID; 64a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam } 65a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam } 66a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam 67a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam @Override 68a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam public int getItemCount() { 69a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam return mItemHierarchy.getCount(); 70a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam } 71a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam 72a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam @Override 73180360409c9e4e9163c670ff48663244b4057eafMaurice Lam public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 74a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam final LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 75a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam final View view = inflater.inflate(viewType, parent, false); 76180360409c9e4e9163c670ff48663244b4057eafMaurice Lam final ItemViewHolder viewHolder = new ItemViewHolder(view); 77a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam 78a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam final TypedArray typedArray = parent.getContext() 795d7bea799d0a1231f16b9e975718035c786da5f3Maurice Lam .obtainStyledAttributes(R.styleable.SuwRecyclerItemAdapter); 805d7bea799d0a1231f16b9e975718035c786da5f3Maurice Lam Drawable selectableItemBackground = typedArray.getDrawable( 815d7bea799d0a1231f16b9e975718035c786da5f3Maurice Lam R.styleable.SuwRecyclerItemAdapter_android_selectableItemBackground); 825d7bea799d0a1231f16b9e975718035c786da5f3Maurice Lam if (selectableItemBackground == null) { 835d7bea799d0a1231f16b9e975718035c786da5f3Maurice Lam selectableItemBackground = typedArray.getDrawable( 845d7bea799d0a1231f16b9e975718035c786da5f3Maurice Lam R.styleable.SuwRecyclerItemAdapter_selectableItemBackground); 855d7bea799d0a1231f16b9e975718035c786da5f3Maurice Lam } 86bb8f21ea108666cc962b016a7664b5f500c63ff3Ajay Nadathur 875d7bea799d0a1231f16b9e975718035c786da5f3Maurice Lam final Drawable background = typedArray.getDrawable( 885d7bea799d0a1231f16b9e975718035c786da5f3Maurice Lam R.styleable.SuwRecyclerItemAdapter_android_colorBackground); 895d7bea799d0a1231f16b9e975718035c786da5f3Maurice Lam 905d7bea799d0a1231f16b9e975718035c786da5f3Maurice Lam if (selectableItemBackground == null || background == null) { 915d7bea799d0a1231f16b9e975718035c786da5f3Maurice Lam Log.e(TAG, "Cannot resolve required attributes." 925d7bea799d0a1231f16b9e975718035c786da5f3Maurice Lam + " selectableItemBackground=" + selectableItemBackground 935d7bea799d0a1231f16b9e975718035c786da5f3Maurice Lam + " background=" + background); 94bb8f21ea108666cc962b016a7664b5f500c63ff3Ajay Nadathur } else { 955d7bea799d0a1231f16b9e975718035c786da5f3Maurice Lam final Drawable[] layers = { background, selectableItemBackground }; 965d7bea799d0a1231f16b9e975718035c786da5f3Maurice Lam view.setBackgroundDrawable(new LayerDrawable(layers)); 97bb8f21ea108666cc962b016a7664b5f500c63ff3Ajay Nadathur } 98bb8f21ea108666cc962b016a7664b5f500c63ff3Ajay Nadathur 99a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam typedArray.recycle(); 100a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam 101a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam view.setOnClickListener(new View.OnClickListener() { 102a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam @Override 103a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam public void onClick(View view) { 1045a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam final IItem item = viewHolder.getItem(); 1055a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam if (mListener != null && item != null && item.isEnabled()) { 1065a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam mListener.onItemSelected(item); 107a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam } 108a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam } 109a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam }); 110a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam 111a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam return viewHolder; 112a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam } 113a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam 114a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam @Override 115180360409c9e4e9163c670ff48663244b4057eafMaurice Lam public void onBindViewHolder(ItemViewHolder holder, int position) { 116a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam final IItem item = getItem(position); 117a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam item.onBindView(holder.itemView); 118180360409c9e4e9163c670ff48663244b4057eafMaurice Lam holder.setEnabled(item.isEnabled()); 1195a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam holder.setItem(item); 120a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam } 121a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam 122a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam @Override 123a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam public int getItemViewType(int position) { 124a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam // Use layout resource as item view type. RecyclerView item type does not have to be 125a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam // contiguous. 126a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam IItem item = getItem(position); 127a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam return item.getLayoutResource(); 128a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam } 129a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam 130a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam @Override 131a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam public void onChanged(ItemHierarchy hierarchy) { 132a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam notifyDataSetChanged(); 133a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam } 134a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam 135a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam public ItemHierarchy findItemById(int id) { 136a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam return mItemHierarchy.findItemById(id); 137a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam } 138a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam 139a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam public ItemHierarchy getRootItemHierarchy() { 140a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam return mItemHierarchy; 141a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam } 142a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam 143a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam public void setOnItemSelectedListener(OnItemSelectedListener listener) { 144a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam mListener = listener; 145a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam } 146a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam} 147