I'm trying to write the below code without using the Butterknife method, mostly for learning purposes. Can anyone help with writing it without it's use please?
I'm guessing it's something along the lines of
TextView textName = findViewById(R.id.post_title);
but it doesn't seem the run the same so I'm guessing I'm missing something
public class FriendsHolder extends RecyclerView.ViewHolder {
@BindView(R.id.name)
TextView textName;
@BindView(R.id.image)
CircleImageView imageView;
@BindView(R.id.title)
TextView textTitle;
@BindView(R.id.company)
TextView textCompany;
public FriendsHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
Here is how you can do it when compile SDK version is greater than or equal to 26:
public class FriendsHolder extends RecyclerView.ViewHolder {
TextView textName;
CircleImageView imageView;
TextView textTitle;
TextView textCompany;
public FriendsHolder(View itemView) {
super(itemView);
textName = itemView.findViewById(R.id.name);
imageView = itemView.findViewById(R.id.image);
textTitle = itemView.findViewById(R.id.title);
textCompany = itemView.findViewById(R.id.company);
}
}
For API versions less than 26 you just need to explicit typecast the view returned by findViewById method to the field type.
As you probably know, ButterKnife is an annotation processor that takes your code at compile time, evaluates the annotations (eg. @BindView) and generates code to replace them with.
Now in the case of @BindView what the annotation processor actually does is:
and
So a functional equivalent of your example would be something like this:
public class FriendsHolder extends RecyclerView.ViewHolder {
private TextView textName;
private CircleImageView imageView;
private TextView textTitle;
private TextView textCompany;
FriendsHolder(View itemView) {
super(itemView);
bindViews(itemView);
}
private void bindViews(View root) {
textName = (TextView) root.findViewById(R.id.name);
imageView = (CircleImageView) root.findViewById(R.id.image);
textTitle = (TextView) root.findViewById(R.id.title);
textCompany = (TextView) root.findViewById(R.id.company);
}
}
You can read more about the underlying processes in this blog post or have a look at some of the ButterKnife source code.
Where you can see that essentially what they do is look for the ID on the source view and try to cast it to the expected type that was read from the annotated field.
Excerpt from butterknife.internal.Utils:
public static <T> T findRequiredViewAsType(View source, @IdRes int id, String who, Class<T> cls) {
View view = findRequiredView(source, id, who);
return castView(view, id, who, cls);
}
public static View findRequiredView(View source, @IdRes int id, String who) {
View view = source.findViewById(id);
if (view != null) {
return view;
}
// If view is null throw IllegalStateException
}
public static <T> T castView(View view, @IdRes int id, String who, Class<T> cls) {
try {
return cls.cast(view); // <-- casting
} catch (ClassCastException e) {
throw new IllegalStateException
// Exception handling...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With