2014-02-10 126 views
0

我已經把兩個片段(Frag1和Frag2)片段片段通訊NPE

我試圖做的是一個MainActivity:每次我點擊Frag1按鈕「被點擊的按鈕」字符串應該顯示在Frag2的EditText中。

我使用的ViewPager,所以我沒有片段ID的。
我設置了一個通信器接口和一個片段標籤。
但我不知道我是否正確設置了我的片段標籤。

這裏是我的代碼:

通訊接口

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

} 

在logcat的錯誤點擊Frag1

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) 
+0

您可以將'comm =(Communicator)getActivity()'行移動到'onAttach()'嗎? http://developer.android.com/reference/android/app/Fragment.html#onAttach(android.app.Activity) – midhunhk

回答

0

按鈕後,我想你應該等待懸而未決的respond(String data)要執行交易。但是,你可以執行:

getSupportFragmentManager().executePendingTransactions(); 

前:

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

,我想這應該是罰款


順便說一句,你應該重寫你void respond(String data),以同樣的方式,因爲它是例如從谷歌指南:Deliver a Message to a Fragment。問題是添加新片段時,應該使用setArguments傳遞數據,但是當片段已經存在時,您可以調用它的方法。這樣你就不需要executePendingTransactions()。

+0

這不會是片段的緊密結合嗎? – midhunhk

+0

可能是的,這個方法它由谷歌建議其實:http://developer.android.com/training/basics/fragments/communicating.html – marcinj

+0

@marcin_j - 有什麼更好的方法來使用,爲什麼? – luwionline