Home | History | Annotate | Download | only in binding
      1 /*
      2  * Copyright (C) 2013 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 
     17 package com.android.layoutlib.bridge.impl.binding;
     18 
     19 import com.android.ide.common.rendering.api.DataBindingItem;
     20 import com.android.ide.common.rendering.api.LayoutlibCallback;
     21 import com.android.ide.common.rendering.api.LayoutLog;
     22 import com.android.ide.common.rendering.api.ResourceReference;
     23 import com.android.ide.common.rendering.api.IProjectCallback.ViewAttribute;
     24 import com.android.layoutlib.bridge.Bridge;
     25 import com.android.layoutlib.bridge.android.BridgeContext;
     26 import com.android.layoutlib.bridge.impl.RenderAction;
     27 import com.android.util.Pair;
     28 
     29 import android.view.View;
     30 import android.view.ViewGroup;
     31 import android.widget.AdapterView;
     32 import android.widget.Checkable;
     33 import android.widget.ImageView;
     34 import android.widget.TextView;
     35 
     36 /**
     37  * A Helper class to do fake data binding in {@link AdapterView} objects.
     38  */
     39 public class AdapterHelper {
     40 
     41     @SuppressWarnings("deprecation")
     42     static Pair<View, Boolean> getView(AdapterItem item, AdapterItem parentItem, ViewGroup parent,
     43             LayoutlibCallback callback, ResourceReference adapterRef, boolean skipCallbackParser) {
     44         // we don't care about recycling here because we never scroll.
     45         DataBindingItem dataBindingItem = item.getDataBindingItem();
     46 
     47         BridgeContext context = RenderAction.getCurrentContext();
     48 
     49         Pair<View, Boolean> pair = context.inflateView(dataBindingItem.getViewReference(),
     50                 parent, false /*attachToRoot*/, skipCallbackParser);
     51 
     52         View view = pair.getFirst();
     53         skipCallbackParser |= pair.getSecond();
     54 
     55         if (view != null) {
     56             fillView(context, view, item, parentItem, callback, adapterRef);
     57         } else {
     58             // create a text view to display an error.
     59             TextView tv = new TextView(context);
     60             tv.setText("Unable to find layout: " + dataBindingItem.getViewReference().getName());
     61             view = tv;
     62         }
     63 
     64         return Pair.of(view, skipCallbackParser);
     65     }
     66 
     67     private static void fillView(BridgeContext context, View view, AdapterItem item,
     68             AdapterItem parentItem, LayoutlibCallback callback, ResourceReference adapterRef) {
     69         if (view instanceof ViewGroup) {
     70             ViewGroup group = (ViewGroup) view;
     71             final int count = group.getChildCount();
     72             for (int i = 0 ; i < count ; i++) {
     73                 fillView(context, group.getChildAt(i), item, parentItem, callback, adapterRef);
     74             }
     75         } else {
     76             int id = view.getId();
     77             if (id != 0) {
     78                 ResourceReference resolvedRef = context.resolveId(id);
     79                 if (resolvedRef != null) {
     80                     int fullPosition = item.getFullPosition();
     81                     int positionPerType = item.getPositionPerType();
     82                     int fullParentPosition = parentItem != null ? parentItem.getFullPosition() : 0;
     83                     int parentPositionPerType = parentItem != null ?
     84                             parentItem.getPositionPerType() : 0;
     85 
     86                     if (view instanceof TextView) {
     87                         TextView tv = (TextView) view;
     88                         Object value = callback.getAdapterItemValue(
     89                                 adapterRef, context.getViewKey(view),
     90                                 item.getDataBindingItem().getViewReference(),
     91                                 fullPosition, positionPerType,
     92                                 fullParentPosition, parentPositionPerType,
     93                                 resolvedRef, ViewAttribute.TEXT, tv.getText().toString());
     94                         if (value != null) {
     95                             if (value.getClass() != ViewAttribute.TEXT.getAttributeClass()) {
     96                                 Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format(
     97                                         "Wrong Adapter Item value class for TEXT. Expected String, got %s",
     98                                         value.getClass().getName()), null);
     99                             } else {
    100                                 tv.setText((String) value);
    101                             }
    102                         }
    103                     }
    104 
    105                     if (view instanceof Checkable) {
    106                         Checkable cb = (Checkable) view;
    107 
    108                         Object value = callback.getAdapterItemValue(
    109                                 adapterRef, context.getViewKey(view),
    110                                 item.getDataBindingItem().getViewReference(),
    111                                 fullPosition, positionPerType,
    112                                 fullParentPosition, parentPositionPerType,
    113                                 resolvedRef, ViewAttribute.IS_CHECKED, cb.isChecked());
    114                         if (value != null) {
    115                             if (value.getClass() != ViewAttribute.IS_CHECKED.getAttributeClass()) {
    116                                 Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format(
    117                                         "Wrong Adapter Item value class for IS_CHECKED. Expected Boolean, got %s",
    118                                         value.getClass().getName()), null);
    119                             } else {
    120                                 cb.setChecked((Boolean) value);
    121                             }
    122                         }
    123                     }
    124 
    125                     if (view instanceof ImageView) {
    126                         ImageView iv = (ImageView) view;
    127 
    128                         Object value = callback.getAdapterItemValue(
    129                                 adapterRef, context.getViewKey(view),
    130                                 item.getDataBindingItem().getViewReference(),
    131                                 fullPosition, positionPerType,
    132                                 fullParentPosition, parentPositionPerType,
    133                                 resolvedRef, ViewAttribute.SRC, iv.getDrawable());
    134                         if (value != null) {
    135                             if (value.getClass() != ViewAttribute.SRC.getAttributeClass()) {
    136                                 Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format(
    137                                         "Wrong Adapter Item value class for SRC. Expected Boolean, got %s",
    138                                         value.getClass().getName()), null);
    139                             } else {
    140                                 // FIXME
    141                             }
    142                         }
    143                     }
    144                 }
    145             }
    146         }
    147     }
    148 }
    149