Android:在片段和活动之间传递数据

时间:2016-06-18 10:22:55

标签: android

我试图将一个片段中的值传递给一个活动而我不能因为我得到一个例外。在我的片段中,我必须选择一个在FrameLayout中呈现的占星术。 使用回调在Activity和Fragment之间进行通信。

例外是:

 java.lang.NullPointerException: Attempt to invoke interface method
 'void 
 com.converter.android.dailyhoroscope.HoroscopeChoice$OnInfoChangedListener.onInfoChanged(java.lang.String)'
 on a null object reference                                            
 at
 com.converter.android.dailyhoroscope.HoroscopeChoice$1.onClick(HoroscopeChoice.java:133)
 at android.view.View.performClick(View.java:5204)                     
 at android.view.View$PerformClick.run(View.java:21153)                
 at android.os.Handler.handleCallback(Handler.java:739)                
 at android.os.Handler.dispatchMessage(Handler.java:95)                
 at android.os.Looper.loop(Looper.java:148)                            
 at android.app.ActivityThread.main(ActivityThread.java:5417)          
 at java.lang.reflect.Method.invoke(Native Method)                     
 at
 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

在Fragment上,我有以下代码:

public class HoroscopeChoice extends DialogFragment {
public HoroscopeChoice() {
    }
    /******************************
     * Callback
     ********/
    public static void setOnInfoChangedListener(OnInfoChangedListener callback) {
        mCallback = callback;
    }

    public interface OnInfoChangedListener {
        public void onInfoChanged(String horosocopo);

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

        View view = inflater.inflate(R.layout.fragment_horoscope_choice,
                container, false);

        Button aquarius;
        aquarius  = (Button) view.findViewById(R.id.aquarius1);

        final int id = view.getId();

        View.OnClickListener onClickListener = new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                String horoscopo = onClick2(v.getId());
                mCallback.onInfoChanged(horoscopo);
            }
        };

        aquarius.setOnClickListener(onClickListener);
        return view;
    }

    public String onClick2(int id)
    {
        String horoscopo="";

        if (id == R.id.aquarius1) {
            horoscopo = "Aquarius";
        }
      (...)
      return horoscope;
    }

在活动上,如果我试图让setOnInfoChangedListener(this);尝试解决我遇到的异常,我会收到另一个错误"无法解决方法setOnInfoChangedListener"。

的活动:

public class SchedulerActivity extends Activity implements HoroscopeChoice.OnInfoChangedListener {

(...)
setOnInfoChangedListener(this);

    public void onInfoChanged(String horoscopo) {
        String sign="";
        mHoroscopeDisplay = (TextView) findViewById(R.id.dailyHoroscope4);
        mHoroscopeDisplay.setText(horoscopo);
        saveData(dHosocope, sign);
    }
}
你能帮帮我吗?

3 个答案:

答案 0 :(得分:0)

您获得的接口实例为null。如果要从Fragment调用接口方法,

  1. 创建界面并在Activity中实现它。 (你已经这样做了)
  2. 在片段中创建接口实例。

    public class MyFragment extends Fragment{
      private onInfoChangedListener listener;
    
      //you have to instantiate the listener variable in onAttach()
      @Override 
      public void onAttach(Context context){
          super.onAttach();
          try{
            listener=(SchedulerActivity)context;
          }catch(Throwable e){
            //interface might not be implemented
          }
      }
    
      //now you can use this in the onCreateView() method
      public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState){
           aquarius.setOnClickListener(new View.OnCLickListener{
                 @Override
                 public void onClick(View v){
                    try{
                       listener.onInfoChanged(horoscopo);
                    }catch(Throwable e){
                       //listener can be null
                    }
                 }
           });
    }
    

答案 1 :(得分:0)

嗯,您可能需要提醒界面如何工作;)

片段:

public class MyFragment extends Fragment {
    private OnInfoChangedListener listener;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        this.listener = null;
        return inflater.inflate(R.layout.fragment_layout, container, false);
    }

    void aFunctionWhereSomethingHappen(){
        // fire event
        if(listener!=null)
            listener.onInfoChanged("text");
    }

    public interface OnInfoChangedListener {
        void onInfoChanged(String horosocopo);
    }

    public void setOnInfoChangedListener(OnInfoChangedListener listener) {
        this.listener = listener;
    }
}

在您的活动中:

MyFragment fragment = new MyFragment();
fragment.setOnInfoChangedListener(new MyFragment.OnInfoChangedListener() {
    @Override
    public void onInfoChanged(String horosocopo) {
        // event
    }
});

我希望它更清楚!

修改

您可能还想考虑使用EventBusOtto这样的库,这些库就是为此而制作的。

答案 2 :(得分:0)

在片段中添加以下代码。

@Override 
public void onAttach(Activity context){
   super.onAttach() 
   if(context instanceof OnInfoChangedListener)
        listener=(OnInfoChangedListener)context;
}