GithubHelp home page GithubHelp logo

jakewharton / butterknife Goto Github PK

View Code? Open in Web Editor NEW
25.6K 1.0K 4.6K 3.82 MB

Bind Android views and callbacks to fields and methods.

Home Page: http://jakewharton.github.io/butterknife/

License: Apache License 2.0

Shell 0.32% Java 94.00% HTML 3.02% CSS 0.38% Kotlin 2.28%

butterknife's Introduction

Butter Knife

Attention: This tool is now deprecated. Please switch to view binding. Existing versions will continue to work, obviously, but only critical bug fixes for integration with AGP will be considered. Feature development and general bug fixes have stopped.

Logo

Field and method binding for Android views which uses annotation processing to generate boilerplate code for you.

  • Eliminate findViewById calls by using @BindView on fields.
  • Group multiple views in a list or array. Operate on all of them at once with actions, setters, or properties.
  • Eliminate anonymous inner-classes for listeners by annotating methods with @OnClick and others.
  • Eliminate resource lookups by using resource annotations on fields.
class ExampleActivity extends Activity {
  @BindView(R.id.user) EditText username;
  @BindView(R.id.pass) EditText password;

  @BindString(R.string.login_error) String loginErrorMessage;

  @OnClick(R.id.submit) void submit() {
    // TODO call server...
  }

  @Override public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.simple_activity);
    ButterKnife.bind(this);
    // TODO Use fields...
  }
}

For documentation and additional information see the website.

Remember: A butter knife is like a dagger, only infinitely less sharp.

Download

android {
  ...
  // Butterknife requires Java 8.
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

dependencies {
  implementation 'com.jakewharton:butterknife:10.2.3'
  annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.3'
}

If you are using Kotlin, replace annotationProcessor with kapt.

Snapshots of the development version are available in Sonatype's snapshots repository.

Library projects

To use Butter Knife in a library, add the plugin to your buildscript:

buildscript {
  repositories {
    mavenCentral()
    google()
  }
  dependencies {
    classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.3'
  }
}

and then apply it in your module:

apply plugin: 'com.android.library'
apply plugin: 'com.jakewharton.butterknife'

Now make sure you use R2 instead of R inside all Butter Knife annotations.

class ExampleActivity extends Activity {
  @BindView(R2.id.user) EditText username;
  @BindView(R2.id.pass) EditText password;
...
}

License

Copyright 2013 Jake Wharton

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 the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

butterknife's People

Contributors

alexkrupa avatar bananeweizen avatar christiankatzmann avatar corycharlton avatar egor-n avatar ersin-ertan avatar f2prateek avatar felipecsl avatar gavra0 avatar holmes avatar imminent avatar jakewharton avatar jaredsburrows avatar jaynewstrom avatar jlleitschuh avatar kageiit avatar kierans avatar lptr avatar lukaciko avatar michaelevans avatar naturalwarren avatar nguyentruongtho avatar plastiv avatar scottkennedy avatar simonvt avatar tomxor avatar tonsv2 avatar vanniktech avatar wuseal avatar zacsweers avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

butterknife's Issues

SherlockFragmentActivity and Inject Issues

None of my views are injected they all equal null. Proguard is disabled, Annotations are enabled and jar added.

Here is the excert:

public class DetailsActivity extends SherlockFragmentActivity {

private ImageLoader imageLoader;

@InjectView(R.id.map) MapView map;
@InjectView(R.id.icon) ImageView icon;
@InjectView(R.id.title) TextView title;
@InjectView(R.id.subtitle) TextView subtitle;
@InjectView(R.id.description) TextView description;
@InjectView(R.id.details) LinearLayout details;

public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.details);
    Views.inject(this);

    //Prevent Black Flickering with Google Maps
    details.requestTransparentRegion(map);

Injecting failed

Seem to be having issue injecting the views, even with the sample code in the repo.

I've tried using the straight JAR file, referencing it to export with apk etc but all no go.
FWIW i'm not using proguard, but I do have Lombok installed in Eclipse (Which shouldent be an issue). No stacktrace available as the injected views are just not being set

Add butterknife-1.2.2.jar to my project,but cann't run the app. How to use?

I create a android app, add butterknife-1.2.2.jar to my project.

Write some code like this

public class MainActivity extends Activity {

@InjectView(R.id.hello) TextView tvHello;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Views.inject(this);
    // tvHellp = (TextView) findViewById(R.id.hello);
    tvHello.setText("knife ok!!");
}

}

