Java 如何使方法同时与活动和片段通信?

Java 如何使方法同时与活动和片段通信?,java,android,android-fragments,Java,Android,Android Fragments,我有一个应用程序,其中包括一个活动和一个片段。在活动中,som数据使用文本视图显示,在片段中,用户可以使用EditText视图输入一些数据。我有一个方法,它从活动和片段中获取数据,执行一些计算,最后在片段和活动中显示结果。当我在片段的任何EditText视图中编辑文本后调用if时,此方法当前有效。但是,我也希望在每次更新活动中的数据时调用它,但是当我尝试这样做时,我无法获取EditText数据,因为它们返回null。 所以我的问题是:当处理活动和片段都应该达到的方法时,什么是好的实践,或者“正确

我有一个应用程序,其中包括一个活动和一个片段。在活动中,som数据使用文本视图显示,在片段中,用户可以使用EditText视图输入一些数据。我有一个方法,它从活动和片段中获取数据,执行一些计算,最后在片段和活动中显示结果。当我在片段的任何EditText视图中编辑文本后调用if时,此方法当前有效。但是,我也希望在每次更新活动中的数据时调用它,但是当我尝试这样做时,我无法获取EditText数据,因为它们返回null。 所以我的问题是:当处理活动和片段都应该达到的方法时,什么是好的实践,或者“正确的方法”是什么?如果有人能引导我走上正确的道路,我将不胜感激

我已经读过了,其中提到了ViewModel。但这似乎不适合我的应用程序,因为我希望参与活动。我需要用这个还是可以完成我的主要活动?我也读过关于接口的书,但我不确定哪一个最适合我的项目。我目前正在使用接口,但我不确定是否正确

我还观看并阅读了以下问题:

“我的上帝”对我的回答很有帮助,但我仍然不确定在我的情况下最好做什么,因为我有一个用户可以输入数据的片段,同样的片段也应该作为输入的结果来查看数据。(也许我的第一个错误是构建这样的应用程序?)

我提供了一些代码,以防有用

public class AccuracyFragment extends Fragment {
    EditText editTextLevel, editTextAccuracy; 
    private OnFragmentInteractionListener mListener;

    public AccuracyFragment() {
        // Required empty public constructor
    }

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_accuracy, container, false);
        editTextAccuracy = view.findViewById(R.id.text_accuracy_character);
        editTextLevel = view.findViewById(R.id.text_level_character);


        TextWatcher watcher = new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
//Doing nothing

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
//Doing nothing

            }

            @Override
            public void afterTextChanged(Editable editable) {
                updateFragment(Float.valueOf(editTextLevel.getText().toString()), Float.valueOf(editTextAccuracy.getText().toString()));
            }
        };

        editTextLevel.addTextChangedListener(watcher);
        editTextAccuracy.addTextChangedListener(watcher);

        return view;
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null; //I don’t know what this does
    }

    @Override
    public void onResume() {
        super.onResume();
//        updateFragment(); //Should I have this? 
    }

    public interface OnFragmentInteractionListener {
        String[] onAccuracyFragmentInputChanged(float levelFromFragment, float accuracyFromFragment);    }

    public void updateFragment(float level, float accuracy) {

        //Complicated method doing things with editTextLevel and editTextAccuracy. However, it doesn’t work when this method is called from outside AccuracyFragment – EditTexts are null


    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public void onPause() {
        super.onPause();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
    }

    @Override
    public void onStop() {
        super.onStop();
    }
}
 
public class MainActivity extends AppCompatActivity implements AccuracyFragment.OnFragmentInteractionListener, AdapterView.OnItemSelectedListener {




    AccuracyFragment accuracyFragment;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main_new); 
        selectedID = null;
        textView1 = (TextView) findViewById(R.id.text_1);
textView2 =  (TextView) findViewById(R.id.text_2); 

