【问题标题】:Injectview (Roboguice) not working with multiple layoutsInjectview (Roboguice) 不能使用多个布局
【发布时间】:2011-11-02 18:39:23
【问题描述】:

所以我对这个 Activity 有不同的布局。

我有不同的课程,每个课程都打开并使用布局做他们的事情。

我通过@Inject 在 Activity 中注入这些类。这一切都没有问题。

但是,当我尝试在非活动布局中的其中一个控件上使用 @InjectView 时,我得到一个错误。

11-02 19:17:31.086:错误/AndroidRuntime(1326):由以下原因引起: java.lang.NullPointerException:无法将空值注入类 be.baes.notes.View.EditNoteImpl.saveButton 当字段不是@Nullable

这就是代码。

public class EditNoteImpl implements EditNote {
    @Inject CancelEditNoteClickListener cancelEditNoteClickListener;
    @Inject SaveNoteClickListener saveNoteClickListener;
    @Inject Provider<Activity> activity;
    @InjectView(R.id.saveButton) Button saveButton;

    /* (non-Javadoc)
     * @see be.baes.notes.EditNote#activateEditNote()
     */
    @Override
    public void activateEditNote()
    {
        activity.get().setContentView(R.layout.editnote);

        this.saveButton.setOnClickListener(saveNoteClickListener);
    }
}

但是我可以这样做。

public class EditNoteImpl implements EditNote {
    @Inject CancelEditNoteClickListener cancelEditNoteClickListener;
    @Inject SaveNoteClickListener saveNoteClickListener;
    @Inject Provider<Activity> activity;
    private Button saveButton;

    /* (non-Javadoc)
     * @see be.baes.notes.EditNote#activateEditNote()
     */
    @Override
    public void activateEditNote()
    {
        activity.get().setContentView(R.layout.editnote);
        saveButton = (Button)activity.get().findViewById(R.id.saveButton);

        this.saveButton.setOnClickListener(saveNoteClickListener);
    }
}

有更好的方法吗?

【问题讨论】:

  • 是否有理由使按钮@Nullable 不是一个选项?
  • 我试过了,但也没有注入按钮。
  • 您使用的是 RoboGuice 2.0 吗?这可能适用于 2.0
  • 我使用的是 1.2,因为那是稳定版本。我会尝试 2.0。
  • RoboGuice 2.0 支持@Nullable。看到这个问题stackoverflow.com/questions/15200701/…

标签: android roboguice


【解决方案1】:

我刚刚开始使用 roboguice,所以有更多经验的人可能会给出更好的答案,但这是我目前发现的:

  • 在 roboguice-1.1.2(当前稳定版本)中,@InjectView 项目仅在 Activity 中第一次调用 setContentView() 时注入。由于您的代码从辅助类动态调用setContentView(),因此那里的注入项目将无法正确注入。

  • 在 roboguice-2.0b2(当前测试版)中,支持多个 setContentView() 调用,您的代码应该可以工作。但是,注入的视图仍然与上下文 Activity(而不是声明类)相关联,因此每个 @InjectView 可能还需要在共享同一 Activity 的所有辅助类中为 @Nullable

由于这里的问题似乎源于单个 Activity 中的多个布局(以及因此多个 setContentView() 调用),因此另一种方法是避免它,如下所示:

  • 使用&lt;include/&gt; 标签将所有布局加载到父 FrameLayout 中,而不是使用多个布局:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <include layout="@layout/layout1" />

    <include layout="@layout/layout2" />

    <!-- other layouts... -->

</FrameLayout>
  • 然后,不要调用 setContentView(),而是使用一种方法来切换 Activity 上的可见布局,如下所示:
// instead of: activity.setContentView(R.layout.layout1);
// use: activity.showLayout(R.id.layoutview1);
public void showLayout(int layoutViewId) {
    final View view = findViewById(layoutViewId);
    final ViewGroup root = (ViewGroup) view.getParent();
    for (int i = 0; i < root.getChildCount(); i++) {
        final View v = root.getChildAt(i);
        v.setVisibility(v == view ? View.VISIBLE : View.GONE);
    }
}

上述替代方案应该适用于稳定版和 beta roboguice 版本。这里的权衡是我们同时加载多个布局,而不是在几个不同的时间加载每个布局。它似乎对我来说足够好用(尽管它可能因您的需要而异)。

我要注意的一点是,在当前的"Upgrading from RoboGuice 1.1 to 2.0" 页面上,提到了以下内容:

在视图中使用 @InjectView 的能力(尽管您需要调用 RoboGuice.injectMembers() 自己,因为没有 RoboView 基础 类,可能永远不会)。

似乎这应该允许您实现从 View 派生的辅助类,并使 @InjectView 在其中更好地工作(希望它们不需要成为 @Nullable,因为它们与 Activity 的联系较少)。不过看目前的代码,这个功能好像还没有实现(虽然我可能看错地方了)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多