23

我正在尝试使用 Butter Knife 来简化自定义 BaseAdapter 类的创建。我在这里遵循示例:http: //jakewharton.github.io/butterknife/在“另一个用途是简化列表适配器内的视图持有者模式”下。部分。不幸的是,每次为列表中的每个项目创建 ViewHolder 时,我都会收到“无法注入视图”错误。

这是我的代码:

public class ButterknifeCustomBaseAdapter extends BaseAdapter{
@Override
public int getCount() {
    return arrayListNames.size();
}

@Override
public Name getItem(int iPosition) {
    return arrayListNames.get(iPosition);
}

@Override
public long getItemId(int iID) {
    return 0;
}

LayoutInflater inflater;
ArrayList<Name> arrayListNames = new ArrayList<Name>();
static Context context;
Activity activity;

public ButterknifeCustomBaseAdapter(Context context, ArrayList<Name> names, Activity activity) {
    arrayListNames = names;
    this.context = context;
    inflater = LayoutInflater.from(this.context);
}



static class ViewHolder implements View.OnClickListener {
    @InjectView(R.id.textViewFullName) TextView textViewFullName;
    @InjectView(R.id.imageButtonDeleteName) TextView imageButtonDeleteName;
    @OnClick(R.id.imageButtonDeleteName)
    public void onClick(View view) {
        ((NameActivity)context).DeleteUser((Name)view.getTag());
    }

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

@Override public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder viewHolder;

    if (convertView != null) {
        viewHolder = (ViewHolder) convertView.getTag();
    } else {
        convertView = inflater.inflate(R.layout.item_name, parent, false);
        viewHolder = new ViewHolder(convertView);
        convertView.setTag(viewHolder);
    }

    viewHolder.textViewFullName.setText(((Name)getItem(position)).GetFullName());
    L.l("ArrayAdapterName", ((Name)getItem(position)).GetID() + " inserted in list | position = " + position);
    viewHolder.imageButtonDeleteName.setTag((Name)getItem(position));
    return convertView;
}

}

错误发生在“ButterKnife.Inject(this, view);” 线。每次为我放入列表中的每个项目创建视图持有者时也会发生这种情况。有人知道如何使这项工作以应有的方式工作吗?

回复 Jake Wharton 的评论 首先,我要感谢您开发此工具。与我刚开始时相比,它使 android 开发变得更加愉快。

这是完整的堆栈跟踪:

