所以我对这个Activity有不同的布局.
我有不同的类,每个类都打开并用布局做他们的事情.
我通过@Inject在Activity中注入这些类.这一切都没有问题.
但是当我尝试在非活动布局中的一个控件上使用@InjectView时,我收到错误.
11-02 19:17:31.086:ERROR/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);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我可以这样做.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法呢?
我刚刚开始使用 roboguice,所以其他有更多经验的人可能能够给出更好的答案,但这是我到目前为止发现的:
在 roboguice-1.1.2(当前稳定版本)中,只有在 Activity 中第一次调用@InjectView时才会注入项目。setContentView()由于您的代码setContentView()从辅助类动态调用,因此注入的项目将无法正确注入。
在 roboguice-2.0b2(当前测试版)中,支持多个setContentView()调用,您的代码应该可以工作。但是,注入的视图仍然与上下文 Activity(而不是声明类)相关联,因此每个视图@InjectView也可能需要@Nullable跨共享同一 Activity 的所有辅助类。
由于这里的问题似乎根源于setContentView()单个 Activity 中的多个布局(因此多个调用),因此执行您想要的操作的另一种方法是避免它,如下所示:
<include/>将所有布局加载到父 FrameLayout 中:Run Code Online (Sandbox Code Playgroud)<?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 上的可见布局,如下所示:Run Code Online (Sandbox Code Playgroud)// 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 版本。这里的权衡是我们同时加载多个布局,而不是在几个不同的时间加载每个布局。它似乎对我来说足够好(尽管它可能会根据您的需求而有所不同)。
我应该注意的一件事是,在当前的“从RoboGuice 1.1升级到2.0”页面上,提到了以下内容:
在视图中使用 @InjectView 的能力(尽管您需要自己调用 RoboGuice.injectMembers() ,因为没有 RoboView 基类,而且可能永远不会)。
看来这应该允许您实现从 View 派生的辅助类,并使@InjectView它们更好地工作(希望不需要它们,@Nullable因为它们与 Activity 的联系较少)。然而,从目前的代码来看,这个功能似乎还没有实现(尽管我可能看错了地方)。
| 归档时间: |
|
| 查看次数: |
5513 次 |
| 最近记录: |