我被困在这一段时间,我正在从一个活动中加载一个片段(替换另一个)。它加载很好,我可以看到它并返回到前一个片段,但是当我调用一个方法将数据加载到它时,我得到一个空指针异常。我的第一个代码是......
public class MainActivity extends Activity implements MainListFragment.MainListListener, StoryFragment.StoryListener {
MainListFragment mainListFragment;
StoryFragment storyFragment;
。 。
public void onMainListClick(DBRecordType recordType, int recordID){
switch(recordType){
case story:{
DBHandler dbHandler = new DBHandler(this, null, null, 1);
Story story = dbHandler.getStory(recordID);
Toast.makeText(getApplicationContext(), story.toString(), Toast.LENGTH_SHORT ).show();
storyFragment = new StoryFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.container, storyFragment);
transaction.addToBackStack(null);
transaction.commit();
storyFragment.loadStory(story);
break;
}
我收到此错误:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.EditText.setText(java.lang.CharSequence)' on a null object reference
at com.maniblett.listtest.StoryFragment.loadStory(StoryFragment.java:60)
at com.maniblett.listtest.MainActivity.onMainListClick(MainActivity.java:104)
片段中的方法是在edittext中设置文本,这里是我调用mName的片段方法,而mSummary是编辑文本小部件的引用:
public void loadStory(Story story){
mName.setText(story.get_name());
mSummary.setText(story.get_summary());
}
引用这样的片段是否合法(在我用于通过片段管理器添加片段的同一引用上调用方法)?看起来我已经有了对片段的引用,所以使用ID片段查找片段将是多余的,但是当我仔细检查我读到的所有内容时,似乎表明我需要首先使用findFragmentByID或Tag找到片段,因此将我的代码更改为此。 ..
storyFragment = new StoryFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.container, storyFragment, "loadedFragment");
transaction.addToBackStack(null);
transaction.commit();
StoryFragment loadedFragment = (StoryFragment)getFragmentManager().findFragmentByTag("loadedFragment");
loadedFragment.loadStory(story);
break;
但是我得到了类似的错误:
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.maniblett.listtest.StoryFragment.loadStory(com.maniblett.listtest.datamodel.Story)' on a null object reference
at com.maniblett.listtest.MainActivity.onMainListClick(MainActivity.java:107)
at com.maniblett.listtest.MainListFragment.onListItemClick(MainListFragment.java:156)
at android.app.ListFragment$2.onItemClick(ListFragment.java:160)
at android.widget.AdapterView.performItemClick(AdapterView.java:300)
我已经验证了我发送的对象在创建后不是null(case语句中的'story'是枚举)。再一次,如果我注释掉方法调用,frgament加载并运行正常,就在我调用emthod的时候就失败了。所以,我想我没有加载的实际片段?有人能告诉我我做错了什么吗? (我确实搜索了许多其他类似的主题,但找不到任何有用的东西,我对android很新)。感谢任何花时间提供帮助的人!
StoryFragment类:
public class StoryFragment extends Fragment
{
StoryListener activityCallback;
private EditText mName;
private EditText mSummary;
public interface StoryListener {
public void onAddButtonClick(String text);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_story, container, false);
Button button = (Button)rootView.findViewById(R.id.button);
mName = (EditText)rootView.findViewById(R.id.name);
mSummary = (EditText)rootView.findViewById(R.id.summary);
button.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
DBHandler dbHandler = new DBHandler(getActivity().getBaseContext(), null, null, 1);
Story story = new Story(mName.getText().toString(),mSummary.getText().toString());
dbHandler.addStory(story);
activityCallback.onAddButtonClick("Story"); //use same callback for all record types passing back record type created?
}
} );
return rootView;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try { activityCallback = (StoryListener) activity;
}
catch (ClassCastException e) {
throw new ClassCastException(activity.toString()+ " must implement StoryListener");
}
}
public void loadStory(Story story){
mName.setText(story.get_name());
mSummary.setText(story.get_summary());
}
}
答案 0 :(得分:3)
好吧,你应该先了解android的工作原理。仅当片段可见时才会调用onCreateView
方法。因此,当您在loadstory
方法之后立即致电FragmentTransaction
时,您会看到NullPointer Exception
我的解决方案:
将StoryFragment
中的两个变量声明为name
和summary
更改loadStory
方法就像这样
public void loadStory(Story story){
this.name = story.get_name();
this.summary = story.get_summary();
}
最后在适当更改后的OnCreateView
StoryFragment
方法
mName = (EditText)rootView.findViewById(R.id.name);
mSummary = (EditText)rootView.findViewById(R.id.summary);
//if your fragment is also gonna be called by some other manner you should check for null in this.name and this.summary before setting it to the `TextView`
mName.setText(this.name);
mSummary.setText(this.summary);
答案 1 :(得分:0)
谢谢。这非常有效。实际上,我所做的是创建一个私人故事类型,然后在我分配的StoryFragment.loadStory中。
public void loadStory(Story story){
mStory = story;
}
我还能够看到它可以正常工作,不必使用findFragmentByID搜索片段,这部分工作:
storyFragment = new StoryFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.container, storyFragment);
transaction.addToBackStack(null);
transaction.commit();
storyFragment.loadStory(story);
非常感谢你指点我正确的方向