Send data from activity to fragment on android II

Send data from activity to fragment on android II
When it was instanceted of fragment, we can’t to pass data with parameter, The only way is to call fragment’s method from activity.

We need:
– Activity
– Fragment
We instance a fragment from activity. After that We will call a fragment’s method from the activity.

Complete code in github

You can check the activity.

package com.thedeveloperworldisyours.l;

import android.graphics.Color;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.SearchView;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

public class MainActivity extends AppCompatActivity {

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

    private SearchView mSearchView;
    private String mSearchString;
    private static final String SEARCH_KEY = "search";

    FirstFragment mFirstFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // if you saved something on outState you can recover them here
        if (savedInstanceState != null) {
            mSearchString = savedInstanceState.getString(SEARCH_KEY);
        }
        mFirstFragment = new FirstFragment().newInstance();
        replaceFragment();
    }

    // This is called before the activity is destroyed
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mSearchString = mSearchView.getQuery().toString();
        outState.putString(SEARCH_KEY, mSearchString);
    }

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

        customSearView();

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

            @Override
            public boolean onQueryTextChange(String newText) {
                mFirstFragment.refreshString(newText);
                return false;
            }
        });

        return super.onCreateOptionsMenu(menu);
    }

    public void customSearView() {
        SearchView.SearchAutoComplete searchAutoComplete = (SearchView.SearchAutoComplete) mSearchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
        searchAutoComplete.setHintTextColor(Color.WHITE);
        searchAutoComplete.setTextColor(Color.WHITE);

        View searchPlate = mSearchView.findViewById(android.support.v7.appcompat.R.id.search_plate);
        searchPlate.setBackgroundResource(R.drawable.background_search);

        mSearchView.setIconifiedByDefault(false);
    }


    public void replaceFragment() {

        try {

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

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

    }


}

Complete code in github

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

Listener from fragment to activity

Listener from fragment to actvity

We need three things
– Interface
– Fragment
– Activity

Complete code in github

We create a simple Interface:

public interface InteractionListener {
    void onFragmentInteraction(String string);
}

Now in our fragment We need to use onAttach(Context context), called when a fragment is first attached to its context. In this method we init our listener

When the user click in button, we call our listener.

public class OurFragment extends Fragment implements View.OnClickListener{

    private EditText mEditText;
    private InteractionListener mListener;

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

    public static OurFragment newInstance() {
        OurFragment fragment = new OurFragment();
        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_our, container, false);
        mEditText = (EditText) view.findViewById(R.id.fragment_our_edit_text);
        Button button = (Button) view.findViewById(R.id.fragment_our_button);
        button.setOnClickListener(this);
        return view;
    }

    public void sentString() {
        mListener.onFragmentInteraction(mEditText.getText().toString());
    }

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

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    @Override
    public void onClick(View v) {
        sentString();
    }
}

Now in activity We implement the listener

implements InteractionListener

And then to put our method

onFragmentInteraction(String string)
 
public class MainActivity extends AppCompatActivity implements InteractionListener{
    private static final String TAG = "MainActivity";
    private MenuItem mSearchMenuItem;

    private SearchView mSearchView;
    private String mSearchString;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       
        replaceFragment();

    }

    

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

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

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

        focusSearView();

        return super.onCreateOptionsMenu(menu);
    }

    public void focusSearView(){
        if (mSearchString != null && !mSearchString.isEmpty()) {
            mSearchMenuItem.expandActionView();
            mSearchView.setQuery(mSearchString, true);
            mSearchView.clearFocus();
        }
    }

    public void replaceFragment() {
        Fragment OurFragment = new OurFragment().newInstance();

        try {

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

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

    }

    @Override
    public void onFragmentInteraction(String string) {
        //listened
        mSearchString = string;
        focusSearView();
    }
}

Here activity layout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/content_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.javier.customsearchview.MainActivity">

</RelativeLayout>

Now we create our SearchView. First we need to create new folder which name is menu.

After that we create new xml file, which name is “main”.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/menu_main_action_search"
        android:icon="@android:drawable/ic_menu_search"
        android:title="@string/menu_main_search_title"
        app:actionViewClass="android.support.v7.widget.SearchView"
        app:showAsAction="always|collapseActionView" />
</menu>

Finally fragment layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.javier.customsearchview.OurFragment">

    <EditText
        android:id="@+id/fragment_our_edit_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:gravity="center" />

    <Button
        android:id="@+id/fragment_our_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/fragment_our_edit_text"
        android:layout_centerHorizontal="true" />

</RelativeLayout>

Complete code in github

Send data from activity to fragment in android

Update

Send data from activity to fragment in android

In this example We learn how to send two string from Activity to fragment.

Android recommends to use newInstance.

In the activity:

FirstFragment fragment = FirstFragment.newInstance("Param One","Param Two");

In the fragment:

    public static FirstFragment newInstance(String param1, String param2) {
        FirstFragment fragment = new FirstFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }


From Activity you send data with intent as:

public class MainActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
 
    public void goToFragment(View view) {
        FirstFragment fragment = FirstFragment.newInstance("Param One","Param Two");
 
        replaceFragment(fragment, "FirstFragment");
        view.setVisibility(View.GONE);
    }
 
 
 
    public void replaceFragment(Fragment fragment, String tag) {
 
        try {
 
            FragmentManager fragmentManager = getSupportFragmentManager();
            fragmentManager.beginTransaction().replace(R.id.content_main, fragment, tag).commit();
 
        } catch (Exception e) {
            Log.d(TAG, e.toString());
        }
 
    }
}

and in Fragment onCreateView method:

public class FirstFragment extends Fragment {
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";
 
    private String mParam1;
    private String mParam2;
 
    public FirstFragment() {
        // Required empty public constructor
    }
 
    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment FirstFragment.
     */
    public static FirstFragment newInstance(String param1, String param2) {
        FirstFragment fragment = new FirstFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }
 
    @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);
        TextView textView1 = (TextView) view.findViewById(R.id.fragment_first_param_one);
        TextView textView2 = (TextView) view.findViewById(R.id.fragment_first_param_two);
 
        textView1.setText(mParam1);
        textView2.setText(mParam2);
 
        return view;
    }
 
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
    }
 
    @Override
    public void onDetach() {
        super.onDetach();
    }
 
}

fragment_first.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.javier.activitytofragment.FirstFragment">
 
    <TextView
        android:id="@+id/fragment_first_param_one"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="@string/hello_blank_fragment" />
 
    <TextView
        android:id="@+id/fragment_first_param_two"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_below="@+id/fragment_first_param_one"
        android:text="@string/hello_blank_fragment" />
 
</RelativeLayout>

contentent_main.xml(This content has the fragment)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/content_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
 
</RelativeLayout>

content_activity.xml (This content has the activity)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:onClick="goToFragment" />
 
</RelativeLayout>

activity_main.xml(this layout has the contents)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.javier.activitytofragment.MainActivity">
 
    <include layout="@layout/content_activity" />
    <include layout="@layout/content_main" />
</RelativeLayout>