@Override public Object instantiateItem(View container, int position) { synchronized (viewsLock) { ViewGroup pager = (ViewGroup) container; TiViewProxy tiProxy = mViews.get(position); TiUIView tiView = tiProxy.getOrCreateView(); View view = tiView.getOuterView(); ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); TiCompositeLayout layout = new TiCompositeLayout(tiProxy.getActivity()); ViewParent parent = view.getParent(); if (parent instanceof ViewGroup) { pager.removeView((View) parent); ViewGroup group = (ViewGroup) parent; group.removeView(view); } layout.addView(view, tiView.getLayoutParams()); if (position < pager.getChildCount()) { pager.addView(layout, position, params); } else { pager.addView(layout, params); } return tiProxy; } }
public TiUIScrollableView(ScrollableViewProxy proxy, TiBaseActivity activity) { super(proxy); // activity.addConfigurationChangedListener(this); mViews = new ArrayList<TiViewProxy>(); viewsLock = new Object(); buildViewPager(activity); TiCompositeLayout.LayoutParams params = new LayoutParams(); params.optionWidth = new TiDimension("100%", TiDimension.TYPE_WIDTH); params.optionHeight = new TiDimension("100%", TiDimension.TYPE_HEIGHT); mPager.setLayoutParams(params); mContainer = new TiViewPagerLayout(activity) { @Override public boolean dispatchTouchEvent(MotionEvent event) { if (touchPassThrough == true) return false; return super.dispatchTouchEvent(event); } }; mContainer.addView((View) mPager, params); mPagingControl = buildPagingControl(activity); mContainer.addView(mPagingControl, buildFillLayoutParams()); setNativeView(mContainer); }
public TiUIFragment(TiViewProxy proxy, Activity activity) { super(proxy); // When 'fragmentOnly' property is enabled, we generate the standalone fragment, enabling // us to add it directly to other fragment managers. if (proxy.hasProperty(TiC.PROPERTY_FRAGMENT_ONLY)) { fragmentOnly = TiConvert.toBoolean(proxy.getProperty(TiC.PROPERTY_FRAGMENT_ONLY), false); } if (fragmentOnly) { fragment = createFragment(); } else { TiCompositeLayout container = new TiCompositeLayout(activity, proxy) { @Override public boolean dispatchTouchEvent(MotionEvent ev) { return interceptTouchEvent(ev) || super.dispatchTouchEvent(ev); } }; container.setId(viewId++); setNativeView(container); FragmentManager manager = ((FragmentActivity) activity).getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); fragment = createFragment(); transaction.add(container.getId(), fragment); transaction.commitAllowingStateLoss(); } }
public View layoutHeaderOrFooterView(TiViewProxy viewProxy) { TiUIView tiView = viewProxy.peekView(); if (tiView != null) { TiViewProxy parentProxy = viewProxy.getParent(); // Remove parent view if possible if (parentProxy != null) { TiUIView parentView = parentProxy.peekView(); if (parentView != null) { parentView.remove(tiView); } } } else { tiView = viewProxy.forceCreateView(); } View outerView = tiView.getOuterView(); ViewGroup parentView = (ViewGroup) outerView.getParent(); if (parentView != null && parentView.getId() == HEADER_FOOTER_WRAP_ID) { return parentView; } else { // add a wrapper so layout params such as height, width takes in effect. TiCompositeLayout wrapper = new TiCompositeLayout(viewProxy.getActivity(), LayoutArrangement.DEFAULT, null); AbsListView.LayoutParams params = new AbsListView.LayoutParams( AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT); wrapper.setLayoutParams(params); outerView = tiView.getOuterView(); wrapper.addView(outerView, tiView.getLayoutParams()); wrapper.setId(HEADER_FOOTER_WRAP_ID); return wrapper; } }
@Override public boolean isViewFromObject(View view, Object object) { synchronized (viewsLock) { TiViewProxy tiProxy = (TiViewProxy) object; if (tiProxy != null) { View outerView = tiProxy.getOuterView(); if (outerView != null) { TiCompositeLayout layout = (TiCompositeLayout) outerView.getParent(); return (layout != null && layout.equals(view)); } } } return false; }
public void showPager() { View v = null; v = mContainer.findViewById(PAGE_LEFT); if (v != null) { v.setVisibility(mCurIndex > 0 ? View.VISIBLE : View.INVISIBLE); } v = mContainer.findViewById(PAGE_RIGHT); if (v != null) { v.setVisibility(mCurIndex < (mViews.size() - 1) ? View.VISIBLE : View.INVISIBLE); } mPagingControl.setVisibility(View.VISIBLE); ((ScrollableViewProxy) proxy).setPagerTimeout(); }
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension( Math.max(measuredWidth, getMeasuredWidth()), Math.max(measuredHeight, getMeasuredHeight())); }
@Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); if (enabled) { drawMask(canvas); } }
protected void refreshControls() { ArrayList<TiViewProxy> proxies = getRowProxy().getControls(); int len = proxies.size(); if (views == null) { views = new ArrayList<TiUIView>(len); } else if (views.size() != len) { for (TiUIView view : views) { View v = view.getNativeView(); if (v != null && v.getParent().equals(content)) { content.removeView(v); } } views = new ArrayList<TiUIView>(len); } for (int i = 0; i < len; i++) { TiUIView view = views.size() > i ? views.get(i) : null; TiViewProxy proxy = proxies.get(i); if (view != null && view.getProxy() instanceof TableViewRowProxy) { proxy = addViewToOldRow(i, view, proxy); len++; } if (view == null) { // In some cases the TiUIView for this proxy has been reassigned to another proxy // We don't want to actually release it though, just reassign by creating a new view view = proxy.forceCreateView(tiContext.getActivity()); clearChildViews(proxy); if (i >= views.size()) { views.add(view); } else { views.set(i, view); } } View v = view.getNativeView(); view.setProxy(proxy); view.processProperties(proxy.getProperties()); applyChildProxies(proxy, view); if (v != null && v.getParent() == null) { content.addView(v, view.getLayoutParams()); } } }
public void processProperties(KrollDict d) { if (d.containsKey(TiC.PROPERTY_LAYOUT)) { String layout = TiConvert.toString(d, TiC.PROPERTY_LAYOUT); if (nativeView instanceof TiCompositeLayout) { ((TiCompositeLayout) nativeView).setLayoutArrangement(layout); } } if (TiConvert.fillLayout(d, layoutParams)) { if (nativeView != null) { nativeView.requestLayout(); } } Integer bgColor = null; // Default background processing. // Prefer image to color. if (hasImage(d) || hasColorState(d) || hasBorder(d)) { handleBackgroundImage(d); } else if (d.containsKey(TiC.PROPERTY_BACKGROUND_COLOR)) { bgColor = TiConvert.toColor(d, TiC.PROPERTY_BACKGROUND_COLOR); nativeView.setBackgroundColor(bgColor); } if (d.containsKey(TiC.PROPERTY_OPACITY)) { if (nativeView != null) { setOpacity(TiConvert.toFloat(d, TiC.PROPERTY_OPACITY)); } } if (d.containsKey(TiC.PROPERTY_VISIBLE)) { nativeView.setVisibility( TiConvert.toBoolean(d, TiC.PROPERTY_VISIBLE) ? View.VISIBLE : View.INVISIBLE); } if (d.containsKey(TiC.PROPERTY_ENABLED)) { nativeView.setEnabled(TiConvert.toBoolean(d, TiC.PROPERTY_ENABLED)); } if (d.containsKey(TiC.PROPERTY_FOCUSABLE)) { boolean focusable = TiConvert.toBoolean(d, TiC.PROPERTY_FOCUSABLE); nativeView.setFocusable(focusable); if (focusable) { registerForKeyClick(nativeView); } else { nativeView.setOnClickListener(null); } } initializeBorder(d, bgColor); if (d.containsKey(TiC.PROPERTY_TRANSFORM)) { Ti2DMatrix matrix = (Ti2DMatrix) d.get(TiC.PROPERTY_TRANSFORM); if (matrix != null) { applyTransform(matrix); } } }
// Animation @Override public void invalidateDrawable(Drawable dr) { if (dr != getBackground() && dr != null) { initMask(dr); swapBitmapMask(makeBitmapMask(dr)); invalidate(); } else { super.invalidateDrawable(dr); } }
@Override protected void constrainChild(View child, int width, int wMode, int height, int hMode) { super.constrainChild(child, width, wMode, height, hMode); // We need to support an automatically growing contentArea, so this code is // updates the measured dimensions as needed. absWidth, absHeight are // left in for debugging purposes. ATM int absWidth = calculateAbsoluteRight(child); int absHeight = calculateAbsoluteBottom(child); }
public TiTableViewRowProxyItem(TiContext tiContext) { super(tiContext); this.handler = new Handler(this); this.leftImage = new ImageView(tiContext.getActivity()); leftImage.setVisibility(GONE); addView(leftImage, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); this.content = new TiCompositeLayout(tiContext.getActivity()); content.setMinimumHeight(48); addView(content, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); this.rightImage = new ImageView(tiContext.getActivity()); rightImage.setVisibility(GONE); addView(rightImage, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); }
protected void layoutNativeView(boolean informParent) { if (nativeView != null) { Animation a = nativeView.getAnimation(); if (a != null && a instanceof TiMatrixAnimation) { TiMatrixAnimation matrixAnimation = (TiMatrixAnimation) a; matrixAnimation.invalidateWithMatrix(nativeView); } if (informParent) { if (parent != null) { TiUIView uiv = parent.peekView(); if (uiv != null) { View v = uiv.getNativeView(); if (v instanceof TiCompositeLayout) { ((TiCompositeLayout) v).resort(); } } } } nativeView.requestLayout(); } }
protected void refreshOldStyleRow() { TableViewRowProxy rp = getRowProxy(); if (!rp.hasProperty(TiC.PROPERTY_TOUCH_ENABLED)) { rp.setProperty(TiC.PROPERTY_TOUCH_ENABLED, false); } if (views == null) { views = new ArrayList<TiUIView>(); views.add(new TiUILabel(rp)); } TiUILabel t = (TiUILabel) views.get(0); t.setProxy(rp); t.processProperties(filterProperties(rp.getProperties())); View v = t.getNativeView(); if (v.getParent() == null) { TiCompositeLayout.LayoutParams params = (TiCompositeLayout.LayoutParams) t.getLayoutParams(); params.optionLeft = new TiDimension(5, TiDimension.TYPE_LEFT); params.optionRight = new TiDimension(5, TiDimension.TYPE_RIGHT); params.autoFillsWidth = true; content.addView(v, params); } }
@Override public void release() { super.release(); if (views != null) { for (TiUIView view : views) { view.release(); } views = null; } if (content != null) { content.removeAllViews(); content = null; } if (hasCheckDrawable != null) { hasCheckDrawable.setCallback(null); hasCheckDrawable = null; } if (hasChildDrawable != null) { hasChildDrawable.setCallback(null); hasChildDrawable = null; } }
@Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { int contentLeft = left; int contentRight = right; bottom = bottom - top; top = 0; int height = bottom - top; if (leftImage != null && leftImage.getVisibility() != GONE) { int w = leftImage.getMeasuredWidth(); int h = leftImage.getMeasuredHeight(); int leftMargin = LEFT_MARGIN; contentLeft += w + leftMargin; int offset = (height - h) / 2; leftImage.layout(left + leftMargin, top + offset, left + leftMargin + w, top + offset + h); } if (rightImage != null && rightImage.getVisibility() != GONE) { int w = rightImage.getMeasuredWidth(); int h = rightImage.getMeasuredHeight(); int rightMargin = RIGHT_MARGIN; contentRight -= w + rightMargin; int offset = (height - h) / 2; rightImage.layout( right - w - rightMargin, top + offset, right - rightMargin, top + offset + h); } if (hasControls) { contentLeft = left + LEFT_MARGIN; contentRight = right - RIGHT_MARGIN; } if (content != null) { content.layout(contentLeft, top, contentRight, bottom); } }
@Override protected void onDestroy() { super.onDestroy(); for (WeakReference<TiContext> contextRef : contexts) { TiContext ctx = contextRef.get(); if (ctx != null) { ctx.dispatchOnDestroy(); ctx.release(); } } if (layout != null) { Log.e(LCAT, "Layout cleanup."); layout.removeAllViews(); layout = null; } if (proxy != null) { proxy.closeFromActivity(); proxy = null; } handler = null; }
@Override public void addWindow(View v, TiCompositeLayout.LayoutParams params) { layout.addView(v, params); }
@Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); updateSize(getMeasuredWidth(), getMeasuredHeight()); }
// Once the size has changed we need to remake the mask. @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); updateSize(w, h); }
/** * Sets the proxy for our layout (used for post layout event) * * @param proxy */ public void setLayoutProxy(TiViewProxy proxy) { if (layout instanceof TiCompositeLayout) { ((TiCompositeLayout) layout).setProxy(proxy); } }
@Override /** * When this activity is destroyed, this method removes it from the activity stack, performs clean * up, and fires javascript 'destroy' event. */ protected void onDestroy() { Log.d(TAG, "Activity " + this + " onDestroy", Log.DEBUG_MODE); inForeground = false; TiApplication tiApp = getTiApp(); // Clean up dialogs when activity is destroyed. releaseDialogs(true); if (tiApp.isRestartPending()) { super.onDestroy(); if (!isFinishing()) { finish(); } return; } synchronized (lifecycleListeners.synchronizedList()) { for (OnLifecycleEvent listener : lifecycleListeners.nonNull()) { try { TiLifecycle.fireLifecycleEvent(this, listener, TiLifecycle.LIFECYCLE_ON_DESTROY); } catch (Throwable t) { Log.e(TAG, "Error dispatching lifecycle event: " + t.getMessage(), t); } } } super.onDestroy(); boolean isFinishing = isFinishing(); // If the activity is finishing, remove the windowId and supportHelperId so the window and // supportHelper can be released. // If the activity is forced to destroy by Android OS, keep the windowId and supportHelperId so // the activity can be recovered. if (isFinishing) { int windowId = getIntentInt(TiC.INTENT_PROPERTY_WINDOW_ID, -1); TiActivityWindows.removeWindow(windowId); TiActivitySupportHelpers.removeSupportHelper(supportHelperId); } fireOnDestroy(); if (layout instanceof TiCompositeLayout) { Log.e(TAG, "Layout cleanup.", Log.DEBUG_MODE); ((TiCompositeLayout) layout).removeAllViews(); } layout = null; // LW windows if (window == null && view != null) { view.releaseViews(); view = null; } if (window != null) { window.closeFromActivity(isFinishing); window = null; } if (menuHelper != null) { menuHelper.destroy(); menuHelper = null; } if (activityProxy != null) { activityProxy.release(); activityProxy = null; } // Don't dispose the runtime if the activity is forced to destroy by Android, // so we can recover the activity later. KrollRuntime.decrementActivityRefCount(isFinishing); KrollRuntime.suggestGC(); }
@Override public void removeWindow(View v) { layout.removeView(v); }
@Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); measuredHeight = measuredWidth = 0; }
public void setRowData(TableViewRowProxy rp) { KrollDict props = rp.getProperties(); hasControls = rp.hasControls(); Object newSelectorSource = null; if (rp.hasProperty(TiC.PROPERTY_BACKGROUND_SELECTED_IMAGE)) { newSelectorSource = rp.getProperty(TiC.PROPERTY_BACKGROUND_SELECTED_IMAGE); } else if (rp.hasProperty(TiC.PROPERTY_BACKGROUND_SELECTED_COLOR)) { newSelectorSource = rp.getProperty(TiC.PROPERTY_BACKGROUND_SELECTED_COLOR); } if (newSelectorSource == null || selectorSource != null && !selectorSource.equals(newSelectorSource)) { selectorDrawable = null; } selectorSource = newSelectorSource; if (selectorSource != null) { rp.getTable().getTableView().getTableView().enableCustomSelector(); } setBackgroundFromProperties(props); // Handle right image boolean clearRightImage = true; // It's one or the other, check or child. If you set them both, child's gonna win. if (props.containsKey(TiC.PROPERTY_HAS_CHECK)) { if (TiConvert.toBoolean(props, TiC.PROPERTY_HAS_CHECK)) { if (hasCheckDrawable == null) { hasCheckDrawable = createHasCheckDrawable(); } rightImage.setImageDrawable(hasCheckDrawable); rightImage.setVisibility(VISIBLE); clearRightImage = false; } } if (props.containsKey(TiC.PROPERTY_HAS_CHILD)) { if (TiConvert.toBoolean(props, TiC.PROPERTY_HAS_CHILD)) { if (hasChildDrawable == null) { hasChildDrawable = createHasChildDrawable(); } rightImage.setImageDrawable(hasChildDrawable); rightImage.setVisibility(VISIBLE); clearRightImage = false; } } if (props.containsKey(TiC.PROPERTY_RIGHT_IMAGE)) { String path = TiConvert.toString(props, TiC.PROPERTY_RIGHT_IMAGE); String url = tiContext.resolveUrl(null, path); Drawable d = loadDrawable(url); if (d != null) { rightImage.setImageDrawable(d); rightImage.setVisibility(VISIBLE); clearRightImage = false; } } if (clearRightImage) { rightImage.setImageDrawable(null); rightImage.setVisibility(GONE); } // Handle left image if (props.containsKey(TiC.PROPERTY_LEFT_IMAGE)) { String path = TiConvert.toString(props, TiC.PROPERTY_LEFT_IMAGE); String url = tiContext.resolveUrl(null, path); Drawable d = loadDrawable(url); if (d != null) { leftImage.setImageDrawable(d); leftImage.setVisibility(VISIBLE); } } else { leftImage.setImageDrawable(null); leftImage.setVisibility(GONE); } if (props.containsKey(TiC.PROPERTY_HEIGHT)) { if (!props.get(TiC.PROPERTY_HEIGHT).equals(TiC.SIZE_AUTO)) { height = TiConvert.toTiDimension( TiConvert.toString(props, TiC.PROPERTY_HEIGHT), TiDimension.TYPE_HEIGHT); } } if (props.containsKey(TiC.PROPERTY_LAYOUT)) { content.setLayoutArrangement(TiConvert.toString(props, TiC.PROPERTY_LAYOUT)); } if (rp.hasControls()) { refreshControls(); } else { refreshOldStyleRow(); } }
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int w = MeasureSpec.getSize(widthMeasureSpec); int wMode = MeasureSpec.getMode(widthMeasureSpec); int h = MeasureSpec.getSize(heightMeasureSpec); int hMode = MeasureSpec.getMode(heightMeasureSpec); int imageHMargin = 0; int leftImageWidth = 0; int leftImageHeight = 0; if (leftImage != null && leftImage.getVisibility() != View.GONE) { measureChild(leftImage, widthMeasureSpec, heightMeasureSpec); leftImageWidth = leftImage.getMeasuredWidth(); leftImageHeight = leftImage.getMeasuredHeight(); imageHMargin += LEFT_MARGIN; } int rightImageWidth = 0; int rightImageHeight = 0; if (rightImage != null && rightImage.getVisibility() != View.GONE) { measureChild(rightImage, widthMeasureSpec, heightMeasureSpec); rightImageWidth = rightImage.getMeasuredWidth(); rightImageHeight = rightImage.getMeasuredHeight(); imageHMargin += RIGHT_MARGIN; } int adjustedWidth = w - leftImageWidth - rightImageWidth - imageHMargin; // int adjustedWidth = w; if (content != null) { measureChild(content, MeasureSpec.makeMeasureSpec(adjustedWidth, wMode), heightMeasureSpec); if (hMode == MeasureSpec.UNSPECIFIED) { TableViewProxy table = ((TableViewRowProxy) item.proxy).getTable(); int minRowHeight = -1; if (table != null && table.hasProperty(TiC.PROPERTY_MIN_ROW_HEIGHT)) { minRowHeight = TiConvert.toTiDimension( TiConvert.toString(table.getProperty(TiC.PROPERTY_MIN_ROW_HEIGHT)), TiDimension.TYPE_HEIGHT) .getAsPixels(this); } if (height == null) { h = Math.max( h, Math.max( content.getMeasuredHeight(), Math.max(leftImageHeight, rightImageHeight))); h = Math.max(h, minRowHeight); } else { h = Math.max(minRowHeight, height.getAsPixels(this)); } if (DBG) { Log.d(LCAT, "Row content measure (" + adjustedWidth + "x" + h + ")"); } measureChild( content, MeasureSpec.makeMeasureSpec(adjustedWidth, wMode), MeasureSpec.makeMeasureSpec(h, hMode)); } } setMeasuredDimension(w, Math.max(h, Math.max(leftImageHeight, rightImageHeight))); }