Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 68862f07 authored by Deepanshu Gupta's avatar Deepanshu Gupta Committed by Android Git Automerger
Browse files

am 79a1a7c3: am 31207780: am 0ecfe381: am 54d88f76: Fix ClassCastException when rendering ListView

* commit '79a1a7c3':
  Fix ClassCastException when rendering ListView
parents 12d3f488 79a1a7c3
Loading
Loading
Loading
Loading
+19 −118
Original line number Diff line number Diff line
/*
 * Copyright (C) 2011 The Android Open Source Project
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@

package com.android.layoutlib.bridge.impl.binding;

import com.android.ide.common.rendering.api.AdapterBinding;
import com.android.ide.common.rendering.api.DataBindingItem;
import com.android.ide.common.rendering.api.IProjectCallback;
import com.android.ide.common.rendering.api.LayoutLog;
@@ -27,7 +26,6 @@ import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.layoutlib.bridge.impl.RenderAction;
import com.android.util.Pair;

import android.database.DataSetObserver;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
@@ -35,124 +33,27 @@ import android.widget.Checkable;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Base adapter to do fake data binding in {@link AdapterView} objects.
 */
public class BaseAdapter {

/**
     * This is the items provided by the adapter. They are dynamically generated.
 * A Helper class to do fake data binding in {@link AdapterView} objects.
 */
    protected final static class AdapterItem {
        private final DataBindingItem mItem;
        private final int mType;
        private final int mFullPosition;
        private final int mPositionPerType;
        private List<AdapterItem> mChildren;

        protected AdapterItem(DataBindingItem item, int type, int fullPosition,
                int positionPerType) {
            mItem = item;
            mType = type;
            mFullPosition = fullPosition;
            mPositionPerType = positionPerType;
        }

        void addChild(AdapterItem child) {
            if (mChildren == null) {
                mChildren = new ArrayList<AdapterItem>();
            }

            mChildren.add(child);
        }

        List<AdapterItem> getChildren() {
            if (mChildren != null) {
                return mChildren;
            }

            return Collections.emptyList();
        }

        int getType() {
            return mType;
        }

        int getFullPosition() {
            return mFullPosition;
        }

        int getPositionPerType() {
            return mPositionPerType;
        }

        DataBindingItem getDataBindingItem() {
            return mItem;
        }
    }

    private final AdapterBinding mBinding;
    private final IProjectCallback mCallback;
    private final ResourceReference mAdapterRef;
    private boolean mSkipCallbackParser = false;

    protected final List<AdapterItem> mItems = new ArrayList<AdapterItem>();

    protected BaseAdapter(ResourceReference adapterRef, AdapterBinding binding,
            IProjectCallback callback) {
        mAdapterRef = adapterRef;
        mBinding = binding;
        mCallback = callback;
    }

    // ------- Some Adapter method used by all children classes.

    public boolean areAllItemsEnabled() {
        return true;
    }

    public boolean hasStableIds() {
        return true;
    }

    public boolean isEmpty() {
        return mItems.size() == 0;
    }

    public void registerDataSetObserver(DataSetObserver observer) {
        // pass
    }

    public void unregisterDataSetObserver(DataSetObserver observer) {
        // pass
    }

    // -------


    protected AdapterBinding getBinding() {
        return mBinding;
    }
@SuppressWarnings("deprecation")
public class AdapterHelper {

