碎片到碎片通信NPE

时间:2014-02-10 13:23:52

标签: android android-fragments

我有一个MainActivity,它包含两个片段(Frag1和Frag2)

我要做的是:每当我点击Frag1中的按钮时,“单击按钮”字符串应该显示在Frag2的EditText中。

我正在使用ViewPager,因此我没有片段ID 我设置了一个通信器界面和一个片段标签 但我不知道我是否正确设置了碎片标记。

这是我的代码:

Communicator界面

public interface Communicator {
    public void respond(String data);

}

Frag1

public class Frag1 extends Fragment implements OnClickListener { 

Button button1;
Communicator comm;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {    

    return inflater.inflate(R.layout.frag1, container, false);
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    comm = (Communicator)getActivity();

    button1 = (Button) getActivity().findViewById(R.id.button1);
    button1.setOnClickListener(this);
}

@Override
public void onClick(View view) {
    comm.respond("The button was clicked");     


}

}

MainActivity

public class MainActivity extends FragmentActivity implements Communicator {

ViewPager viewPager = null; 

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    viewPager = (ViewPager)findViewById(R.id.pager);    
    FragmentManager fragmentManager = getSupportFragmentManager();
    viewPager.setAdapter(new MyAdapter(fragmentManager));
    viewPager.setOffscreenPageLimit(2);
}

public class MyAdapter extends FragmentStatePagerAdapter {  

    public MyAdapter (FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int i) {
        Fragment fragment = null;

        if (i == 0)
        {
            fragment = new Frag1();
        }
        if (i == 1)
        {
            fragment = new Frag2();
        }
        return fragment;
    }

    @Override
    public int getCount() {
        return 2;
    }   
}

@Override
public void respond(String data) {

    Frag2 frag2 = new Frag2();
    getSupportFragmentManager().beginTransaction().add(frag2, "Hello").commit();

    Frag2 frag = (Frag2) getSupportFragmentManager().findFragmentByTag("Hello");
    frag.changeText(data);
}

}

Frag2

public class Frag2 extends Fragment { 

    EditText edittext1;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {    

        return inflater.inflate(R.layout.frag2, container, false);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        edittext1 = (EditText) getActivity().findViewById(R.id.edit1);
    }

    public void changeText(String data) {
        edittext1.setText(data);
    }

}
单击Frag1

中的按钮后,LogCat中出现

错误

02-10 21:22:09.210: E/AndroidRuntime(9760): FATAL EXCEPTION: main
02-10 21:22:09.210: E/AndroidRuntime(9760): java.lang.NullPointerException
02-10 21:22:09.210: E/AndroidRuntime(9760):     at lmf.test5.MainActivity.respond(MainActivity.java:59)
02-10 21:22:09.210: E/AndroidRuntime(9760):     at lmf.test5.Frag1.onClick(Frag1.java:35)
02-10 21:22:09.210: E/AndroidRuntime(9760):     at android.view.View.performClick(View.java:4212)
02-10 21:22:09.210: E/AndroidRuntime(9760):     at android.view.View$PerformClick.run(View.java:17476)
02-10 21:22:09.210: E/AndroidRuntime(9760):     at android.os.Handler.handleCallback(Handler.java:800)
02-10 21:22:09.210: E/AndroidRuntime(9760):     at android.os.Handler.dispatchMessage(Handler.java:100)
02-10 21:22:09.210: E/AndroidRuntime(9760):     at android.os.Looper.loop(Looper.java:194)
02-10 21:22:09.210: E/AndroidRuntime(9760):     at android.app.ActivityThread.main(ActivityThread.java:5371)
02-10 21:22:09.210: E/AndroidRuntime(9760):     at java.lang.reflect.Method.invokeNative(Native Method)
02-10 21:22:09.210: E/AndroidRuntime(9760):     at java.lang.reflect.Method.invoke(Method.java:525)
02-10 21:22:09.210: E/AndroidRuntime(9760):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
02-10 21:22:09.210: E/AndroidRuntime(9760):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
02-10 21:22:09.210: E/AndroidRuntime(9760):     at dalvik.system.NativeStart.main(Native Method)

1 个答案:

答案 0 :(得分:0)

我认为你应该等待在respond(String data)中执行挂起的交易。但你可以执行:

getSupportFragmentManager().executePendingTransactions();

之前:

Frag2 frag = (Frag2) getSupportFragmentManager().findFragmentByTag("Hello");
frag.changeText(data);

我认为它应该没问题


顺便说一句,您应该像在Google导游中使用Deliver a Message to a Fragment一样重写您的void respond(String data)。问题是,在添加新片段时,您应该使用setArguments传递数据,但是当片段已经存在时,您可以在其上调用方法。这样你就不需要executePendingTransactions()。