[英]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.