then run the application.

Problem:
The app throw some exception.

03-14 14:18:41.169: E/AndroidRuntime(2306): FATAL EXCEPTION: main
03-14 14:18:41.169: E/AndroidRuntime(2306): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.testknife/com.example.testknife.MainActivity}: butterknife.Views$UnableToInjectException: Unable to inject views for com.example.testknife.MainActivity@45ff94f8
03-14 14:18:41.169: E/AndroidRuntime(2306): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2787)
03-14 14:18:41.169: E/AndroidRuntime(2306): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2803)
03-14 14:18:41.169: E/AndroidRuntime(2306): at android.app.ActivityThread.access$2300(ActivityThread.java:135)
03-14 14:18:41.169: E/AndroidRuntime(2306): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2136)
03-14 14:18:41.169: E/AndroidRuntime(2306): at android.os.Handler.dispatchMessage(Handler.java:99)
03-14 14:18:41.169: E/AndroidRuntime(2306): at android.os.Looper.loop(Looper.java:144)
03-14 14:18:41.169: E/AndroidRuntime(2306): at android.app.ActivityThread.main(ActivityThread.java:4937)
03-14 14:18:41.169: E/AndroidRuntime(2306): at java.lang.reflect.Method.invokeNative(Native Method)
03-14 14:18:41.169: E/AndroidRuntime(2306): at java.lang.reflect.Method.invoke(Method.java:521)
03-14 14:18:41.169: E/AndroidRuntime(2306): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
03-14 14:18:41.169: E/AndroidRuntime(2306): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
03-14 14:18:41.169: E/AndroidRuntime(2306): at dalvik.system.NativeStart.main(Native Method)
03-14 14:18:41.169: E/AndroidRuntime(2306): Caused by: butterknife.Views$UnableToInjectException: Unable to inject views for com.example.testknife.MainActivity@45ff94f8
03-14 14:18:41.169: E/AndroidRuntime(2306): at butterknife.Views.inject(Views.java:116)
03-14 14:18:41.169: E/AndroidRuntime(2306): at butterknife.Views.inject(Views.java:65)
03-14 14:18:41.169: E/AndroidRuntime(2306): at com.example.testknife.MainActivity.onCreate(MainActivity.java:17)
03-14 14:18:41.169: E/AndroidRuntime(2306): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1069)
03-14 14:18:41.169: E/AndroidRuntime(2306): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2751)
03-14 14:18:41.169: E/AndroidRuntime(2306): ... 11 more
03-14 14:18:41.169: E/AndroidRuntime(2306): Caused by: java.lang.ClassNotFoundException: com.example.testknife.MainActivity$$ViewInjector
03-14 14:18:41.169: E/AndroidRuntime(2306): at java.lang.Class.classForName(Native Method)
03-14 14:18:41.169: E/AndroidRuntime(2306): at java.lang.Class.forName(Class.java:235)
03-14 14:18:41.169: E/AndroidRuntime(2306): at java.lang.Class.forName(Class.java:182)
03-14 14:18:41.169: E/AndroidRuntime(2306): at butterknife.Views.inject(Views.java:108)
03-14 14:18:41.169: E/AndroidRuntime(2306): ... 15 more
03-14 14:18:41.169: E/AndroidRuntime(2306): Caused by: java.lang.NoClassDefFoundError: com.example.testknife.MainActivity$$ViewInjector
03-14 14:18:41.169: E/AndroidRuntime(2306): ... 19 more
03-14 14:18:41.169: E/AndroidRuntime(2306): Caused by: java.lang.ClassNotFoundException: com.example.testknife.MainActivity$$ViewInjector in loader dalvik.system.PathClassLoader[/data/app/com.example.testknife-2.apk]
03-14 14:18:41.169: E/AndroidRuntime(2306): at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:243)
03-14 14:18:41.169: E/AndroidRuntime(2306): at java.lang.ClassLoader.loadClass(ClassLoader.java:573)
03-14 14:18:41.169: E/AndroidRuntime(2306): at java.lang.ClassLoader.loadClass(ClassLoader.java:532)
03-14 14:18:41.169: E/AndroidRuntime(2306): ... 19 more

