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