diff --git a/AndroidAnnotations/androidannotations-core/androidannotations-api/src/main/java/org/androidannotations/api/view/HasViews.java b/AndroidAnnotations/androidannotations-core/androidannotations-api/src/main/java/org/androidannotations/api/view/HasViews.java index d1d5c99bd7..2fca41fb73 100644 --- a/AndroidAnnotations/androidannotations-core/androidannotations-api/src/main/java/org/androidannotations/api/view/HasViews.java +++ b/AndroidAnnotations/androidannotations-core/androidannotations-api/src/main/java/org/androidannotations/api/view/HasViews.java @@ -1,5 +1,6 @@ /** * Copyright (C) 2010-2016 eBusiness Information, Excilys Group + * Copyright (C) 2016-2017 the AndroidAnnotations 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 @@ -18,5 +19,5 @@ import android.view.View; public interface HasViews { - View findViewById(int id); + T internalFindViewById(int id); } diff --git a/AndroidAnnotations/androidannotations-core/androidannotations-test/src/test/java/org/androidannotations/test/ebean/SomeSingletonTest.java b/AndroidAnnotations/androidannotations-core/androidannotations-test/src/test/java/org/androidannotations/test/ebean/SomeSingletonTest.java index 850f4af285..1f36137d45 100644 --- a/AndroidAnnotations/androidannotations-core/androidannotations-test/src/test/java/org/androidannotations/test/ebean/SomeSingletonTest.java +++ b/AndroidAnnotations/androidannotations-core/androidannotations-test/src/test/java/org/androidannotations/test/ebean/SomeSingletonTest.java @@ -58,8 +58,8 @@ public void viewsAreNotInjected() throws Exception { notifier.notifyViewChanged(new HasViews() { @Override - public View findViewById(int id) { - return mock(View.class); + public T internalFindViewById(int id) { + return (T) mock(View.class); } }); diff --git a/AndroidAnnotations/androidannotations-core/androidannotations-test/src/test/java/org/androidannotations/test/efragment/MyListFragmentTest.java b/AndroidAnnotations/androidannotations-core/androidannotations-test/src/test/java/org/androidannotations/test/efragment/MyListFragmentTest.java index 87ea95667e..05bf734479 100644 --- a/AndroidAnnotations/androidannotations-core/androidannotations-test/src/test/java/org/androidannotations/test/efragment/MyListFragmentTest.java +++ b/AndroidAnnotations/androidannotations-core/androidannotations-test/src/test/java/org/androidannotations/test/efragment/MyListFragmentTest.java @@ -55,7 +55,7 @@ public void setUp() { @Test public void isItemClickAvailableFromListFragment() { startFragment(myListFragment); - ListView listView = (ListView) myListFragment.findViewById(android.R.id.list); + ListView listView = (ListView) myListFragment.internalFindViewById(android.R.id.list); long itemId = listView.getAdapter().getItemId(TESTED_CLICKED_INDEX); View view = listView.getChildAt(TESTED_CLICKED_INDEX); diff --git a/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/holder/EActivityHolder.java b/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/holder/EActivityHolder.java index 86d251fa99..133b223945 100644 --- a/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/holder/EActivityHolder.java +++ b/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/holder/EActivityHolder.java @@ -394,6 +394,11 @@ private JMethod setContentViewMethod(AbstractJType[] paramTypes, String[] paramN return method; } + @Override + public IJExpression getFindViewByIdExpression(JVar idParam) { + return JExpr._this().invoke("findViewById").arg(idParam); + } + public JVar getInitSavedInstanceParam() { return initSavedInstanceParam; } diff --git a/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/holder/EComponentWithViewSupportHolder.java b/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/holder/EComponentWithViewSupportHolder.java index c9bb48a9d0..330f5d54e2 100644 --- a/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/holder/EComponentWithViewSupportHolder.java +++ b/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/holder/EComponentWithViewSupportHolder.java @@ -71,10 +71,14 @@ public abstract class EComponentWithViewSupportHolder extends EComponentHolder i public EComponentWithViewSupportHolder(AndroidAnnotationsEnvironment environment, TypeElement annotatedElement) throws Exception { super(environment, annotatedElement); - viewNotifierHelper = new ViewNotifierHelper(this); + viewNotifierHelper = new ViewNotifierHelper(this, environment); keyEventCallbackMethodsDelegate = new KeyEventCallbackMethodsDelegate<>(this); } + public IJExpression getFindViewByIdExpression(JVar idParam) { + return _null(); + } + public JBlock getOnViewChangedBody() { if (onViewChangedBody == null) { setOnViewChanged(); @@ -132,7 +136,7 @@ protected void setOnViewChanged() { } public JInvocation findViewById(JFieldRef idRef) { - JInvocation findViewById = invoke(getOnViewChangedHasViewsParam(), "findViewById"); + JInvocation findViewById = invoke(getOnViewChangedHasViewsParam(), "internalFindViewById"); findViewById.arg(idRef); return findViewById; } @@ -157,8 +161,6 @@ protected FoundViewHolder createFoundViewAndIfNotNullBlock(JFieldRef idRef, Abst if (viewClass == null) { viewClass = getClasses().VIEW; - } else if (viewClass != getClasses().VIEW) { - findViewExpression = cast(viewClass, findViewExpression); } IJAssignmentTarget foundView = fieldRef; diff --git a/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/holder/EFragmentHolder.java b/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/holder/EFragmentHolder.java index 89e2157c1d..a930d8ed73 100644 --- a/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/holder/EFragmentHolder.java +++ b/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/holder/EFragmentHolder.java @@ -21,6 +21,7 @@ import static com.helger.jcodemodel.JExpr._new; import static com.helger.jcodemodel.JExpr._null; import static com.helger.jcodemodel.JExpr._super; +import static com.helger.jcodemodel.JExpr.cond; import static com.helger.jcodemodel.JExpr.invoke; import static com.helger.jcodemodel.JExpr.ref; import static com.helger.jcodemodel.JMod.PRIVATE; @@ -38,12 +39,14 @@ import com.helger.jcodemodel.AbstractJClass; import com.helger.jcodemodel.IJAssignmentTarget; +import com.helger.jcodemodel.IJExpression; import com.helger.jcodemodel.JBlock; import com.helger.jcodemodel.JClassAlreadyExistsException; import com.helger.jcodemodel.JDefinedClass; import com.helger.jcodemodel.JExpr; import com.helger.jcodemodel.JFieldRef; import com.helger.jcodemodel.JFieldVar; +import com.helger.jcodemodel.JInvocation; import com.helger.jcodemodel.JMethod; import com.helger.jcodemodel.JMod; import com.helger.jcodemodel.JVar; @@ -100,7 +103,6 @@ private void setOnCreate() { JBlock onCreateBody = onCreate.body(); JVar previousNotifier = viewNotifierHelper.replacePreviousNotifier(onCreateBody); - setFindViewById(); onCreateBody.invoke(getInit()).arg(onCreateSavedInstanceState); onCreateBody.invoke(_super(), onCreate).arg(onCreateSavedInstanceState); onCreateAfterSuperBlock = onCreateBody.blockSimple(); @@ -117,20 +119,10 @@ private void setOnViewCreated() { viewNotifierHelper.invokeViewChanged(onViewCreatedBody); } - private void setFindViewById() { - JMethod findViewById = generatedClass.method(PUBLIC, getClasses().VIEW, "findViewById"); - findViewById.annotate(Override.class); - - JVar idParam = findViewById.param(getCodeModel().INT, "id"); - - JBlock body = findViewById.body(); - + public IJExpression getFindViewByIdExpression(JVar idParam) { JFieldVar contentView = getContentView(); - - body._if(contentView.eq(_null())) // - ._then()._return(_null()); - - body._return(contentView.invoke(findViewById).arg(idParam)); + JInvocation invocation = contentView.invoke("findViewById").arg(idParam); + return cond(contentView.eq(_null()), _null(), invocation); } private void setFragmentBuilder() throws JClassAlreadyExistsException { diff --git a/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/holder/EViewHolder.java b/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/holder/EViewHolder.java index e9add2060b..3f0e968669 100644 --- a/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/holder/EViewHolder.java +++ b/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/holder/EViewHolder.java @@ -35,6 +35,7 @@ import org.androidannotations.AndroidAnnotationsEnvironment; import com.helger.jcodemodel.AbstractJClass; +import com.helger.jcodemodel.IJExpression; import com.helger.jcodemodel.JBlock; import com.helger.jcodemodel.JExpr; import com.helger.jcodemodel.JFieldVar; @@ -207,6 +208,11 @@ public JBlock getOnDetachBeforeSuperBlock() { return getOnDetachedToWindowBeforeSuperBlock(); } + @Override + public IJExpression getFindViewByIdExpression(JVar idParam) { + return JExpr._this().invoke("findViewById").arg(idParam); + } + @Override public JFieldVar getIntentFilterField(ReceiverRegistrationDelegate.IntentFilterData intentFilterData) { return receiverRegistrationDelegate.getIntentFilterField(intentFilterData); diff --git a/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/internal/helper/ViewNotifierHelper.java b/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/internal/helper/ViewNotifierHelper.java index e77085f59c..ea4f1acf9b 100644 --- a/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/internal/helper/ViewNotifierHelper.java +++ b/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/internal/helper/ViewNotifierHelper.java @@ -1,5 +1,6 @@ /** * Copyright (C) 2010-2016 eBusiness Information, Excilys Group + * Copyright (C) 2016-2017 the AndroidAnnotations 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 @@ -20,25 +21,34 @@ import static com.helger.jcodemodel.JExpr._this; import static com.helger.jcodemodel.JMod.FINAL; import static com.helger.jcodemodel.JMod.PRIVATE; +import static com.helger.jcodemodel.JMod.PUBLIC; import static org.androidannotations.helper.ModelConstants.generationSuffix; +import org.androidannotations.AndroidAnnotationsEnvironment; import org.androidannotations.api.view.HasViews; import org.androidannotations.api.view.OnViewChangedNotifier; -import org.androidannotations.holder.EComponentHolder; +import org.androidannotations.holder.EComponentWithViewSupportHolder; import org.androidannotations.holder.EViewHolder; import com.helger.jcodemodel.AbstractJClass; +import com.helger.jcodemodel.IJExpression; import com.helger.jcodemodel.JBlock; +import com.helger.jcodemodel.JCodeModel; +import com.helger.jcodemodel.JDirectClass; +import com.helger.jcodemodel.JExpr; import com.helger.jcodemodel.JFieldVar; +import com.helger.jcodemodel.JMethod; import com.helger.jcodemodel.JVar; public class ViewNotifierHelper { - private EComponentHolder holder; + private AndroidAnnotationsEnvironment environment; + private EComponentWithViewSupportHolder holder; private JFieldVar notifier; - public ViewNotifierHelper(EComponentHolder holder) { + public ViewNotifierHelper(EComponentWithViewSupportHolder holder, AndroidAnnotationsEnvironment environment) { this.holder = holder; + this.environment = environment; } public void invokeViewChanged(JBlock block) { @@ -49,11 +59,25 @@ public JVar replacePreviousNotifier(JBlock block) { AbstractJClass notifierClass = holder.getEnvironment().getJClass(OnViewChangedNotifier.class); if (notifier == null) { notifier = holder.getGeneratedClass().field(PRIVATE | FINAL, notifierClass, "onViewChangedNotifier" + generationSuffix(), _new(notifierClass)); - holder.getGeneratedClass()._implements(HasViews.class); + implementHasViewsInHolder(); } return block.decl(notifierClass, "previousNotifier", notifierClass.staticInvoke("replaceNotifier").arg(notifier)); } + private void implementHasViewsInHolder() { + holder.getGeneratedClass()._implements(HasViews.class); + JCodeModel codeModel = environment.getCodeModel(); + + JDirectClass genericType = codeModel.directClass("T"); + JMethod findViewById = holder.getGeneratedClass().method(PUBLIC, genericType, "internalFindViewById"); + findViewById.generify("T", environment.getClasses().VIEW); + findViewById.annotate(Override.class); + + JVar idParam = findViewById.param(codeModel.INT, "id"); + IJExpression findViewByIdExpression = holder.getFindViewByIdExpression(idParam); + findViewById.body()._return(JExpr.cast(genericType, findViewByIdExpression)); + } + public JVar replacePreviousNotifierWithNull(JBlock block) { AbstractJClass notifierClass = holder.getEnvironment().getJClass(OnViewChangedNotifier.class); return block.decl(notifierClass, "previousNotifier", notifierClass.staticInvoke("replaceNotifier").arg(_null()));