Any wrong whit my project?

Inject multiple layout files into same target view

I have a ListFragment which's ListView has a footer. Fragment and footer layouts are declared in separate layout files. The views of both layouts are declared as fields all together in my ListFragment class.

Now in my fragment I tried to inject the views of both layouts:

View view = inflater.inflate(layout.fragment_marketplace_list, container);
Views.inject(this, view);

View listFooter = inflater.inflate(layout.list_footer_marketplace, container);
Views.inject(this, listFooter);

Unfortunately this results in "butterknife.Views$UnableToInjectException" at the first inject(...) call.
I guess this is because butterknife does not find the views in the first layout for all the footer fields.

Would it make sense to add something like a "strict" flag (which would be set to false here) to the inject(...) method, to make the desired behavior possible? Meaning optionally ignoring fields that are not found in the layout during injection.

Add Support For Non-Final IDs

Android's resource system is disaster and to unbreak library projects last year they made the IDs non-final.

@InjectView(id = "title") TextView title

Context context = activity.getApplicationContext();
String packageName = context.getPackageName();
Resources res = context.getResources();
// ...
int id = res.getIdentifier(packageName, "android:id", annotation.id());

Moar robustness?

What do you think of doing a sort of LRU cache pattern for INJECTORS, to improve scalability? I don't know if it is easy to become problematic, but in theory, an app could have tons of things injecting Views. Was just thinking about that.

Add Support For Fragments And Views

What this really means is extend support to any class type so long as you provide a root View on which to perform injection. Should be extremely simple.

Require views to be present. Add @Optional for those that are not.

@InjectView(R.id.foo) View foo

would throw an injection exception if R.id.foo is not found.

@Optional @InjectView(R.id.foo) View foo

would allow R.id.foo to be missing.

By default views will be required because failing fast is what you want, even if you don't know it yet.

Inject Fragments Proposal

I know you said no to the various proposal of adding other Injection features to butter knife. But when I think about it, it seems that an @InjectFragment would really be the perfect companion for @InjectView, enabling the developers to reference every element in the xml while avoiding the verbose getFragmentManager().findFragmentById(). I started developing something along those lines, enjoying the added benefit of eliminating the confusion between support fragment manager, fragment activities etc. If you're interested in expanding butter knife in that direction I can come up with a decent pull request.

Injecting Views in Parent Class throws IllegalAccessError

I've got a super class in a.b.widget and a child class in a.b.something. If the fields are set to anything but public an IllegalAccessError is thrown.

        java.lang.RuntimeException: Unable to start activity ComponentInfo{com.squareup.cardcase.development/com.squareup.cardcase.home.WalletHomeActivity}: butterknife.Views$UnableToInjectException: Unable to inject views for com.squareup.cardcase.home.ActivityHistoryPanel{4176d420 V.E..... ......I. 0,0-0,0}
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
        at android.app.ActivityThread.access$600(ActivityThread.java:141)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:5041)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
        at dalvik.system.NativeStart.main(Native Method)
        Caused by: butterknife.Views$UnableToInjectException: Unable to inject views for com.squareup.cardcase.home.ActivityHistoryPanel{4176d420 V.E..... ......I. 0,0-0,0}
        at butterknife.Views.inject(Views.java:125)
        at butterknife.Views.inject(Views.java:77)
        at com.squareup.cardcase.ui.widget.MessageAndListView.<init>(MessageAndListView.java:22)
        at com.squareup.cardcase.home.ActivityHistoryPanel.<init>(ActivityHistoryPanel.java:37)
        at com.squareup.cardcase.home.HomeFragment.buildView(HomeFragment.java:46)
        at com.squareup.cardcase.ui.AbstractWalletFragment.onCreateView(AbstractWalletFragment.java:48)
        at android.app.Fragment.performCreateView(Fragment.java:1695)
        at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:885)
        at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1057)
        at android.app.BackStackRecord.run(BackStackRecord.java:682)
        at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1435)
        at android.app.Activity.performStart(Activity.java:5113)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2153)
        ... 11 more
        Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at butterknife.Views.inject(Views.java:117)
        ... 23 more
        Caused by: java.lang.IllegalAccessError: tried to access field com.squareup.cardcase.home.ActivityHistoryPanel.messageSheet from class com.squareup.cardcase.home.ActivityHistoryPanel$$ViewInjector
        at com.squareup.cardcase.home.ActivityHistoryPanel$$ViewInjector.inject(ActivityHistoryPanel$$ViewInjector.java from OutputFileObject:8)
        ... 26 more

