Android - communicating between viewpager fragments and activity

Sending data from fragment to activity, especially viewpager fragment is an important feature in android programming.
In this example, I will present the way to comunicating between fragment and activity. Now, we need make a simple screen like this:
Full size
- Area (1): a viewpager with fragments, each fragment has a text number (random between 1 and 100).

- Area (2): a text number in activity (this text not belongs to any fragment).
- The data flow: when a fragment created, it randomized a number and show it to text at (1), then sending data to activity and show it at text in activity (2).

Now, start an android project in Eclipse.
Create MainPagerActivity to launch. Source code may be simple :) :

public class MainPagerActivity extends FragmentActivity implements OnFragmentInteractionListener {
    private ViewPager pager;
    private TextView text;
    private ViewPagerAdapter adapter;

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

        pager = (ViewPager) findViewById(R.id.viewpager);
        text = (TextView) findViewById(R.id.text);

        setPagerAdapter();
    }


    private void setPagerAdapter() {
        adapter = new ViewPagerAdapter(getSupportFragmentManager());
        pager.setAdapter(adapter);
    }

    @Override
    public void onFragmentCreated(int number) {
        text.setText(String.valueOf(number));
    }
}

Customize a ViewpagerAdapter (extends FragmentPagerAdapter) like this:

public class ViewPagerAdapter  extends FragmentPagerAdapter {

    public ViewPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int i) {
        return ViewFragment.newInstance(i);
    }

    @Override
    public int getCount() {
        return Integer.MAX_VALUE;
    }
}

activity_mainpager.xml file:

<LinearLayout 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:background="#339966"
    android:orientation="vertical" >

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.5" />
    
    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.15"
        android:gravity="center"
        android:padding="20dp"
        android:textSize="25sp" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:gravity="center_horizontal"
        android:layout_weight="0.35"
        android:text="@string/activity" />

</LinearLayout>

Next, defining a viewpager fragment (all fragments are same - difference is their position)!
For sending data to activity:
  • Declaring an interface (called  OnFragmentInteractionListener) in ViewPagerFragment to save data.
  • Override onAttach(Activity activity) method: sending data here.
  • MainPagerActivity must implement this interface (you can see at above code).
By this way, data will be sent from fragment and activity.
Remainding problem is ViewPager create 2 page together, so we mus detect which fragment is visible with user by overrid setUserVisibleHint() method and randomize number here. This "hacked method"  will make code run right.
ViewPagerFragment.java source code:

package com.blogspot.hongthaiit.viewpager;

import java.util.Random;

import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.blogspot.hongthaiit.viewpagerfragment.R;

public class ViewFragment extends Fragment {
    
    /**
     * Interface for communicating data
     *
     */
    public interface OnFragmentInteractionListener {
        public void onFragmentCreated (int number);
    }

    private View rootView;
    private TextView textView;
    private int number = -1;

    private OnFragmentInteractionListener listener;

    public static Fragment newInstance(int number) {
        ViewFragment instance;
        instance = new ViewFragment();

        return instance;
    }

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

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.viewpager_fragment, container, false);

        textView = (TextView) rootView.findViewById(R.id.text);

        if (number == -1) randomNumber();
        textView.setText(String.valueOf(number));

        Log.i("Fragment", "number: " + number);
        return rootView;
    }

    @Override
    public void onAttach(Activity activity) {
        try {
            listener = (OnFragmentInteractionListener) getActivity();
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnFragmentInteractionListener");
        }
        super.onAttach(activity);
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser) {
            // for the first page.
            if (number == -1) randomNumber(); 


            listener.onFragmentCreated(number);
            Log.i("Fragment", "call activity: " + number);
        }
    }

    /**
     * random number between 10 and 100
     */
    public void randomNumber() {
        Random r = new Random();
        int low = 10;
        int high = 100;
        number = r.nextInt(high - low) + low;
    }

    /**
     * 
     * @return number randomized.
     */
    public int getNumber() {
        return number;
    }
}

And finally, viewpager_fragment.xml source:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/text"
        android:layout_marginTop="10dp"
        android:gravity="center"
        android:text="@string/fragment" />

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:drawableLeft="@drawable/ic_previous"
        android:drawableRight="@drawable/ic_next"
        android:gravity="center"
        android:textSize="20sp" />

</RelativeLayout>

Running program, our result like this:

pic name pic name pic name
Hope this is helpful! :)

(Sorry for having ads in download link)

Share


Previous post
« Prev Post
Next post
Next Post »