Communicating between fragment and activity

Communicating between fragment and activity


The easiest way to communicate between your activity and fragments is using interfaces or parameters.

There are different ways to communicate:

*From activity to Fragment:

1. When it is instantiated, We can pass a parameter (Send data from activity to fragment in android)
2. When it was instantiated, We can call a fragment’s method from activity.(Send data from activity to fragment on android II)
3. When we use a TabBar with some fragments, We use a interface in our Adapter.(Communicating activity with fragments in TabBar)

*From fragment to activity:

1. When we need to communicate with activity from fragment, we use a interface. The idea is basically to define an interface a given fragment with onAttach(Activity activity) and onDetach(), and let the activity implement that interface.(Listener from fragment to activity)

Communicating activity with fragments in TabBar

Communicating activity with fragments in TabBar

We need
– Interface.
– Actvity.
– ManagerFragment.
– Adapter
– FirstFragment.
– SecondFragment.


Complete code in github

First Step

In our Activity we will call a Manager fragment

mManagerFragment.update(newText);

You can check the complete activity

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";
    private MenuItem mSearchMenuItem;

    private SearchView mSearchView;

    ManagerFragment mManagerFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       
        mManagerFragment = new ManagerFragment().newInstance();
        replaceFragment();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);

        mSearchMenuItem = menu.findItem(R.id.menu_main_action_search);

        mSearchView = (SearchView) MenuItemCompat.getActionView(mSearchMenuItem);

        mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                return true;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                //sent to ManagerAdapter
                mManagerFragment.update(newText);
                return false;
            }
        });

        return super.onCreateOptionsMenu(menu);
    }


    public void replaceFragment() {

        try {

            FragmentManager fragmentManager = getSupportFragmentManager();
            fragmentManager.beginTransaction().replace(R.id.content_main, mManagerFragment, "tag").commit();

        } catch (Exception e) {
            Log.d(TAG, e.toString());
        }

    }
    
}

Now in Our ManagerFragment we received the string in this method

public void update(String string)

In Our Fragment we send the string from Manager To Adapter

public void update(String string){
        mAdapter.update(string);
    }

This is ManagerFragment

public class ManagerFragment extends Fragment {

    private ViewPager mViewPager;
    private TabsAdapter mAdapter;

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

    public static ManagerFragment newInstance() {
        ManagerFragment fragment = new ManagerFragment();
        return fragment;
    }

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_manager, container, false);

        TabLayout tabLayout = (TabLayout) view.findViewById(R.id.fragment_manager_tab_bar_tab_layout);
        mViewPager = (ViewPager) view.findViewById(R.id.fragment_manager_tab_bar_pager);

        mAdapter = new TabsAdapter(getFragmentManager(), getActivity());

        mViewPager.setAdapter(mAdapter);
        tabLayout.setupWithViewPager(mViewPager);

        return view;
    }

    //received from Activity
    public void update(String string){
        //sent to Adapter
        mAdapter.update(string);
    }

}

Second Step

This is the most importa step
In Our adapter We receive from ManagerFragment

//received from ManagerFragment
    public void update(String string) {
        mGeneralString = string;
        //updated
        notifyDataSetChanged();
    }

And we sent to FirstFragment and SecondFragment

@Override
    public int getItemPosition(Object object) {
        if (object instanceof UpdateableFragmentListener) {
            //sent to FirstFragment and SecondFragment
            ((UpdateableFragmentListener) object).update(mGeneralString);
        }
        return super.getItemPosition(object);
    }

You can see the adapter

public class TabsAdapter extends FragmentStatePagerAdapter {

    public static final int TOTAL_TABS = 2;
    public String mGeneralString;
    public Context mContext;

    public TabsAdapter(FragmentManager fm, Context context) {
        super(fm);
        mContext = context;
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return new FirstFragment().newInstance();

            case 1:
                return new SecondFragment().newInstance();
        }
        return null;
    }

    //received from ManagerFragment
    public void update(String string) {
        mGeneralString = string;
        //updated
        notifyDataSetChanged();
    }

    @Override
    public int getItemPosition(Object object) {
        if (object instanceof UpdateableFragmentListener) {
            //sent to FirstFragment and SecondFragment
            ((UpdateableFragmentListener) object).update(mGeneralString);
        }
        return super.getItemPosition(object);
    }

    @Override
    public int getCount() {
        return TOTAL_TABS;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
            case 0:
                return mContext.getString(R.string.fragment_first_title);
            case 1:
                return mContext.getString(R.string.fragment_second_title);
            default:
                return mContext.getString(R.string.fragment_first_title);
        }
    }
}

And our listener is a simple interface

 
public interface UpdateableFragmentListener {
    public void update(String string);
}

Third Step

In FirstFragment and SecondFragment we receive the string with our Listener,
We implement the listener

public class FirstFragment extends Fragment implements UpdateableFragmentListener{
//received from Adapter with our Listener
    @Override
    public void update(String string) {
        mTextView.setText(string);
    }

you can see the simple Fragment

public class FirstFragment extends Fragment implements UpdateableFragmentListener{

    TextView mTextView;

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

    public static FirstFragment newInstance() {
        FirstFragment fragment = new FirstFragment();
        return fragment;
    }

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_first, container, false);
        mTextView = (TextView) view.findViewById(R.id.fragment_first_text);
        return view;
    }

    //received from Adapter with our Listener
    @Override
    public void update(String string) {
        mTextView.setText(string);
    }
}

Complete code in github