12fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet/* 254d88f7678387a6eb871ec2dccd36af4ff35b1feDeepanshu Gupta * Copyright (C) 2013 The Android Open Source Project 32fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet * 42fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet * Licensed under the Apache License, Version 2.0 (the "License"); 52fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet * you may not use this file except in compliance with the License. 62fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet * You may obtain a copy of the License at 72fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet * 82fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet * http://www.apache.org/licenses/LICENSE-2.0 92fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet * 102fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet * Unless required by applicable law or agreed to in writing, software 112fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet * distributed under the License is distributed on an "AS IS" BASIS, 122fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet * See the License for the specific language governing permissions and 142fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet * limitations under the License. 152fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet */ 162fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 172fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetpackage com.android.layoutlib.bridge.impl.binding; 182fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 192fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport com.android.ide.common.rendering.api.DataBindingItem; 202fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport com.android.ide.common.rendering.api.IProjectCallback; 212fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport com.android.ide.common.rendering.api.LayoutLog; 222fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport com.android.ide.common.rendering.api.ResourceReference; 232fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport com.android.ide.common.rendering.api.IProjectCallback.ViewAttribute; 242fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport com.android.layoutlib.bridge.Bridge; 252fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeContext; 262fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport com.android.layoutlib.bridge.impl.RenderAction; 272fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport com.android.util.Pair; 282fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 292fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport android.view.View; 302fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport android.view.ViewGroup; 312fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport android.widget.AdapterView; 322fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport android.widget.Checkable; 332fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport android.widget.ImageView; 342fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport android.widget.TextView; 352fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 362fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet/** 3754d88f7678387a6eb871ec2dccd36af4ff35b1feDeepanshu Gupta * A Helper class to do fake data binding in {@link AdapterView} objects. 382fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet */ 3954d88f7678387a6eb871ec2dccd36af4ff35b1feDeepanshu Gupta@SuppressWarnings("deprecation") 4054d88f7678387a6eb871ec2dccd36af4ff35b1feDeepanshu Guptapublic class AdapterHelper { 412fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 4254d88f7678387a6eb871ec2dccd36af4ff35b1feDeepanshu Gupta static Pair<View, Boolean> getView(AdapterItem item, AdapterItem parentItem, ViewGroup parent, 4354d88f7678387a6eb871ec2dccd36af4ff35b1feDeepanshu Gupta IProjectCallback callback, ResourceReference adapterRef, boolean skipCallbackParser) { 442fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet // we don't care about recycling here because we never scroll. 452fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet DataBindingItem dataBindingItem = item.getDataBindingItem(); 462fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 472fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet BridgeContext context = RenderAction.getCurrentContext(); 482fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 492fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet Pair<View, Boolean> pair = context.inflateView(dataBindingItem.getViewReference(), 5054d88f7678387a6eb871ec2dccd36af4ff35b1feDeepanshu Gupta parent, false /*attachToRoot*/, skipCallbackParser); 512fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 522fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet View view = pair.getFirst(); 5354d88f7678387a6eb871ec2dccd36af4ff35b1feDeepanshu Gupta skipCallbackParser |= pair.getSecond(); 542fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 552fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet if (view != null) { 5654d88f7678387a6eb871ec2dccd36af4ff35b1feDeepanshu Gupta fillView(context, view, item, parentItem, callback, adapterRef); 572fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } else { 582fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet // create a text view to display an error. 592fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet TextView tv = new TextView(context); 602fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet tv.setText("Unable to find layout: " + dataBindingItem.getViewReference().getName()); 612fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet view = tv; 622fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 632fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 6454d88f7678387a6eb871ec2dccd36af4ff35b1feDeepanshu Gupta return Pair.of(view, skipCallbackParser); 652fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 662fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 6754d88f7678387a6eb871ec2dccd36af4ff35b1feDeepanshu Gupta private static void fillView(BridgeContext context, View view, AdapterItem item, 6854d88f7678387a6eb871ec2dccd36af4ff35b1feDeepanshu Gupta AdapterItem parentItem, IProjectCallback callback, ResourceReference adapterRef) { 692fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet if (view instanceof ViewGroup) { 702fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet ViewGroup group = (ViewGroup) view; 712fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet final int count = group.getChildCount(); 722fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet for (int i = 0 ; i < count ; i++) { 7354d88f7678387a6eb871ec2dccd36af4ff35b1feDeepanshu Gupta fillView(context, group.getChildAt(i), item, parentItem, callback, adapterRef); 742fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 752fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } else { 762fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet int id = view.getId(); 772fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet if (id != 0) { 782fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet ResourceReference resolvedRef = context.resolveId(id); 792fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet if (resolvedRef != null) { 802fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet int fullPosition = item.getFullPosition(); 812fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet int positionPerType = item.getPositionPerType(); 822fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet int fullParentPosition = parentItem != null ? parentItem.getFullPosition() : 0; 832fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet int parentPositionPerType = parentItem != null ? 842fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet parentItem.getPositionPerType() : 0; 852fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 862fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet if (view instanceof TextView) { 872fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet TextView tv = (TextView) view; 8854d88f7678387a6eb871ec2dccd36af4ff35b1feDeepanshu Gupta Object value = callback.getAdapterItemValue( 8954d88f7678387a6eb871ec2dccd36af4ff35b1feDeepanshu Gupta adapterRef, context.getViewKey(view), 902fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet item.getDataBindingItem().getViewReference(), 912fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet fullPosition, positionPerType, 922fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet fullParentPosition, parentPositionPerType, 932fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet resolvedRef, ViewAttribute.TEXT, tv.getText().toString()); 942fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet if (value != null) { 952fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet if (value.getClass() != ViewAttribute.TEXT.getAttributeClass()) { 962fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format( 972fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet "Wrong Adapter Item value class for TEXT. Expected String, got %s", 982fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet value.getClass().getName()), null); 992fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } else { 1002fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet tv.setText((String) value); 1012fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 1022fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 1032fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 1042fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 1052fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet if (view instanceof Checkable) { 1062fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet Checkable cb = (Checkable) view; 1072fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 10854d88f7678387a6eb871ec2dccd36af4ff35b1feDeepanshu Gupta Object value = callback.getAdapterItemValue( 10954d88f7678387a6eb871ec2dccd36af4ff35b1feDeepanshu Gupta adapterRef, context.getViewKey(view), 1102fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet item.getDataBindingItem().getViewReference(), 1112fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet fullPosition, positionPerType, 1122fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet fullParentPosition, parentPositionPerType, 1132fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet resolvedRef, ViewAttribute.IS_CHECKED, cb.isChecked()); 1142fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet if (value != null) { 1152fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet if (value.getClass() != ViewAttribute.IS_CHECKED.getAttributeClass()) { 1162fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format( 1172fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet "Wrong Adapter Item value class for TEXT. Expected Boolean, got %s", 1182fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet value.getClass().getName()), null); 1192fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } else { 1202fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet cb.setChecked((Boolean) value); 1212fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 1222fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 1232fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 1242fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 1252fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet if (view instanceof ImageView) { 1262fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet ImageView iv = (ImageView) view; 1272fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet 12854d88f7678387a6eb871ec2dccd36af4ff35b1feDeepanshu Gupta Object value = callback.getAdapterItemValue( 12954d88f7678387a6eb871ec2dccd36af4ff35b1feDeepanshu Gupta adapterRef, context.getViewKey(view), 1302fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet item.getDataBindingItem().getViewReference(), 1312fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet fullPosition, positionPerType, 1322fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet fullParentPosition, parentPositionPerType, 1332fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet resolvedRef, ViewAttribute.SRC, iv.getDrawable()); 1342fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet if (value != null) { 1352fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet if (value.getClass() != ViewAttribute.SRC.getAttributeClass()) { 1362fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format( 1372fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet "Wrong Adapter Item value class for TEXT. Expected Boolean, got %s", 1382fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet value.getClass().getName()), null); 1392fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } else { 1402fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet // FIXME 1412fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 1422fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 1432fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 1442fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 1452fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 1462fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 1472fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet } 1482fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet} 149