butterknife icon indicating copy to clipboard operation
butterknife copied to clipboard

Support Custom Annotations

Open YGStar opened this issue 9 years ago • 6 comments

thanks for butterknife.

I found butterknife anntations managed by ButterKnifeProcessor class -private static final List<Class<? extends Annotation>> LISTENERS

I want to make some custom annotation with butterknife.

let me know how I add custom annotation myself.

is it possible?

YGStar avatar Apr 24 '16 07:04 YGStar

Hey,

To make custom annotations are not related with ButterKnife. It is built by using annotations. ButterKnife's annotations are also custom ones. So, yes, it is possible. ButterKnifeProcessor class extends AbstractProcessor which implements Processor interface. All of the annotations are parsed by the Processor. You can check this and this for further information.

anlcnydn avatar May 01 '16 14:05 anlcnydn

@JakeWharton would you be willing to take a look at a PR for something along these lines if I were to work on it?

JayNewstrom avatar May 09 '16 15:05 JayNewstrom

Sure!

On Mon, May 9, 2016 at 11:48 AM Jay Newstrom [email protected] wrote:

@JakeWharton https://github.com/JakeWharton would you be willing to take a look at a PR for something along these lines if I were to work on it?

— You are receiving this because you were mentioned.

Reply to this email directly or view it on GitHub https://github.com/JakeWharton/butterknife/issues/497#issuecomment-217904065

JakeWharton avatar May 09 '16 15:05 JakeWharton

HI @JakeWharton I need to know if i can implement this feature in ButterKnife. That's what I'm thinking about

  • Add new Annotation which is called AnnotationAdapter with ANNOTATION_TYPE target under butterknife-annotations module, take one attribute which is Class<?>, this annotation used for annotate custom annotation and pass implementation class to it as attribute e.g (@AnnotationAdapter(ViewPager2Listener.class)) the ViewPager2Listener is a class for deal with ViewPager2 and register listener to it
  • Add new interface which is called ButterKnifeAdapter for example and this interface take one generic parameter which is the view you need to create custom annotation for it to use it with AnnotationAdapter
  • Add another interface which is called ButterKnifeListener for example this interface to link custom listener with code generation

Full example

AnnotationAdapter

@Target(ElementType.ANNOTATION_TYPE)
public @interface AnnotationAdapter {

    Class<? extends ButterKnifeAdapter> value();
}

ButterKnifeAdapter

public interface ButterKnifeAdapter<T> {
}

ButterKnifeListener

public interface ButterKnifeListener<T> {
    void invoke(T t);
}

OnPageChangeListener2 (My custom annotation)

@AnnotationAdapter(ViewPager2Listener.class)
public @interface OnPageChangeListener2 {
    int value();
}

ViewPager2Listener(My custom listener)

public class ViewPager2Listener implements ButterKnifeAdapter<ViewPager2> {

    public ViewPager2Listener(ViewPager2 viewPager2, ButterKnifeListener<Integer> listener) {
        viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
            @Override
            public void onPageSelected(int position) {
                super.onPageSelected(position);
                listener.invoke(position);
            }
        });
    }
}

MainActivity

public class MainActivity extends AppCompatActivity {
    
    @OnPageChangeListener2(R.id.viewpager2)
    void onPageChange(int position) {
        
    }
}

I do not know if there is a better way to do that but that's what I thought of, also i think i need another annotation like @SupportCustomListeners for example to annotate activity, fragment etc... to scan classes and search for custom annotations which is annotated with @AnnotationAdapter

winfoozmnayef avatar Feb 15 '19 11:02 winfoozmnayef

I worked on something for this a while back. https://github.com/JakeWharton/butterknife/pull/573

I'd be happy to help if there's anything we can do to get support merged.

JayNewstrom avatar Feb 15 '19 13:02 JayNewstrom

@JayNewstrom After i saw your pull request i have changed my thought about custom annotations i think it will be implemented like this

OnPageChangeListener2 (My custom annotation)

@ListenerClass(
    targetType = "androidx.viewpager2.widget.ViewPager2",
    setter = "registerOnPageChangeCallback",
    remover = "unregisterOnPageChangeCallback"
    type = "androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback",
    method = @ListenerMethod(
        name = "onPageSelected",
        parameters = "Integer"
    )
)
public @interface OnPageChangeListener2 {
    int value();
}

MainActivity

public class MainActivity extends AppCompatActivity {

    @OnPageChangeListener2(R.id.viewpager2)
    void onPageChange(int position) {
    }
}

And ListenerClass must be added to LISTENERS in ButterKnifeProcessor and generate code based on ListenerClass attrs

winfoozmnayef avatar Feb 15 '19 17:02 winfoozmnayef