package gueei.binding.widgets; import gueei.binding.Binder; import gueei.binding.Command; import gueei.binding.IBindableView; import gueei.binding.ViewAttribute; import gueei.binding.Binder.InflateResult; import gueei.binding.viewAttributes.templates.SingleTemplateLayout; import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.widget.FrameLayout; public class BindableFrameLayout extends FrameLayout implements IBindableView<BindableFrameLayout>{ private int LayoutId = 0; private Object dataSource = null; private boolean updateEnabled = true; private InflateResult inflateResult = null; public BindableFrameLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public BindableFrameLayout(Context context, AttributeSet attrs) { super(context, attrs); } public BindableFrameLayout(Context context) { super(context); } @Override protected void onDetachedFromWindow() { LayoutId = 0; dataSource = null; inflateResult = null; super.onDetachedFromWindow(); } private ViewAttribute<?, Object> LayoutIdViewAttribute = new ViewAttribute<BindableFrameLayout, Object>(Object.class, BindableFrameLayout.this, "LayoutId"){ @Override protected void doSetAttributeValue(Object newValue) { int newLayoutId = 0; if( newValue instanceof SingleTemplateLayout) { SingleTemplateLayout layout = (SingleTemplateLayout)newValue; newLayoutId = layout.getDefaultLayoutId(); } else { if ((newValue != null)&&(newValue.toString().length()>0)){ try { newLayoutId = Integer.parseInt(newValue.toString()); } catch( Exception e ) {} } } BindableFrameLayout.this.setLayoutId(newLayoutId); } @Override public Object get() { return LayoutId; } }; private ViewAttribute<?, Object> DataSourceViewAttribute = new ViewAttribute<BindableFrameLayout, Object>( Object.class, BindableFrameLayout.this, "DataSource"){ @Override protected void doSetAttributeValue(Object newValue) { BindableFrameLayout.this.setDatasource(newValue); } @Override public Object get() { return dataSource; } }; private ViewAttribute<?, Command> OnLoadAttribute = new ViewAttribute<BindableFrameLayout, Command>( Command.class, BindableFrameLayout.this, "OnLoad"){ @Override protected void doSetAttributeValue(Object newValue) { if (newValue instanceof Command){ Command loadCmd = (Command)newValue; loadCmd.Invoke(BindableFrameLayout.this, new ILayoutLoadEvent() { @Override public void setLayoutId(int layoutId) { BindableFrameLayout.this.setLayoutId(layoutId); } @Override public void setDatasource(Object... dataSource) { BindableFrameLayout.this.setDatasource(dataSource); } }); } } @Override public Command get() { return null; } }; private ViewAttribute<BindableFrameLayout, Boolean> ItemUpdateEnabledAttribute = new ViewAttribute<BindableFrameLayout, Boolean>(Boolean.class, BindableFrameLayout.this, "UpdateEnabled"){ @Override protected void doSetAttributeValue(Object newValue) { if( newValue == null ) { updateEnabled = true; } else if( newValue instanceof Boolean ) { Boolean value = (Boolean) newValue; updateEnabled = value; if(updateEnabled) { BindableFrameLayout.this.invalidate(); } } } @Override public Boolean get() { return updateEnabled; } }; @Override protected void onDraw(Canvas canvas) { if( !updateEnabled ) return; super.onDraw(canvas); } @Override protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) { if( !updateEnabled ) return; super.onMeasure(widthMeasureSpec, heightMeasureSpec); } public ViewAttribute<?, ?> createViewAttribute( String attributeName) { if (attributeName.equals("layoutId")) return LayoutIdViewAttribute; if (attributeName.equals("dataSource")) return DataSourceViewAttribute; if (attributeName.equals("onLoad")) return OnLoadAttribute; if (attributeName.equals("updateEnabled")) return ItemUpdateEnabledAttribute; return null; } protected void setDatasource(Object newValue) { if(dataSource!=null) inflateResult = null; // inflate new dataSource = newValue; rebind(); refreshDrawableState(); } // TODO: add layout caching // TODO: add a binding:useLayoutCaching="true" attribute // TODO: add a transition manager protected void setLayoutId(int layoutId) { if( LayoutId != layoutId ) { LayoutId = layoutId; inflateResult = null; // inflate new rebind(); refreshDrawableState(); } } protected void rebind(){ BindableFrameLayout.this.removeAllViews(); if (LayoutId<=0) return; if(inflateResult==null||dataSource==null) inflateResult= Binder.inflateView(BindableFrameLayout.this.getContext(), LayoutId, BindableFrameLayout.this, false); BindableFrameLayout.this.addView(inflateResult.rootView); if (dataSource==null){ Binder.bindView(BindableFrameLayout.this.getContext(), inflateResult, null); }else if (dataSource.getClass().isArray()){ Object[] sources = (Object[])dataSource; for(int i=0; i<sources.length; i++){ Binder.bindView(BindableFrameLayout.this.getContext(), inflateResult, sources[i]); } }else{ Binder.bindView(BindableFrameLayout.this.getContext(), inflateResult, dataSource); } } }