From 82e0dab94c11f5382396dda45af4cdff686589e3 Mon Sep 17 00:00:00 2001 From: Manij Date: Sat, 14 Mar 2015 00:26:16 -0500 Subject: [PATCH] Added @OnAutoCompleteItemClick annotation to bind onItemClickListener on AutoCompleteTextView Added missing documentation --- .../main/java/butterknife/ButterKnife.java | 1 + .../butterknife/OnAutoCompleteItemClick.java | 47 ++++ .../internal/ButterKnifeProcessor.java | 2 + .../internal/OnAutoCompleteItemClickTest.java | 203 ++++++++++++++++++ 4 files changed, 253 insertions(+) create mode 100644 butterknife/src/main/java/butterknife/OnAutoCompleteItemClick.java create mode 100644 butterknife/src/test/java/butterknife/internal/OnAutoCompleteItemClickTest.java diff --git a/butterknife/src/main/java/butterknife/ButterKnife.java b/butterknife/src/main/java/butterknife/ButterKnife.java index badcfd0bb..b2904e7b1 100644 --- a/butterknife/src/main/java/butterknife/ButterKnife.java +++ b/butterknife/src/main/java/butterknife/ButterKnife.java @@ -72,6 +72,7 @@ * * @see InjectView * @see InjectViews + * @see OnAutoCompleteItemClick * @see OnCheckedChanged * @see OnClick * @see OnEditorAction diff --git a/butterknife/src/main/java/butterknife/OnAutoCompleteItemClick.java b/butterknife/src/main/java/butterknife/OnAutoCompleteItemClick.java new file mode 100644 index 000000000..08096907c --- /dev/null +++ b/butterknife/src/main/java/butterknife/OnAutoCompleteItemClick.java @@ -0,0 +1,47 @@ +package butterknife; + +import android.view.View; +import butterknife.internal.ListenerClass; +import butterknife.internal.ListenerMethod; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static android.widget.AdapterView.OnItemClickListener; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.CLASS; + +/** + * Bind a method to an + * {@link android.widget.AutoCompleteTextView OnItemClickListener} on the view for each ID + * specified. + *

+ * {@literal @}OnItemClick(R.id.example_list) void onItemClick(int position) {
+ *   Toast.makeText(this, "Clicked position " + position + "!", LENGTH_SHORT).show();
+ * }
+ * 
+ * Any number of parameters from + * {@link OnItemClickListener#onItemClick(android.widget.AdapterView, + * android.view.View, int, long) onItemClick} may be used on the method. + * + * @see OnItemClickListener + * @see Optional + */ +@Target(METHOD) +@Retention(CLASS) +@ListenerClass( + targetType = "android.widget.AutoCompleteTextView", + setter = "setOnItemClickListener", + type = "android.widget.AdapterView.OnItemClickListener", + method = @ListenerMethod( + name = "onItemClick", + parameters = { + "android.widget.AdapterView", + "android.view.View", + "int", + "long" + } + ) +) +public @interface OnAutoCompleteItemClick { + int[] value() default { View.NO_ID }; +} diff --git a/butterknife/src/main/java/butterknife/internal/ButterKnifeProcessor.java b/butterknife/src/main/java/butterknife/internal/ButterKnifeProcessor.java index 2fe8878ea..6fbc7c092 100644 --- a/butterknife/src/main/java/butterknife/internal/ButterKnifeProcessor.java +++ b/butterknife/src/main/java/butterknife/internal/ButterKnifeProcessor.java @@ -3,6 +3,7 @@ import android.view.View; import butterknife.InjectView; import butterknife.InjectViews; +import butterknife.OnAutoCompleteItemClick; import butterknife.OnCheckedChanged; import butterknife.OnClick; import butterknife.OnEditorAction; @@ -63,6 +64,7 @@ public final class ButterKnifeProcessor extends AbstractProcessor { static final String VIEW_TYPE = "android.view.View"; private static final String LIST_TYPE = List.class.getCanonicalName(); private static final List> LISTENERS = Arrays.asList(// + OnAutoCompleteItemClick.class, // OnCheckedChanged.class, // OnClick.class, // OnEditorAction.class, // diff --git a/butterknife/src/test/java/butterknife/internal/OnAutoCompleteItemClickTest.java b/butterknife/src/test/java/butterknife/internal/OnAutoCompleteItemClickTest.java new file mode 100644 index 000000000..3f0d52ad6 --- /dev/null +++ b/butterknife/src/test/java/butterknife/internal/OnAutoCompleteItemClickTest.java @@ -0,0 +1,203 @@ +package butterknife.internal; + +import com.google.common.base.Joiner; +import com.google.testing.compile.JavaFileObjects; +import org.junit.Test; + +import javax.tools.JavaFileObject; + +import static butterknife.internal.ProcessorTestUtilities.butterknifeProcessors; +import static com.google.common.truth.Truth.ASSERT; +import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource; + +public class OnAutoCompleteItemClickTest { + @Test public void onClickInjection() { + JavaFileObject source = JavaFileObjects.forSourceString("test.Test", Joiner.on('\n').join( + "package test;", + "import android.app.Activity;", + "import butterknife.OnAutoCompleteItemClick;", + "public class Test extends Activity {", + " @OnAutoCompleteItemClick(1) void doStuff() {}", + "}")); + + JavaFileObject expectedSource = JavaFileObjects.forSourceString("test/Test$$ViewInjector", + Joiner.on('\n').join( + "package test;", + "import android.view.View;", + "import butterknife.ButterKnife.Finder;", + "import butterknife.ButterKnife.Injector;", + "public class Test$$ViewInjector implements Injector {", + " @Override public void inject(final Finder finder, final T target, Object source) {", + " View view;", + " view = finder.findRequiredView(source, 1, \"method 'doStuff'\");", + " ((android.widget.AutoCompleteTextView) view).setOnItemClickListener(", + " new android.widget.AdapterView.OnItemClickListener() {", + " @Override public void onItemClick(", + " android.widget.AdapterView p0, android.view.View p1, int p2, long p3) {", + " target.doStuff();", + " }", + " });", + " }", + " @Override public void reset(T target) {", + " }", + "}" + )); + + ASSERT.about(javaSource()).that(source) + .processedWith(butterknifeProcessors()) + .compilesWithoutError() + .and() + .generatesSources(expectedSource); + } + + @Test public void onClickInjectionWithParameters() { + JavaFileObject source = JavaFileObjects.forSourceString("test.Test", Joiner.on('\n').join( + "package test;", + "import android.app.Activity;", + "import android.view.View;", + "import android.widget.AdapterView;", + "import butterknife.OnAutoCompleteItemClick;", + "public class Test extends Activity {", + " @OnAutoCompleteItemClick(1) void doStuff(", + " AdapterView parent,", + " View view,", + " int position,", + " long id", + " ) {}", + "}")); + + JavaFileObject expectedSource = JavaFileObjects.forSourceString("test/Test$$ViewInjector", + Joiner.on('\n').join( + "package test;", + "import android.view.View;", + "import butterknife.ButterKnife.Finder;", + "import butterknife.ButterKnife.Injector;", + "public class Test$$ViewInjector implements Injector {", + " @Override public void inject(final Finder finder, final T target, Object source) {", + " View view;", + " view = finder.findRequiredView(source, 1, \"method 'doStuff'\");", + " ((android.widget.AutoCompleteTextView) view).setOnItemClickListener(", + " new android.widget.AdapterView.OnItemClickListener() {", + " @Override public void onItemClick(", + " android.widget.AdapterView p0, android.view.View p1, int p2, long p3) {", + " target.doStuff(p0, p1, p2, p3);", + " }", + " });", + " }", + " @Override public void reset(T target) {", + " }", + "}" + )); + + ASSERT.about(javaSource()).that(source) + .processedWith(butterknifeProcessors()) + .compilesWithoutError() + .and() + .generatesSources(expectedSource); + } + + @Test public void onClickRootViewInjection() { + JavaFileObject source = JavaFileObjects.forSourceString("test.Test", Joiner.on('\n').join( + "package test;", + "import android.content.Context;", + "import android.widget.AutoCompleteTextView;", + "import butterknife.OnAutoCompleteItemClick;", + "public class Test extends AutoCompleteTextView {", + " @OnAutoCompleteItemClick void doStuff() {}", + " public Test(Context context) {", + " super(context);", + " }", + "}")); + + JavaFileObject expectedSource = JavaFileObjects.forSourceString("test/Test$$ViewInjector", + Joiner.on('\n').join( + "package test;", + "import android.view.View;", + "import butterknife.ButterKnife.Finder;", + "import butterknife.ButterKnife.Injector;", + "public class Test$$ViewInjector implements Injector {", + " @Override public void inject(final Finder finder, final T target, Object source) {", + " View view;", + " view = target;", + " ((android.widget.AutoCompleteTextView) view).setOnItemClickListener(", + " new android.widget.AdapterView.OnItemClickListener() {", + " @Override public void onItemClick(", + " android.widget.AdapterView p0,", + " android.view.View p1,", + " int p2,", + " long p3", + " ) {", + " target.doStuff();", + " }", + " });", + " }", + " @Override public void reset(T target) {", + " }", + "}" + )); + + ASSERT.about(javaSource()).that(source) + .processedWith(butterknifeProcessors()) + .compilesWithoutError() + .and() + .generatesSources(expectedSource); + } + + @Test public void failsWithInvalidId() { + JavaFileObject source = JavaFileObjects.forSourceString("test.Test", Joiner.on('\n').join( + "package test;", + "import android.content.Context;", + "import android.app.Activity;", + "import butterknife.OnAutoCompleteItemClick;", + "public class Test extends Activity {", + " @OnAutoCompleteItemClick({1, -1}) void doStuff() {}", + "}")); + + ASSERT.about(javaSource()).that(source) + .processedWith(butterknifeProcessors()) + .failsToCompile() + .withErrorContaining("@OnAutoCompleteItemClick annotation contains invalid ID -1. (test.Test.doStuff)") + .in(source).onLine(6); + } + + @Test public void failsWithInvalidParameterConfiguration() { + JavaFileObject source = JavaFileObjects.forSourceString("test.Test", Joiner.on('\n').join( + "package test;", + "import android.app.Activity;", + "import android.view.View;", + "import android.widget.AdapterView;", + "import butterknife.OnAutoCompleteItemClick;", + "public class Test extends Activity {", + " @OnAutoCompleteItemClick(1) void doStuff(", + " AdapterView parent,", + " View view,", + " View whatIsThis", + " ) {}", + "}")); + + ASSERT.about(javaSource()).that(source) + .processedWith(butterknifeProcessors()) + .failsToCompile() + .withErrorContaining(Joiner.on('\n').join( + "Unable to match @OnAutoCompleteItemClick method arguments. (test.Test.doStuff)", + " ", + " Parameter #1: android.widget.AdapterView", + " matched listener parameter #1: android.widget.AdapterView", + " ", + " Parameter #2: android.view.View", + " matched listener parameter #2: android.view.View", + " ", + " Parameter #3: android.view.View", + " did not match any listener parameters", + " ", + " Methods may have up to 4 parameter(s):", + " ", + " android.widget.AdapterView", + " android.view.View", + " int", + " long", + " ", + " These may be listed in any order but will be searched for from top to bottom.")) + .in(source).onLine(7); + } +}