我正在尝试这样做:http://android-er.blogspot.com/2012/06/communication-between-fragments-in.html 除了我正在使用FragmentStatePagerAdapter
我的活动有两个片段( FragmentA & FragmentB )
FragmentA有一个edittext和一个按钮,FragmentB有一个textview
现在我想要的是每当我在edittext中输入内容并单击按钮时,我的textview上就会出现这样的内容。
MainActivity:
public class MainActivity extends FragmentActivity {
ViewPager viewPager = null;
String TabFragmentB;
@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));
}
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 FragmentA();
}
if (i == 1)
{
fragment = new FragmentB();
}
return fragment;
}
@Override
public int getCount() {
return 2;
}
}
public void setTabFragmentB(String t) {
TabFragmentB = t;
}
public String getTabFragmentB() {
return TabFragmentB;
}
}
FragmentA:
public class FragmentA extends Fragment {
EditText et;
Button bt;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fraga, container, false);
et = (EditText)v.findViewById(R.id.edit1);
bt = (Button)v.findViewById(R.id.button1);
bt.setOnClickListener(Click);
return v;
}
OnClickListener Click = new OnClickListener(){
@Override
public void onClick(View v) {
String textPassToB = et.getText().toString();
String TabOfFragmentB = ((MainActivity)getActivity()).getTabFragmentB();
FragmentB fragmentB = (FragmentB)getActivity()
.getSupportFragmentManager()
.findFragmentByTag(TabOfFragmentB);
fragmentB.updateText(textPassToB);
}
};
}
FragmentB:
public class FragmentB extends Fragment {
TextView tv;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragb, container, false);
tv = (TextView)v.findViewById(R.id.text1);
String myTag = getTag();
((MainActivity)getActivity()).setTabFragmentB(myTag);
return v;
}
public void updateText(String t){
tv.setText(t);
}
}
logcat的:
FATAL EXCEPTION: main
java.lang.NullPointerException
at lmf.sample1.FragmentA$1.onClick(FragmentA.java:43)
at android.view.View.performClick(View.java:4212)
at android.view.View$PerformClick.run(View.java:17476)
at android.os.Handler.handleCallback(Handler.java:800)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5371)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)
每当我点击第一个片段上的按钮时,我的应用就崩溃了。这到底是什么问题?
答案 0 :(得分:29)
要做的步骤:
首先,创建一些类来表示文本更改时的事件:
public class TextChangedEvent {
public String newText;
public TextChangedEvent(String newText) {
this.newText = newText;
}
}
然后,在片段A中:
//when text changes
EventBus bus = EventBus.getDefault();
bus.post(new TextChangedEvent(newText));
片段B中的:
EventBus bus = EventBus.getDefault();
//Register to EventBus
@Override
public void onCreate(SavedInstanceState savedState) {
bus.register(this);
}
//catch Event from fragment A
public void onEvent(TextChangedEvent event) {
yourTextView.setText(event.newText);
}
答案 1 :(得分:5)
碎片可以访问父活动 因此,最简单的方法是在父Activity中注册回调。
更新:提交添加到MainActivity的缓存。
public class MainActivity extends FragmentActivity {
private OnButtonClicked mOnButtonClicked;
private String mSubmitCache;
public interface OnButtonClicked {
void submit(final String s);
}
public void setOnButtonClicked(final OnButtonClicked c) {
mOnButtonClicked = c;
// deliver cached string, if any
if (TextUtils.isEmpty(mSubmitCache) == false) {
c.submit(mSubmitCache);
}
}
public void buttonClicked(final String s) {
if (mOnButtonClicked == null) {
// if FragmentB doesn't exist jet, cache value
mSubmitCache = s;
return;
}
mOnButtonClicked.submit(s);
}
}
public class FragmentA extends Fragment implements OnClickListener {
private MainActivity mMain;
private Button mButton;
@Override public onAttach(Activity a) {
mMain = (MainActivity) a;
}
@Override public void onClick(View v) {
mMain.buttonClicked("send this to FragmentB.");
}
}
public class FragmentB extends Fragment implements MainActivity.OnButtonClicked {
private MainActivity mMain;
private TextView mTextView;
// Called when the fragment's activity has been created
// and this fragment's view hierarchy instantiated
@Override public void onActivityCreated(Bundle savedState) {
mMain = (MainActivity) getActivity();
mMain.setOnButtonClicked(this);
}
@Override void submit(final String s) {
mTextView.setText(s);
}
}
答案 2 :(得分:1)
在切换到它之前,甚至不会创建FragmentB,因此fragmentB.updateText(textPassToB);
会给你NullPointerException。
您需要在活动中存储EditText中的文本,稍后当(如果)创建FragmentB时,您需要从中读取值。
答案 3 :(得分:1)
我使用上面Rodion先生的解决方案。但此外,Android Studio要求我在@Subscribe
方法之前添加onEvent
注释。
像这样:
@Subscribe
public void onEvent(TextChangedEvent event) {
textView.setText(event.newText);
}
订阅者实现在发布事件时将调用的事件处理方法(也称为“订阅者方法”)。这些是使用@Subscribe注释定义的。请注意,使用EventBus 3,可以自由选择方法名称(没有像EventBus 2中那样的命名约定)。