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