2014-12-06 104 views
0

我一直在此停留一段時間,我正在從一個活動(替換另一個)中加載一個片段。它加載正常,我可以看到它,並返回到前一個片段,但是當我調用一個方法來加載數據到它時,我得到一個空指針異常。我的第一個代碼是...當調用片段方法時,空指針異常

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; 
     } 

我收到此錯誤:

在一個EditText
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) 

在片段的方法是設置文本,這裏的片段方法我打電話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) 

我已經驗證了我送的對象不是創建後空(在case語句中的「故事」是一個枚舉)。再說一遍,如果我註釋掉方法調用,那麼它會加載並運行正常,只是當我調用它的方法失敗時。所以,我想我沒有加載的實際片段?有人能告訴我我做錯了什麼嗎? (我也搜索了許多其他類似的主題,但找不到任何有用的東西,我對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()); 
} 


} 

回答

3

那麼,你應該明白擺在首位如何Android版。 onCreateView方法僅在碎片即將可見時才被調用。所以,當你的FragmentTransaction方法其明顯後,立即打電話loadstory你會得到一個NullPointer Exception

我的解決辦法: 聲明中StoryFragmentnamesummary

更改loadStory方法是這樣的

兩個變量
public void loadStory(Story story){ 
    this.name = story.get_name(); 
    this.summary = story.get_summary(); 
} 

最後在OnCreateView方法StoryFragment之後chang在這裏適當地

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); 
0

謝謝。這工作完美。其實,我做的是創建一個私人的Story類型,然後在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); 

非常感謝您指出我在正確的方向這裏