// Check that the activity is using the layout version with
// the fragment_container FrameLayout
if (findViewById(R.id.fragment_container) != null) {
// However, if we're being restored from a previous state, then we don't need to do anything and should return or else we could end up with overlapping fragments.
if (savedInstanceState != null) {
    return;
}

// Create a new Fragment to be placed in the activity layout
accuracyFragment = new AccuracyFragment();       
 }
}
//This is the core method which takes the value from two EditTexts in the Fragment, and two TextViews in the MainActivity
    private String[] getRequiredAccuracy(float firstValueFromActivity, float secondValueFromActivity, float firstValueFromFragment, float secondValueFromFragment) {

//This methods uses parameters from the Activity, and two from the Fragment, and is intended to be called from both the Activity and from the Fragment itself

        String returnValues[] = {s, q, r, c}; //This method is too complex to show, but it will end up outputting some values
        return returnValues;
    }



    public void methodCalledUponClick(View view) {
//After showing a Dialog with some choices, I intend to call the method from fragment:
        accuracyFragment.updateFragment();
    }

    @Override
    public String[] onAccuracyFragmentInputChanged(float levelFromFragment, float accuracyFromFragment) {
        String returnValues[] = {"0", "0", "0"};
        if (selectedID != null) {
            if (textView1.length() == 0 || textView2.length() == 0) {
                //Do nothing if any of these are empty
            } else {
                returnValues = getRequiredAccuracy(Float.valueOf(textView1.getText().toString()), Float.valueOf(textView2.getText().toString()), levelFromFragment, accuracyFromFragment);
            }
        }
        return returnValues;
    }

}

}

您可以使用回调/接口同时与片段和活动通信

要创建回调/接口,请执行以下操作:

public interface CallBackListener {
void onCallBack(String value);// pass any parameter in your onCallBack which you want to return 
}
在片段类中:

public class AccuracyFragment extends Fragment {

private CallBackListener callBackListener;

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    //getActivity() is fully created in onActivityCreated and instanceOf differentiate it between different Activities
    if (getActivity() instanceof CallBackListener)
        callBackListener = (CallBackListener) getActivity();
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    EditText editText = (EditText) view.findViewById(R.id.edittext);
    editText.addTextChangedListener(new TextWatcher() {

    @Override
    public void afterTextChanged(Editable s) {}

     @Override    
     public void beforeTextChanged(CharSequence s, int start,
      int count, int after) {
     }

    @Override    
    public void onTextChanged(CharSequence s, int start,
     int before, int count) {
        if(callBackListener != null)
                callBackListener.onCallBack(s.toString());
        }
    });
  }
}
在您的活动中:

public class MainActivity extends AppCompatActivity  implements CallBackListener
 {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

}

 @Override
 public void onCallBack(String value) {
    Toast.makeText(mContext,"onCallback Called",Toast.LENGTH_LONG).show();
 }
}

在GetRequiredAccurance中,您是否从片段中获取值?然后您的活动文本视图文本设置为xml格式。是的,我从片段的EditText中获取值。TextView有一个我用xml定义的默认文本,但稍后它们会从数据库接收一个值,我也会在计算中使用该值。确定您面临的错误是什么
我无法获取EditText数据,因为它们返回null
——其中它给出null?当我尝试通过输入片段来更新片段(执行计算)时,它可以工作。但是,当我在活动中更改数据时,片段返回null,因此我无法访问它以获取用于计算的数据。我的代码如下所示:
如果(editTextLevel!=null&&EditTextAccurance!=null){//从未到达此处,因为这些EditText(在片段中)为null}
您已经从片段中获取了数据,然后y在活动中更新值后再次查找片段数据。好的,你能解释更多关于回调的信息吗?或者给我发一个链接,我可以从中了解更多信息。谢谢!我现在正在检查。
CallBackFragment
是一个单独的类,还是这应该是我的片段(在我的例子中是AccuracyFragment)?我这样问是因为在代码的以下部分,类似乎提前关闭:
public class CallBackFragment扩展了Fragment{private CallBackListener CallBackListener;}
CallBackFragment
基本上就是您的
accurityfragment
类。