05-04 07:29:01.991    2424-2424/com.murach.databasehomework E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to inject views for com.murach.databasehomework.ButterknifeCustomBaseAdapter$ViewHolder@52700878
            at butterknife.ButterKnife.inject(ButterKnife.java:221)
            at butterknife.ButterKnife.inject(ButterKnife.java:184)
            at com.murach.databasehomework.ButterknifeCustomBaseAdapter$ViewHolder.<init>(ButterknifeCustomBaseAdapter.java:59)
            at com.murach.databasehomework.ButterknifeCustomBaseAdapter.getView(ButterknifeCustomBaseAdapter.java:70)
            at android.widget.AbsListView.obtainView(AbsListView.java:2177)
            at android.widget.ListView.makeAndAddView(ListView.java:1840)
            at android.widget.ListView.fillDown(ListView.java:675)
            at android.widget.ListView.fillFromTop(ListView.java:736)
            at android.widget.ListView.layoutChildren(ListView.java:1655)
            at android.widget.AbsListView.onLayout(AbsListView.java:2012)
            at android.view.View.layout(View.java:14289)
            at android.view.ViewGroup.layout(ViewGroup.java:4562)
            at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1076)
            at android.view.View.layout(View.java:14289)
            at android.view.ViewGroup.layout(ViewGroup.java:4562)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
            at android.view.View.layout(View.java:14289)
            at android.view.ViewGroup.layout(ViewGroup.java:4562)
            at com.android.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:349)
            at android.view.View.layout(View.java:14289)
            at android.view.ViewGroup.layout(ViewGroup.java:4562)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
            at android.view.View.layout(View.java:14289)
            at android.view.ViewGroup.layout(ViewGroup.java:4562)
            at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1976)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1730)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1004)
            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5481)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
            at android.view.Choreographer.doCallbacks(Choreographer.java:562)
            at android.view.Choreographer.doFrame(Choreographer.java:532)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
            at android.os.Handler.handleCallback(Handler.java:730)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5103)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.reflect.InvocationTargetException
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at butterknife.ButterKnife.inject(ButterKnife.java:216)
            at butterknife.ButterKnife.inject(ButterKnife.java:184)
            at com.murach.databasehomework.ButterknifeCustomBaseAdapter$ViewHolder.<init>(ButterknifeCustomBaseAdapter.java:59)
            at com.murach.databasehomework.ButterknifeCustomBaseAdapter.getView(ButterknifeCustomBaseAdapter.java:70)
            at android.widget.AbsListView.obtainView(AbsListView.java:2177)
            at android.widget.ListView.makeAndAddView(ListView.java:1840)
            at android.widget.ListView.fillDown(ListView.java:675)
            at android.widget.ListView.fillFromTop(ListView.java:736)
            at android.widget.ListView.layoutChildren(ListView.java:1655)
            at android.widget.AbsListView.onLayout(AbsListView.java:2012)
            at android.view.View.layout(View.java:14289)
            at android.view.ViewGroup.layout(ViewGroup.java:4562)
            at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1076)
            at android.view.View.layout(View.java:14289)
            at android.view.ViewGroup.layout(ViewGroup.java:4562)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
            at android.view.View.layout(View.java:14289)
            at android.view.ViewGroup.layout(ViewGroup.java:4562)
            at com.android.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:349)
            at android.view.View.layout(View.java:14289)
            at android.view.ViewGroup.layout(ViewGroup.java:4562)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
            at android.view.View.layout(View.java:14289)
            at android.view.ViewGroup.layout(ViewGroup.java:4562)
            at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1976)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1730)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1004)
            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5481)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
            at android.view.Choreographer.doCallbacks(Choreographer.java:562)
            at android.view.Choreographer.doFrame(Choreographer.java:532)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
            at android.os.Handler.handleCallback(Handler.java:730)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5103)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.ClassCastException: android.widget.ImageButton cannot be cast to android.widget.TextView
            at com.murach.databasehomework.ButterknifeCustomBaseAdapter$ViewHolder$$ViewInjector.inject(ButterknifeCustomBaseAdapter$ViewHolder$$ViewInjector.java:13)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at butterknife.ButterKnife.inject(ButterKnife.java:216)
            at butterknife.ButterKnife.inject(ButterKnife.java:184)
            at com.murach.databasehomework.ButterknifeCustomBaseAdapter$ViewHolder.<init>(ButterknifeCustomBaseAdapter.java:59)
            at com.murach.databasehomework.ButterknifeCustomBaseAdapter.getView(ButterknifeCustomBaseAdapter.java:70)
            at android.widget.AbsListView.obtainView(AbsListView.java:2177)
            at android.widget.ListView.makeAndAddView(ListView.java:1840)
            at android.widget.ListView.fillDown(ListView.java:675)
            at android.widget.ListView.fillFromTop(ListView.java:736)
            at android.widget.ListView.layoutChildren(ListView.java:1655)
            at android.widget.AbsListView.onLayout(AbsListView.java:2012)
            at android.view.View.layout(View.java:14289)
            at android.view.ViewGroup.layout(ViewGroup.java:4562)
            at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1076)
            at android.view.View.layout(View.java:14289)
            at android.view.ViewGroup.layout(ViewGroup.java:4562)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
            at android.view.View.layout(View.java:14289)
            at android.view.ViewGroup.layout(ViewGroup.java:4562)
            at com.android.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:349)
            at android.view.View.layout(View.java:14289)
            at android.view.ViewGroup.layout(ViewGroup.java:4562)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
            at android.view.View.layout(View.java:14289)
            at android.view.ViewGroup.layout(ViewGroup.java:4562)
            at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1976)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1730)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1004)
            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5481)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
            at android.view.Choreographer.doCallbacks(Choreographer.java:562)
            at android.view.Choreographer.doFrame(Choreographer.java:532)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
            at android.os.Handler.handleCallback(Handler.java:730)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5103)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)
4

5 回答 5

48

检查您@InjectView的 s 是否具有正确的类型。我用过ImageView而不是LinearLayout. 那也可能是你的问题。

更新:

确保您没有使用@OnItemClick(R.id.non_list_view)带有非ListView. 我将它用于android.support.v7.widget.RecyclerView导致以下异常的情况:

java.lang.RuntimeException: Unable to inject views for MyFragment{... id=.... android:switcher:...}
于 2014-06-17T23:05:03.840 回答
7

还要检查你是否在膨胀正确的R.layout.文件。如果没有 - 未找到必要的视图,则会发生此错误。

于 2014-11-24T23:46:03.237 回答
3

我在使用 ButterKnife 时遇到了类似的问题,但原因是我用错误的布局来膨胀我的片段。

我知道这个问题已经回答了,但我决定发布我的解决方案以防有人遇到同样的问题

于 2014-10-03T14:47:39.517 回答
1

如果您试图从 Java 文件中的 XML 绑定错误的 View 类型,那些仍在寻找它的人就会发生这种情况。

例如

你有带有 id 结果的 TextView

 <TextView
        android:id="@+id/result"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:gravity="center"
        android:layout_centerHorizontal="true"
        android:layout_margin="3dp"
        android:layout_weight="2"
        android:background="#fff"
        android:text="Calculator"
        android:textSize="25sp" />

并且您尝试将其与 java 文件中的 Button 绑定

@BindView(R.id.result) 按钮结果;

它让你的应用程序崩溃了。

Butterknife 会因为无法注入视图错误而将非法视图转换为异常

于 2016-06-07T07:38:19.560 回答
1

对我来说,事实证明ViewBinder没有正确刷新。一个干净的项目构建解决了这个问题。

于 2016-07-14T14:18:56.460 回答