1/*
2 * Copyright (C) 2011 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.layoutlib.bridge.impl.binding;
18
19import com.android.ide.common.rendering.api.AdapterBinding;
20import com.android.ide.common.rendering.api.DataBindingItem;
21import com.android.ide.common.rendering.api.IProjectCallback;
22import com.android.ide.common.rendering.api.ResourceReference;
23import com.android.util.Pair;
24
25import android.view.View;
26import android.view.ViewGroup;
27import android.widget.AdapterView;
28import android.widget.BaseAdapter;
29import android.widget.ListAdapter;
30import android.widget.SpinnerAdapter;
31
32import java.util.ArrayList;
33import java.util.List;
34
35/**
36 * Fake adapter to do fake data binding in {@link AdapterView} objects for {@link ListAdapter}
37 * and {@link SpinnerAdapter}.
38 *
39 */
40@SuppressWarnings("deprecation")
41public class FakeAdapter extends BaseAdapter {
42
43    // don't use a set because the order is important.
44    private final List<ResourceReference> mTypes = new ArrayList<ResourceReference>();
45    private final IProjectCallback mCallback;
46    private final ResourceReference mAdapterRef;
47    private final List<AdapterItem> mItems = new ArrayList<AdapterItem>();
48    private boolean mSkipCallbackParser = false;
49
50    public FakeAdapter(ResourceReference adapterRef, AdapterBinding binding,
51            IProjectCallback callback) {
52        mAdapterRef = adapterRef;
53        mCallback = callback;
54
55        final int repeatCount = binding.getRepeatCount();
56        final int itemCount = binding.getItemCount();
57
58        // Need an array to count for each type.
59        // This is likely too big, but is the max it can be.
60        int[] typeCount = new int[itemCount];
61
62        // We put several repeating sets.
63        for (int r = 0 ; r < repeatCount ; r++) {
64            // loop on the type of list items, and add however many for each type.
65            for (DataBindingItem dataBindingItem : binding) {
66                ResourceReference viewRef = dataBindingItem.getViewReference();
67                int typeIndex = mTypes.indexOf(viewRef);
68                if (typeIndex == -1) {
69                    typeIndex = mTypes.size();
70                    mTypes.add(viewRef);
71                }
72
73                int count = dataBindingItem.getCount();
74
75                int index = typeCount[typeIndex];
76                typeCount[typeIndex] += count;
77
78                for (int k = 0 ; k < count ; k++) {
79                    mItems.add(new AdapterItem(dataBindingItem, typeIndex, mItems.size(), index++));
80                }
81            }
82        }
83    }
84
85    @Override
86    public boolean isEnabled(int position) {
87        return true;
88    }
89
90    @Override
91    public int getCount() {
92        return mItems.size();
93    }
94
95    @Override
96    public Object getItem(int position) {
97        return mItems.get(position);
98    }
99
100    @Override
101    public long getItemId(int position) {
102        return position;
103    }
104
105    @Override
106    public int getItemViewType(int position) {
107        return mItems.get(position).getType();
108    }
109
110    @Override
111    public View getView(int position, View convertView, ViewGroup parent) {
112        // we don't care about recycling here because we never scroll.
113        AdapterItem item = mItems.get(position);
114        Pair<View, Boolean> pair = AdapterHelper.getView(item, null /*parentGroup*/, parent,
115                mCallback, mAdapterRef, mSkipCallbackParser);
116        mSkipCallbackParser = pair.getSecond();
117        return pair.getFirst();
118
119    }
120
121    @Override
122    public int getViewTypeCount() {
123        return mTypes.size();
124    }
125
126    // ---- SpinnerAdapter
127
128    @Override
129    public View getDropDownView(int position, View convertView, ViewGroup parent) {
130        // pass
131        return null;
132    }
133}
134