Volodymyr
Volodymyr

Reputation: 6569

Communication between fragments android

I have two fragments. I am using interface to communicate one fragment with another:

public class FragmentLanguages extends ListFragment {
LanguageArrayAdapter adapter;
OnLanguageChangedListener mCallback;

public interface OnLanguageChangedListener {
    public void onLanguageSelected(int position);
}

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

    View view = inflater.inflate(R.layout.languages, null);

    return view;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    Language languages[] = new Language[] {
            new Language(R.drawable.ic_flag_german, "German"),
            new Language(R.drawable.ic_flag_spanish, "Spanish"),
            new Language(R.drawable.ic_flag_russian, "Russian"),
            new Language(R.drawable.ic_flag_ukrainian, "Ukrainian") };

    adapter = new LanguageArrayAdapter(getActivity(), R.layout.list_row,
            languages);
    getListView().setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {
            adapter.setSelectedItem(position);
            mCallback.onLanguageSelected(position + 1);
        }
    });
    setListAdapter(adapter);
}

public static class Language {
    public int image;
    public String text;

    public Language() {
        super();
    }

    public Language(int image, String text) {
        super();
        this.image = image;
        this.text = text;
    }
}

public void setOnLanguageChangedListener(OnLanguageChangedListener mCallback) {
    this.mCallback = mCallback;
}

}

and another

public class FragmentCircles extends Fragment implements OnClickListener,
    OnLanguageChangedListener { ...
.....
    @Override
public void onLanguageSelected(int position) {
    currentLang = position;
    translationCircle.removeAllViews();
    String strSelect = "SELECT Translation FROM Translation WHERE Lang_Id="
            + currentLang + " ORDER BY Word_Id ASC";
    translationList = DataBaseHelper.getInstance(getActivity())
            .SelectTranslationList(strSelect);
    Log.i("Lang ", "changed " + currentLang);


    calculateCentreTranslation(lLabelRadius, width, height);
}

but after screen rotation when I choose some item in ListFragment it gives me an error

12-07 19:06:15.163: E/AndroidRuntime(436): java.lang.NullPointerException

at line

                mCallback.onLanguageSelected(position + 1);

It seems that mCallback is null. But how I can fix it?

Upvotes: 1

Views: 3587

Answers (3)

Shiva
Shiva

Reputation: 697

The mCallBack Listener is only declared but never instantiated. You should instantiate the mCallBack listener with the container activity in the onAttach() method. check here on how to do it. http://developer.android.com/training/basics/fragments/communicating.html#DefineInterface

Upvotes: 0

znat
znat

Reputation: 13474

Your FragmentLanguages must notify your FragmentActivity which in turns notify other fragments. This ensures that no Fragments are linked together which could trigger NullPointerExceptions if one is not instantiated when the other notifies it.

So your interface OnLanguageChangedListener stays in your LanguagesFragment

Your FragmentActivity must implement setOnLanguageChangedListener

In FragmentLanguages:

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    onLanguageChangedListener = (onLanguageChangedListener) activity;
}

Since onAttach() is called even before onCreate() you can use in your fragment whenever you want:

onLanguageChangedListener.onLanguageChanged(...);

In your FragmentActivity which implements OnLanguageChangedListener you are required to override this:

@Override
public void onLanguageChanged(...) {
    // here you implement the logic to notify other fragments
}

Upvotes: 1

sam
sam

Reputation: 3511

In android, when you switch from portrait to landscape or viceversa, the activities are recreated so if you want to keep some data you have to manage theses with the Bundle saveInstanceState.

Upvotes: 0

Related Questions