[英]I get exception when i pass data to third fragment but it works ok for passing data to the second fragment
i have a problem with my three fragments application when i go to pass data between them. 我要在三个片段应用程序之间传递数据时遇到问题。
I use an interface to pass the values, viewpager for the fragments and i keep the fragments on a list in the mainActivity.java.The problem seems to be the instance of the fragments i guess. 我使用一个接口传递片段的值,viewpager,并将片段保存在mainActivity.java的列表中。问题似乎出在片段的实例上。
On my mainFragment (fragment1.java)i have two buttons, one for sending data to the 2nd fragment and one to send data to 3rd fragment. 在我的mainFragment(fragment1.java)上,我有两个按钮,一个用于将数据发送到第二个片段,另一个用于将数据发送到第三个片段。
The application works, and the data are shown on the second fragment when i press the button. 该应用程序有效,当我按下按钮时,数据显示在第二个片段上。
I get an exception if i press the second button to send the data to the third fragment. 如果按第二个按钮将数据发送到第三个片段,则会出现异常。
The data are transfered to the 3rd fragment as they should be, but i get an exception if press the second button before i go to the second fragment and return to the first again. 数据将按原样传输到第三个片段,但是如果在我转到第二个片段并再次返回第一个片段之前按第二个按钮,则会出现异常。
I dont know if i make myself clear, but it seems that is an instance error although frag1 and frag2 have the same code. 我不知道自己是否清楚,但是尽管frag1和frag2具有相同的代码,但这似乎是一个实例错误。
here is my code: 这是我的代码:
mainactivity.java 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);
}
}
}
BELOW IS THE FRAGMENT1.JAVA which it has the two buttons 以下是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);
}
}
below is the fragment3.java, the fragment that i send the btn2 message the data are sent to the fragment3.java , so far so good, but i get a nullpointer exception unless i have gone to the second fragment first and return to the first fragment and after that i press the second button, it seems that is something wrong with the view instance of the fragment. 下面是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);
}
}
if anyone can help me or tell his opinion i would appreciate it. 如果有人可以帮助我或说出他的意见,我将不胜感激。
i need interface to communicate through fragments , that is the way fragments interact with each other, in your answer you suggest to pass the data from inside the clickListener if i am not mistake. 我需要接口通过片段进行通信,这就是片段彼此交互的方式,在您的答案中,如果我没有记错的话,建议您从clickListener内部传递数据。
as for the setoffscreenPageLimit , can you tell me where i tell the code to cashe three pages or is it the way viewpager works to cache by default just three pages? 至于setoffscreenPageLimit,你能告诉我我告诉代码兑现三页的地方吗,还是viewpager缺省只缓存三页的方式?
I added : 我补充说:
mpager.setOffscreenPageLimit(3);
and it works! 而且有效! thank you.
谢谢。
It only caches 3 pages. 它仅缓存3页。 Itself, page on right and on left.
本身,在左右页面上。 Add this:
添加:
mpager.setOffscreenPageLimit(3);
// You have 3 fragments //您有3个片段
And you can just do this, instead of doing all of that: 您可以执行此操作,而不是执行所有操作:
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.