    protected View getView(AdapterItem item, AdapterItem parentItem, View convertView,
            ViewGroup parent) {
    static Pair<View, Boolean> getView(AdapterItem item, AdapterItem parentItem, ViewGroup parent,
            IProjectCallback callback, ResourceReference adapterRef, boolean skipCallbackParser) {
        // we don't care about recycling here because we never scroll.
        DataBindingItem dataBindingItem = item.getDataBindingItem();

        BridgeContext context = RenderAction.getCurrentContext();

        Pair<View, Boolean> pair = context.inflateView(dataBindingItem.getViewReference(),
                parent, false /*attachToRoot*/, mSkipCallbackParser);
                parent, false /*attachToRoot*/, skipCallbackParser);

        View view = pair.getFirst();
        mSkipCallbackParser |= pair.getSecond();
        skipCallbackParser |= pair.getSecond();

        if (view != null) {
            fillView(context, view, item, parentItem);
            fillView(context, view, item, parentItem, callback, adapterRef);
        } else {
            // create a text view to display an error.
            TextView tv = new TextView(context);
@@ -160,16 +61,16 @@ public class BaseAdapter {
            view = tv;
        }

        return view;
        return Pair.of(view, skipCallbackParser);
    }

    private void fillView(BridgeContext context, View view, AdapterItem item,
            AdapterItem parentItem) {
    private static void fillView(BridgeContext context, View view, AdapterItem item,
            AdapterItem parentItem, IProjectCallback callback, ResourceReference adapterRef) {
        if (view instanceof ViewGroup) {
            ViewGroup group = (ViewGroup) view;
            final int count = group.getChildCount();
            for (int i = 0 ; i < count ; i++) {
                fillView(context, group.getChildAt(i), item, parentItem);
                fillView(context, group.getChildAt(i), item, parentItem, callback, adapterRef);
            }
        } else {
            int id = view.getId();
@@ -184,8 +85,8 @@ public class BaseAdapter {

                    if (view instanceof TextView) {
                        TextView tv = (TextView) view;
                        Object value = mCallback.getAdapterItemValue(
                                mAdapterRef, context.getViewKey(view),
                        Object value = callback.getAdapterItemValue(
                                adapterRef, context.getViewKey(view),
                                item.getDataBindingItem().getViewReference(),
                                fullPosition, positionPerType,
                                fullParentPosition, parentPositionPerType,
@@ -204,8 +105,8 @@ public class BaseAdapter {
                    if (view instanceof Checkable) {
                        Checkable cb = (Checkable) view;

                        Object value = mCallback.getAdapterItemValue(
                                mAdapterRef, context.getViewKey(view),
                        Object value = callback.getAdapterItemValue(
                                adapterRef, context.getViewKey(view),
                                item.getDataBindingItem().getViewReference(),
                                fullPosition, positionPerType,
                                fullParentPosition, parentPositionPerType,
@@ -224,8 +125,8 @@ public class BaseAdapter {
                    if (view instanceof ImageView) {
                        ImageView iv = (ImageView) view;

                        Object value = mCallback.getAdapterItemValue(
                                mAdapterRef, context.getViewKey(view),
                        Object value = callback.getAdapterItemValue(
                                adapterRef, context.getViewKey(view),
                                item.getDataBindingItem().getViewReference(),
                                fullPosition, positionPerType,
                                fullParentPosition, parentPositionPerType,
+74 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.layoutlib.bridge.impl.binding;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.android.ide.common.rendering.api.DataBindingItem;

/**
 * This is the items provided by the adapter. They are dynamically generated.
 */
final class AdapterItem {
    private final DataBindingItem mItem;
    private final int mType;
    private final int mFullPosition;
    private final int mPositionPerType;
    private List<AdapterItem> mChildren;

    protected AdapterItem(DataBindingItem item, int type, int fullPosition,
            int positionPerType) {
        mItem = item;
        mType = type;
        mFullPosition = fullPosition;
        mPositionPerType = positionPerType;
    }

    void addChild(AdapterItem child) {
        if (mChildren == null) {
            mChildren = new ArrayList<AdapterItem>();
        }

        mChildren.add(child);
    }

    List<AdapterItem> getChildren() {
        if (mChildren != null) {
            return mChildren;
        }

        return Collections.emptyList();
    }

    int getType() {
        return mType;
    }

    int getFullPosition() {
        return mFullPosition;
    }

    int getPositionPerType() {
        return mPositionPerType;
    }

    DataBindingItem getDataBindingItem() {
        return mItem;
    }
}
+18 −6
Original line number Diff line number Diff line
@@ -20,10 +20,12 @@ import com.android.ide.common.rendering.api.AdapterBinding;
import com.android.ide.common.rendering.api.DataBindingItem;
import com.android.ide.common.rendering.api.IProjectCallback;
import com.android.ide.common.rendering.api.ResourceReference;
import com.android.util.Pair;

import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ListAdapter;
import android.widget.SpinnerAdapter;

@@ -35,17 +37,23 @@ import java.util.List;
 * and {@link SpinnerAdapter}.
 *
 */
public class FakeAdapter extends BaseAdapter implements ListAdapter, SpinnerAdapter {
@SuppressWarnings("deprecation")
public class FakeAdapter extends BaseAdapter {

    // don't use a set because the order is important.
    private final List<ResourceReference> mTypes = new ArrayList<ResourceReference>();
    private final IProjectCallback mCallback;
    private final ResourceReference mAdapterRef;
    private final List<AdapterItem> mItems = new ArrayList<AdapterItem>();
    private boolean mSkipCallbackParser = false;

    public FakeAdapter(ResourceReference adapterRef, AdapterBinding binding,
            IProjectCallback callback) {
        super(adapterRef, binding, callback);
        mAdapterRef = adapterRef;
        mCallback = callback;

        final int repeatCount = getBinding().getRepeatCount();
        final int itemCount = getBinding().getItemCount();
        final int repeatCount = binding.getRepeatCount();
        final int itemCount = binding.getItemCount();

        // Need an array to count for each type.
        // This is likely too big, but is the max it can be.
@@ -54,7 +62,7 @@ public class FakeAdapter extends BaseAdapter implements ListAdapter, SpinnerAdap
        // We put several repeating sets.
        for (int r = 0 ; r < repeatCount ; r++) {
            // loop on the type of list items, and add however many for each type.
            for (DataBindingItem dataBindingItem : getBinding()) {
            for (DataBindingItem dataBindingItem : binding) {
                ResourceReference viewRef = dataBindingItem.getViewReference();
                int typeIndex = mTypes.indexOf(viewRef);
                if (typeIndex == -1) {
@@ -103,7 +111,11 @@ public class FakeAdapter extends BaseAdapter implements ListAdapter, SpinnerAdap
    public View getView(int position, View convertView, ViewGroup parent) {
        // we don't care about recycling here because we never scroll.
        AdapterItem item = mItems.get(position);
        return getView(item, null /*parentGroup*/, convertView, parent);
        Pair<View, Boolean> pair = AdapterHelper.getView(item, null /*parentGroup*/, parent,
                mCallback, mAdapterRef, mSkipCallbackParser);
        mSkipCallbackParser = pair.getSecond();
        return pair.getFirst();

    }

    @Override
+45 −5
Original line number Diff line number Diff line
@@ -20,7 +20,9 @@ import com.android.ide.common.rendering.api.AdapterBinding;
import com.android.ide.common.rendering.api.DataBindingItem;
import com.android.ide.common.rendering.api.IProjectCallback;
import com.android.ide.common.rendering.api.ResourceReference;
import com.android.util.Pair;

import android.database.DataSetObserver;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ExpandableListAdapter;
@@ -29,8 +31,14 @@ import android.widget.HeterogeneousExpandableList;
import java.util.ArrayList;
import java.util.List;

public class FakeExpandableAdapter extends BaseAdapter implements ExpandableListAdapter,
        HeterogeneousExpandableList {
@SuppressWarnings("deprecation")
public class FakeExpandableAdapter implements ExpandableListAdapter, HeterogeneousExpandableList {

    private final IProjectCallback mCallback;
    private final ResourceReference mAdapterRef;
    private boolean mSkipCallbackParser = false;

    protected final List<AdapterItem> mItems = new ArrayList<AdapterItem>();

    // don't use a set because the order is important.
    private final List<ResourceReference> mGroupTypes = new ArrayList<ResourceReference>();
@@ -38,7 +46,8 @@ public class FakeExpandableAdapter extends BaseAdapter implements ExpandableList

    public FakeExpandableAdapter(ResourceReference adapterRef, AdapterBinding binding,
            IProjectCallback callback) {
        super(adapterRef, binding, callback);
        mAdapterRef = adapterRef;
        mCallback = callback;

        createItems(binding, binding.getItemCount(), binding.getRepeatCount(), mGroupTypes, 1);
    }
@@ -125,7 +134,10 @@ public class FakeExpandableAdapter extends BaseAdapter implements ExpandableList
            ViewGroup parent) {
        // we don't care about recycling here because we never scroll.
        AdapterItem item = mItems.get(groupPosition);
        return getView(item, null /*parentItem*/, convertView, parent);
        Pair<View, Boolean> pair = AdapterHelper.getView(item, null /*parentItem*/, parent,
                mCallback, mAdapterRef, mSkipCallbackParser);
        mSkipCallbackParser = pair.getSecond();
        return pair.getFirst();
    }

    @Override
@@ -134,7 +146,10 @@ public class FakeExpandableAdapter extends BaseAdapter implements ExpandableList
        // we don't care about recycling here because we never scroll.
        AdapterItem parentItem = mItems.get(groupPosition);
        AdapterItem item = getChildItem(groupPosition, childPosition);
        return getView(item, parentItem, convertView, parent);
        Pair<View, Boolean> pair = AdapterHelper.getView(item, parentItem, parent, mCallback,
                mAdapterRef, mSkipCallbackParser);
        mSkipCallbackParser = pair.getSecond();
        return pair.getFirst();
    }

    @Override
@@ -172,6 +187,31 @@ public class FakeExpandableAdapter extends BaseAdapter implements ExpandableList
        // pass
    }

    @Override
    public void registerDataSetObserver(DataSetObserver observer) {
        // pass
    }

    @Override
    public void unregisterDataSetObserver(DataSetObserver observer) {
        // pass
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }

    @Override
    public boolean areAllItemsEnabled() {
        return true;
    }

    @Override
    public boolean isEmpty() {
        return mItems.isEmpty();
    }

    // ---- HeterogeneousExpandableList

    @Override