@OnClick array with optional ids (ButterKnife)
Asked Answered
W

3

30

I have an activity that inflates a view when a web request finished. Some of the widgets of this view have to be attached to one onClick method, so I have:

@OnClick({R.id.bt1, R.id.bt2, R.id.inflated_bt1, R.id.inflated_bt2})
public void onClick(View view) {
    // ...
}

As R.id.inflated_bt1 and R.id.inflated_bt2 don't exist when the app is created, it throws an exception suggesting to set an @Optional annotation.

Required view 'inflated_bt1' with ID XXXXXXXX for method 'onClick' was not found. If this view is optional add '@Optional' annotation.

Is there a way to set some of the views with the @Optional annotation and inject them when the view is inflated? Or, is there another way to do it?

Thank you

Whisenhunt answered 1/4, 2015 at 12:20 Comment(0)
L
36

The correct answer is to use the @Nullable annotation. See the Butterknife home page. Usage example:

import android.support.annotation.Nullable;

@Nullable
@OnClick(R.id.maybe_missing)
void onMaybeMissingClicked() {
    // TODO ...
}

EDIT:

In the year since I wrote this answer and it was accepted, the Butterknife docs changed, and the current preferred method for accomplishing this is to use the @Optional annotation. Since this is the accepted answer, I feel it important to update it to address current practice. For example:

import butterknife.Optional;

@Optional
@OnClick(R.id.maybe_missing)
void onMaybeMissingClicked() {
    // TODO ...
}
Latin answered 21/1, 2016 at 18:0 Comment(2)
According to the ButterKnife github page, add a @Nullable annotation to fields or the @Optional annotation to methods jakewharton.github.io/butterknifeHeiskell
@Heiskell Did you seriously downvote my answer? The docs changed. There wasn't an Optional when I answered this over a year ago. If the answer needs updating, update it!Latin
T
46

Just add @Optional annotation on the top of your method as is shown in the code below:

@Optional
@OnClick({R.id.bt1, R.id.bt2, R.id.inflated_bt1, R.id.inflated_bt2})
public void onClick(View view) {
    // ...
}

There is a case where you don't have R.id.inflated_bt1 in the layout xml which you use on your Activity. For case like this you have to use @Optional annotation.

When you use only @OnClick annotation in YourClass$$ViewInjector source code looks like below:

view = finder.findRequiredView(source, 2131230789, "method 'onClick'");
view.setOnClickListener(
  new butterknife.internal.DebouncingOnClickListener() {
    @Override public void doClick(
      android.view.View p0
    ) {
      target.onClick();
    }
  });

and the method findRequiredView throws IllegalStateException when view is null.

But when you use additionally @Optional annotation, generated code looks like below

view = finder.findOptionalView(source, 2131230789);
if (view != null) {
  view.setOnClickListener(
    new butterknife.internal.DebouncingOnClickListener() {
      @Override public void doClick(
        android.view.View p0
      ) {
        target.onClick();
      }
    });
}
Thorp answered 1/4, 2015 at 12:29 Comment(2)
How can I use ButterKnife.Finder? JavaDoc shows a "DO NOT USE" message, and I cannot create it: "cannot inherit from final class butterknife.ButterKnife.Finder"Whisenhunt
Why do you want to use thus class ?Thorp
L
36

The correct answer is to use the @Nullable annotation. See the Butterknife home page. Usage example:

import android.support.annotation.Nullable;

@Nullable
@OnClick(R.id.maybe_missing)
void onMaybeMissingClicked() {
    // TODO ...
}

EDIT:

In the year since I wrote this answer and it was accepted, the Butterknife docs changed, and the current preferred method for accomplishing this is to use the @Optional annotation. Since this is the accepted answer, I feel it important to update it to address current practice. For example:

import butterknife.Optional;

@Optional
@OnClick(R.id.maybe_missing)
void onMaybeMissingClicked() {
    // TODO ...
}
Latin answered 21/1, 2016 at 18:0 Comment(2)
According to the ButterKnife github page, add a @Nullable annotation to fields or the @Optional annotation to methods jakewharton.github.io/butterknifeHeiskell
@Heiskell Did you seriously downvote my answer? The docs changed. There wasn't an Optional when I answered this over a year ago. If the answer needs updating, update it!Latin
P
3
@Nullable
@OnClick({R.id.bt1, R.id.bt2, R.id.inflated_bt1, R.id.inflated_bt2})
public void onClick(View view) {
    // ...
}

If you include nullable as said by Butterknife docs and also by @AutonomousApps then you can include as may as ids even though you are not using them all the time.

Remember to include annotation support library if you are not using appcompact library. Check this link Support Annotations

Preterite answered 27/6, 2016 at 6:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.