Injection for fragment superclass

Hi Jake, thanks a lot for the library! I've been using it for the last day and a bit and it looks pretty awesome!

I've got two fragments: one a parent which has an ImageView, and a child which has a bunch of other views.

When I call Views.inject(this, view) in onCreateView, The only views that appear to be injected are the ones on the child. The ones on the parent never seem to be hooked up (they just turn out to be null).

I can work around this by re-declaring the parent's views in the child, but it's a little messy.

I'm not sure whether the library supports this feature yet, or whether I'm missing something/doing something stupid. Any guidance?

Cheers!

Library project issue

Hi,

I have 4 project.
common

model
service
view

view only see service, service only see model, all of these see common.
I put butterknife lib to common, set the annotations processing. In the view project i can use annotations, but eclipse say for @InjectView value: "The value for annotation attribute InjectView.value must be a constant expression"

@InjectView(R.id.toastviewcontainer)
ToastContainerView toastContainerView;

The .aptgenerated folder created and contains this:
"public class MainActivity$$ViewInjector {
public static void inject(Finder finder, hbogo.view.activity.MainActivity target, Object source) {
View view;
view = finder.findById(source, 0);
target.toastContainerView = (hbogo.view.toast.ToastContainerView) view;
}

public static void reset(hbogo.view.activity.MainActivity target) {
target.toastContainerView = null;
}
}"

How can I correctly use butterknife in library projects?

Sry my bad english ;)

AnnotationTypeMismatchException on gradle

Hi,

I'm porting my app from eclipse to android-studio/gradle and i'm facing the following problem when added butterknife as maven dependency:

Gradle: Execution failed for task ':Weelo:compileDebug'.

java.lang.annotation.AnnotationTypeMismatchException: Incorrectly typed data found for annotation element public abstract int butterknife.InjectView.value() (Found data of type int)

Heres the build.gradle section for butterknife:

dependencies {
compile group: 'com.jakewharton', name: 'butterknife', version: '2.0.1'
}

Any thoughts?

Cast Error Problem in Eclipse

I am getting @InjectView must get View object although I use TextView in Eclipse. When I clean project it is solved but it is happening very frequently. I have to clean the project in every 5 minutes.

ButterKnife and ProGuard (again)

Hey.

I'm trying to run proguard on my application, which use butterknife.
I added
-keep class **$$ViewInjector
to the proguard config file, and I have this error

Android Dex: [ctc-mobile-android] Warning: butterknife.Views$InjectViewProcessor: can't find superclass or interface javax.annotation.processing.AbstractProcessor

I don't know what to do here...
If you guys have a solution...
Thanks.

Injection isn't happening when combined with a Robolectric test suite.

I've added some injection view @InjectView on an Activity under Robolectric test. The views are always null after the Views.inject(this) call after the setContentView() call. I am using a pretty standard Maven build script based off of Android Bootstrap, and have had no luck with the unit test calling activity.onCreate(null) during the test. Tracing through the code, it doesn't seem to be picking up the @InjectView annotations, and simply does the 'no operation' case. What have I done wrong? Is there a trick to getting a unit test running?

View injection fails silently if generated class cannot be located

If the injection class cannot be loaded, because the parent class was renamed by Proguard, the injection fails silently and the view references are null. Most code is then bound to crash with a NullpointerException. I'd prefer if butter knife would fail fast and throw an exception when it can't perform injection for some reason so that it is clear what the problem is.

Check that the annotated type extends View

Butt erk nife should check that the annotated type extends View. Which is quite straightforward:

    public boolean isSubtype(TypeMirror potentialSubtype, TypeMirror potentialSupertype) {
        return processingEnv.getTypeUtils().isSubtype(potentialSubtype, potentialSupertype);
    }

Guess where that code is coming from? A project from the world of Magic ;)

null out injections proposal

I'm new to Android, and studying Fragments.

In the case of a retained instance, is it not a problem that by using Butter Knife I am, by default, holding onto "injected" views?

