RecyclerItemAdapter.java revision bb8f21ea108666cc962b016a7664b5f500c63ff3
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;
20a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lamimport android.support.v7.widget.RecyclerView;
21a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lamimport android.view.LayoutInflater;
22a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lamimport android.view.View;
23a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lamimport android.view.ViewGroup;
249b4e2c4788f066d799af15e573c1dc78102fc0d0Ajay Nadathurimport android.graphics.drawable.LayerDrawable;
259b4e2c4788f066d799af15e573c1dc78102fc0d0Ajay Nadathurimport android.graphics.drawable.Drawable;
26a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lamimport com.android.setupwizardlib.R;
27a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam
28a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam/**
29a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam * An adapter used with RecyclerView to display an {@link ItemHierarchy}. The item hierarchy used to
30a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam * create this adapter can be inflated by {@link com.android.setupwizardlib.items.ItemInflater} from
31a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam * XML.
32a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam */
33180360409c9e4e9163c670ff48663244b4057eafMaurice Lampublic class RecyclerItemAdapter extends RecyclerView.Adapter<ItemViewHolder>
34a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        implements ItemHierarchy.Observer {
35a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam
36a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    private static final int[] SELECTABLE_ITEM_BACKGROUND = new int[] {
379b4e2c4788f066d799af15e573c1dc78102fc0d0Ajay Nadathur            R.attr.selectableItemBackground,
389b4e2c4788f066d799af15e573c1dc78102fc0d0Ajay Nadathur            android.R.attr.colorBackground
39a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    };
40a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam
41a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    public interface OnItemSelectedListener {
42a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        void onItemSelected(IItem item);
43a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    }
44a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam
45a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    private final ItemHierarchy mItemHierarchy;
46a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    private OnItemSelectedListener mListener;
47a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam
48a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    public RecyclerItemAdapter(ItemHierarchy hierarchy) {
49a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        mItemHierarchy = hierarchy;
50a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        mItemHierarchy.registerObserver(this);
51a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    }
52a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam
53a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    public IItem getItem(int position) {
54a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        return mItemHierarchy.getItemAt(position);
55a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    }
56a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam
57a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    @Override
58a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    public long getItemId(int position) {
59a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        IItem mItem = getItem(position);
60a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        if (mItem instanceof AbstractItem) {
61b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam            final int id = ((AbstractItem) mItem).getId();
62b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam            return id > 0 ? id : RecyclerView.NO_ID;
63a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        } else {
64a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam            return RecyclerView.NO_ID;
65a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        }
66a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    }
67a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam
68a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    @Override
69a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    public int getItemCount() {
70a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        return mItemHierarchy.getCount();
71a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    }
72a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam
73a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    @Override
74180360409c9e4e9163c670ff48663244b4057eafMaurice Lam    public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
75a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
76a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        final View view = inflater.inflate(viewType, parent, false);
77180360409c9e4e9163c670ff48663244b4057eafMaurice Lam        final ItemViewHolder viewHolder = new ItemViewHolder(view);
78a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam
79a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        final TypedArray typedArray = parent.getContext()
80a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam                .obtainStyledAttributes(SELECTABLE_ITEM_BACKGROUND);
81bb8f21ea108666cc962b016a7664b5f500c63ff3Ajay Nadathur        Drawable firstLayer = typedArray.getDrawable(0);
82bb8f21ea108666cc962b016a7664b5f500c63ff3Ajay Nadathur        Drawable secondLayer = typedArray.getDrawable(1);
83bb8f21ea108666cc962b016a7664b5f500c63ff3Ajay Nadathur
84bb8f21ea108666cc962b016a7664b5f500c63ff3Ajay Nadathur        if (firstLayer != null && secondLayer != null) {
85bb8f21ea108666cc962b016a7664b5f500c63ff3Ajay Nadathur            Drawable [] layers = new Drawable[] {secondLayer, firstLayer};
86bb8f21ea108666cc962b016a7664b5f500c63ff3Ajay Nadathur            view.setBackgroundDrawable(new LayerDrawable(layers));
87bb8f21ea108666cc962b016a7664b5f500c63ff3Ajay Nadathur        } else {
88bb8f21ea108666cc962b016a7664b5f500c63ff3Ajay Nadathur            view.setBackgroundDrawable(firstLayer);
89bb8f21ea108666cc962b016a7664b5f500c63ff3Ajay Nadathur        }
90bb8f21ea108666cc962b016a7664b5f500c63ff3Ajay Nadathur
91a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        typedArray.recycle();
92a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam
93a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        view.setOnClickListener(new View.OnClickListener() {
94a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam            @Override
95a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam            public void onClick(View view) {
965a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam                final IItem item = viewHolder.getItem();
975a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam                if (mListener != null && item != null && item.isEnabled()) {
985a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam                    mListener.onItemSelected(item);
99a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam                }
100a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam            }
101a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        });
102a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam
103a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        return viewHolder;
104a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    }
105a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam
106a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    @Override
107180360409c9e4e9163c670ff48663244b4057eafMaurice Lam    public void onBindViewHolder(ItemViewHolder holder, int position) {
108a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        final IItem item = getItem(position);
109a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        item.onBindView(holder.itemView);
110180360409c9e4e9163c670ff48663244b4057eafMaurice Lam        holder.setEnabled(item.isEnabled());
1115a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam        holder.setItem(item);
112a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    }
113a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam
114a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    @Override
115a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    public int getItemViewType(int position) {
116a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        // Use layout resource as item view type. RecyclerView item type does not have to be
117a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        // contiguous.
118a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        IItem item = getItem(position);
119a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        return item.getLayoutResource();
120a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    }
121a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam
122a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    @Override
123a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    public void onChanged(ItemHierarchy hierarchy) {
124a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        notifyDataSetChanged();
125a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    }
126a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam
127a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    public ItemHierarchy findItemById(int id) {
128a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        return mItemHierarchy.findItemById(id);
129a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    }
130a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam
131a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    public ItemHierarchy getRootItemHierarchy() {
132a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        return mItemHierarchy;
133a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    }
134a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam
135a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    public void setOnItemSelectedListener(OnItemSelectedListener listener) {
136a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam        mListener = listener;
137a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam    }
138a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2Maurice Lam}
139