[英]Why do I get a null pointer exception while passing the data from activity to fragment?
[英]I get exception when i pass data to third fragment but it works ok for passing data to the second fragment
我要在三個片段應用程序之間傳遞數據時遇到問題。
我使用一個接口傳遞片段的值,viewpager,並將片段保存在mainActivity.java的列表中。問題似乎出在片段的實例上。
在我的mainFragment(fragment1.java)上,我有兩個按鈕,一個用於將數據發送到第二個片段,另一個用於將數據發送到第三個片段。
該應用程序有效,當我按下按鈕時,數據顯示在第二個片段上。
如果按第二個按鈕將數據發送到第三個片段,則會出現異常。
數據將按原樣傳輸到第三個片段,但是如果在我轉到第二個片段並再次返回第一個片段之前按第二個按鈕,則會出現異常。
我不知道自己是否清楚,但是盡管frag1和frag2具有相同的代碼,但這似乎是一個實例錯誤。
這是我的代碼:
mainactivity.java
public class MainActivity extends FragmentActivity
implements ICommunicator{
private String Importeddata;
private PagerAdapter mPagerAdapter;
private List<Fragment> fragments;
private ViewPager mpager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewpager_layout);
initialisePaging();
}
private void initialisePaging() {
// TODO Auto-generated method stub
fragments = new Vector<Fragment>();
fragments.add(Fragment.instantiate(this, Fragment1.class.getName()));
fragments.add(Fragment.instantiate(this, Fragment2.class.getName()));
fragments.add(Fragment.instantiate(this, Fragment3.class.getName()));
mPagerAdapter = new PagerAdapter(this.getSupportFragmentManager(), fragments);
mpager = (ViewPager)findViewById(R.id.viewpager);
mpager.setAdapter(mPagerAdapter);
}
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
//Interface method implementation
public void respond(String data,int frItem) {
// TODO Auto-generated method stub
switch(frItem)
{
case 1:
/*
* THIS WAY WORKS 1
* Fragment2 fr2 = (Fragment2)fragments.get(1);
Toast.makeText(this, "you passed values"+data, Toast.LENGTH_SHORT).show();
System.out.println("you passed values"+data);
fr2.changeData(data);*/
/* THIS WAY WORKS 2
* Fragment2 fr2=(Fragment2)getSupportFragmentManager().findFragmentByTag("android:switcher:"+R.id.viewpager+":1");
fr2.changeData(data);
*/
/* THIS WAY WORKS 3
*
*/
Fragment2 fr2=(Fragment2) mPagerAdapter.instantiateItem(mpager, 1);
fr2.changeData(data);
break;
case 2:
/*
* 1st way works, only if i first go to fragment 2 and return to firstfragment*/
/*otherwise i get a nullpointer EXCEPTION */
/*Fragment3 fr3 = (Fragment3)fragments.get(2);
Toast.makeText(this, "you passed values"+data, Toast.LENGTH_SHORT).show();
System.out.println("you passed values"+data);
fr3.changeData(data);*/
/*2nd way works, only if i first go to fragment 2 and return to firstfragment*/
/*otherwise i get a nullpointer EXCEPTION */
Fragment3 fr3=(Fragment3)getSupportFragmentManager().findFragmentByTag("android:switcher:"+R.id.viewpager+":2");
fr3.changeData(data);
}
}
}
以下是FRAGMENT1.JAVA,它具有兩個按鈕
public class Fragment1 extends Fragment{
Button btn1;
Button btn2;
ICommunicator icommunicator;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.e(getTag(), "onActivityCreated 1");
icommunicator = (ICommunicator) getActivity();
btn1 = (Button) getActivity().findViewById(R.id.Btn_Send);
btn1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getActivity(), "you pressed the button", Toast.LENGTH_LONG).show();
icommunicator.respond("hello from Fragment 1",1);
}
});
btn2 = (Button)getActivity().findViewById(R.id.Btn_Send2);
btn2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getActivity(), "you pressed button 2", Toast.LENGTH_SHORT).show();
icommunicator.respond("hello from fragment1 fragment 2",2);
}
});
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.e(getTag(), "onAttach 1");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e(getTag(), "onDestroy 1");
}
@Override
public void onPause() {
super.onPause();
Log.e(getTag(), "onPause 1");
}
@Override
public void onResume() {
super.onResume();
Log.e(getTag(), "onResume 1");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.e(getTag(), "onCreateView 1");
if (container == null){
return null;
}
return inflater.inflate(R.layout.fragment1_layout,
container,false);
}
}
**below is the fragment2.java, the fragment that i send the btn1 message**
public class Fragment2 extends Fragment{
private String data;
private TextView txt;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.e(getTag(), "onCreateView 2");
txt = (TextView) getActivity().findViewById(R.id.txt_importData);
if (container == null){
return null;
}
return inflater.inflate(R.layout.fragment2_layout,
container,false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.e(getTag(), "onActivityCreated 2");
txt = (TextView) getActivity().findViewById(R.id.txt_importData);
if (this.data == null)
txt.setText("i wait value....");
else
txt.setText(this.data);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.e(getTag(), "onAttach 2");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e(getTag(), "onDestroy 2");
}
@Override
public void onPause() {
super.onPause();
Log.e(getTag(), "onPause 2");
}
@Override
public void onResume() {
super.onResume();
Log.e(getTag(), "onResume 2");
}
public void changeData(String importdata){
this.data = importdata;
txt.setText(importdata);
}
}
下面是fragment3.java,到目前為止,我向數據發送到btn2消息的片段已發送到fragment3.java,到目前為止,效果很好,但是除非我先進入第二個片段並返回第一個片段,否則我會得到空指針異常片段,然后按第二個按鈕,似乎片段的視圖實例有問題。
public class Fragment3 extends Fragment{
private String data;
private TextView txt;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.e(getTag(), "onCreateView 3");
txt = (TextView) getActivity().findViewById(R.id.txt_fragment3);
if (container == null){
return null;
}
return inflater.inflate(R.layout.fragment3_layout,
container,false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
txt = (TextView) getActivity().findViewById(R.id.txt_fragment3);
Log.e(getTag(), "onActivityCreated 3");
if (this.data == null)
txt.setText("i wait value....");
else
txt.setText(this.data);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.e(getTag(), "onAttach 3");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e(getTag(), "onDestroy 3");
}
@Override
public void onPause() {
super.onPause();
Log.e(getTag(), "onPause 3");
}
@Override
public void onResume() {
super.onResume();
Log.e(getTag(), "onResume 3");
}
public void changeData(String importdata){
this.data = importdata;
txt.setText(importdata);
}
}
如果有人可以幫助我或說出他的意見,我將不勝感激。
我需要接口通過片段進行通信,這就是片段彼此交互的方式,在您的答案中,如果我沒有記錯的話,建議您從clickListener內部傳遞數據。
至於setoffscreenPageLimit,你能告訴我我告訴代碼兌現三頁的地方嗎,還是viewpager缺省只緩存三頁的方式?
我補充說:
mpager.setOffscreenPageLimit(3);
而且有效! 謝謝。
它僅緩存3頁。 本身,在左右頁面上。 添加:
mpager.setOffscreenPageLimit(3);
//您有3個片段
您可以執行此操作,而不是執行所有操作:
btn1 = (Button) getActivity().findViewById(R.id.Btn_Send);
btn1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
TextView txt = (TextView) getActivity().findViewById(R.id.txt_importData);
txt.setText("whatever you want");
}
});
btn2 = (Button)getActivity().findViewById(R.id.Btn_Send2);
btn2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
TextView txt = (TextView) getActivity().findViewById(R.id.txt_fragment3);
txt.setText("whatever you want");
}
})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.