当我将数据传递给第三个片段时,我得到异常,但它可以将数据传递给第二个片段

时间:2014-01-27 15:42:11

标签: android android-fragments interface android-viewpager

当我在他们之间传递数据时,我的三个片段应用程序出了问题。

我使用一个接口传递值,viewpager用于片段,我将片段保存在mainActivity.java的列表中。问题似乎是我猜的片段的实例。

在我的mainFragment(fragment1.java)上,我有两个按钮,一个用于将数据发送到第二个片段,另一个用于将数据发送到第三个片段。

应用程序正常工作,当我按下按钮时,数据显示在第二个片段上。

如果按第二个按钮将数据发送到第三个片段,我会收到异常。

数据被转移到第3个片段,但是如果在我转到第二个片段然后再次返回第一个片段之前按第二个按钮,我会收到异常。

我不知道我是否清楚自己,但看起来这是一个实例错误,尽管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,但是我得到了一个nullpointer异常,除非我先去了第二个片段然后返回到第一个片段,之后按下第二个按钮,似乎是错误的片段视图实例。

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

如果有人可以帮助我或说出他的意见我会很感激。

2 个答案:

答案 0 :(得分:1)

我需要通过片段进行通信的接口,这就是片段彼此交互的方式,如果我没有错,你建议从clickListener内部传递数据。

至于setoffscreenPageLimit,你能告诉我在哪里告诉代码要三个页面,还是viewpager默认只缓存三页的方式?

我补充说:

mpager.setOffscreenPageLimit(3);

它有效! 谢谢。

答案 1 :(得分:0)

它只缓存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");
        }
    })