When the Activity bounces, Android zaps our views. Android wants those views gone. But we are holding onto them.

Perhaps a second method
View.clear(this)
that will null out the @InjectView targets? I can call this in the proper Fragment lifecycle method (which I dunno cuz I'm still a learnin')

Or is it not that big of a deal because the fragment exists in the detached state for such a short amount of time before the new views get injected?

Matt

ViewInjector classes missing from deployed APK

After deploying my app (https://github.com/fallenarchon/FuelTracker) to devices for test, I'm getting a NullPointerException when my activity first tries to reference a view that is supposed to be injected. I'm in the middle of converting from using Eclipse to Intellij + maven, so my issue could very well be configuration problem. I've added the suggested proguard changes to my proguard.cfg file, so I'm at a loss for what to do next.

Reproduction steps:
git clone repo

  1. mvn clean install
  2. mvn android:deploy
  3. mvn android:run
    in app
  4. Push 'New Vehicle' button in action bar
  5. Enter vehicle name in dialog box and press 'Ok'
  6. Select vehicle name in list view
  7. Watch app crash as SampleFragment.onCreateView():29 or FuelStatsActivity.configureViewPager():69 calls a method on a null View object that was supposed to be injected

Add Log Toggle

Views.setDebug(true) to log when classes are found/not found, etc.

Redundant cast to android.view.View

Hi. I'm getting this warning then I want to find View inside of my layout:

MyActivity$$ViewInjector.java:[34,27] redundant cast to android.view.View

I'm fail to compile then due to my strict compilation settings:

MyActivity$$ViewInjector.java: warnings found and -Werror specified.

I really need to find just a View, not it's subclass, it's enough for me.

It would be great if butterknife just suppress this warning, because it knows that it does. Optionally don't cast if target class is View.

Superclass injection gets removed

I'm using IDEA12.
Setup is: class B extends A, both classes have some @InjectView fields.
A "Rebuild Project" creates:
A$$ViewInjector and B$$ViewInjector, the latter with a call to A$$ViewInjector.inject(finder, target, source)
I edit B and deploy to my device. Compiling starts and the call to A$$ViewInjector.inject() gets removed -> App crashes because my injected fields in B are now null.

Inject Fragment

Would be nice to have a InjectFragment so that I can inject a SupportMapFragment from the google maps.

I can always do a pull request to add this in for you but I'm just checking if this is the correct syntax ?

i.e

class MainActivity extends Activity {
  @InjectFragment(r.id.map) MapFragment map;

Feature: Menu/Menu Item Injection

Hey Jake,

Not sure of the feasibility of this but it'd be sweet to have the same functionality that this provides for views with Menu Items as well. I know that MenuItem doesn't extend View so it's not directly supported right now.

Inject Fragment Proposal

It would be great to have an annotation @InjectFragment()
with parameters
id to use findFragmentById()
tag to use findFragmentByTag()
support to use the support fragment manager instead of original

to allow all combinations and I think it is very difficult

Superclass injection

Hi, Jake

I found that if you change superclass injection Test to the following

    public class BaseTest {
      public static class Thing extends Activity {
        @InjectView(1) View thing1;
        @InjectView(2) View thing2;
        @InjectView(3) View thing3;
      }
    }

    public class Test extends BaseTest.Thing {
    }

than injection to Test will not work

InjectView not work

I have a ListFragment in a ViewPager (Android 4.0.3)

Copy code form sample and print log, holder.name is null

public class MyAdapter extends BaseAdapter {
@OverRide public void getView(int position, View view, ViewGroup parent) {
ViewHolder holder;
if (view != null) {
holder = (ViewHolder) view.getTag();
} else {
view = inflater.inflate(R.layout.whatever, parent, false);
holder = new ViewHolder(view);
view.setTag(holder);
}

holder.name.setText("John Doe");
// etc...

return convertView;

}

static class ViewHolder {
@InjectView(R.id.title) TextView name;

public ViewHolder(View view) {
  Views.inject(this, view);
}

}
}

Listener Injection Proposal

@InjectView(R.id.call) TextView call;
@InjectView(R.id.call) OnClickListener callClickListener = new OnClickListener() { };
@InjectView(R.id.thing) OnDragListener thingDragListener = new OnDragListener() { };

which would amount to:

call = (TextView) activity.findViewById(R.id.call);
call.setOnClickListener(callClickListener);
activity.findViewById(R.id.thing).setOnDragListener(thingDragListener);

View Injection Fails with Android Bootstrap

View Injection is failing in Android Bootstrap. The error that is happening is:

java.lang.ClassNotFoundException: com.donnfelker.android.bootstrap.ui.CarouselActivity$$ViewInjector

From what I can tell we're doing everything correctly as according to the docs, but it seems to be broken now. Any ideas what might be causing this?

Note, the line where the app is bombing out is: https://github.com/JakeWharton/butterknife/blob/master/butterknife/src/main/java/butterknife/Views.java#L109, then an exception is caught and the app moves on, the views are then null .

OnClick issues

when i change my code then

@OnClick method parameter must extend from View (... .public void tabClick(android.widget.RadioButton) error.

must clean eclipse once, it's ok.

@OnClick({ R.id.tabs_group_friends, R.id.tabs_group_friends_dis_group,
            R.id.tabs_group_friends_group, R.id.tabs_group_mesages })
    public void tabClick(RadioButton button) {

Calling super on a class with injects fails

Calling super on a method which has inject functionality in the parent class doesn't populate the views.

I had a look through the code and it looks like there is functionality for it to recurse through the parent classes. I would try fix it myself, but I don't know how to import/configure the sources :)

From sample sources:

public class SimpleActivity extends BaseActivity {
  //uncommenting this works.
  //@InjectView(R.id.title) TextView title;
  @InjectView(R.id.subtitle) TextView subtitle;
  @InjectView(R.id.footer) TextView footer;

  @Override protected void onCreate(Bundle savedInstanceState) {
    // calling super should populate BaseActivity.title
    super.onCreate(savedInstanceState);

    Views.inject(this);

    // Title is always null because super inject didnt work
    title.setText("Butter Knife");
    subtitle.setText("View \"injection\" for Android.");
    footer.setText("by Jake Wharton");
  }
}
public class BaseActivity extends Activity {
  @InjectView(R.id.title) TextView title;

  @Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.simple_activity);
    Views.inject(this);
  }
}

FWIW Im using the JAR lib v 1.3.0

Overriding setContentView

We've tried to create base Activity class and move the injections into an override on setContentView, but seeing errors on setContentView(int layoutResId). We're just calling super.setContentView(layoutResId) then calling Views.inject(this), which for all intents and purposes would be the same thing we'd be doing in custom activities, but, in a base class, it looks like the layout does not get a chance to be inflated before Views tries to inject them. It's really easy to recreate by just creating one activity that extends another and putting an override in the base class. In your activity, just call setContentView and pass the id as you would normally, injections should fail.

Cache Duplicate ID Lookups

Should be easy to do with sorting by ID and skipping duplicate lookups.

(mostly done in a local branch that I don't want to forget about)

Support @InjectView without value

I usually want to name the views the same way i name the ids so it would be nice if we could do something like @InjectView Button buttonLoginFacebook; and that to locate the id for the view based on the name and find its reference.

i assume this is a bit more difficult since it would require the library to look through the R file to find the match since right now we are passing the actual integer id, but i don't see why not have it as an option.

Proguard configuration

I had to add the proguard conf to make it work:
-dontwarn butterknife.Views$InjectViewProcessor

Do you think it would be better to move the InjectViewProcessor class in a separate project "butterknife-compiler" like dagger-compiler?

Layout Injection Proposal

@InjectLayout(R.layout.login_activity)
public class LoginActivity extends Activity {
  @InjectView(R.id.username) TextView username;
  @InjectView(R.id.password) TextView password;

  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Views.inject(this);
  }
}

which would amount to:

activity.setContentView(R.layout.login_activity);
username = (TextView) activity.findViewById(R.id.username);
password = (TextView) activity.findViewById(R.id.password);

and

@InjectLayout(R.layout.custom_view)
public class CustomView extends View {
  @InjectView(R.id.thing) TextView thing;

  public CustomView(Context context, AttributeSet attrs) {
    super(context, attrs);
    Views.inject(this);
  }
}

which would amount to:

View root = LayoutInflater.from(context).inflate(R.layout.custom_view, this);
thing = (TextView) root.findViewById(R.id.thing);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.