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