akafortes
akafortes

Reputation: 149

Use data from FragmentActivity with ViewPager, for custom ListView adapter inside a Fragment

A few background info first. I have a service running in the background that connects to a server. My application uses this connection to get data from the server. I get a list of users and a list of friends and I display each list in its own Activity with a ListView. I use a custom adapter to populate these ListViews that takes an arraylist of type ArrayList. User is a custom class I've created. Everything works great.

Now I want to move from separate Activities, to one Activity with two tabs.
So using this tutorial I've created two tabs, one for Users and one for Friends. I have a Main Activity with a ViewPager, a FragmentPagerAdapter and two Fragement, one for Users and one for Friends.

MainActivity:

public class MainActivity extends FragmentActivity implements ActionBar.TabListener {

    private ViewPager viewPager;
    private TabsPagerAdapter mAdapter;
    private ActionBar actionBar;
    // Tab titles
    private String[] tabs = { "Friends", "Users" };
    private ArrayList<User> listUsers = new ArrayList<User>();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.v(TAG, "onCreate");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Initilization
        viewPager = (ViewPager) findViewById(R.id.pager);
        actionBar = getActionBar();
        mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
        viewPager.setAdapter(mAdapter);
        // actionBar.setHomeButtonEnabled(false);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        // Adding Tabs
        for (String tab_name : tabs) {
            actionBar.addTab(actionBar.newTab().setText(tab_name).setTabListener(this));
        }

        /**
         * on swiping the viewpager make respective tab selected
         * */
        viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            @Override
            public void onPageSelected(int position) {
                // on changing the page
                // make respected tab selected
                actionBar.setSelectedNavigationItem(position);
            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
            }

            @Override
            public void onPageScrollStateChanged(int arg0) {
            }
        });     

    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        // on tab selected
        // show respected fragment view
        viewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    }
}

I have left out the communication/handle of data from the service. It works without and would just take up space.
activity_main:

<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

</android.support.v4.view.ViewPager>

TabsPagerAdapter:

public class TabsPagerAdapter extends FragmentPagerAdapter {

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


    @Override
    public Fragment getItem(int index) {

        switch (index) {
        case 0:
            // Top Rated fragment activity
            return new FriendsFragment();
        case 1:
            // Games fragment activity
            return new UsersFragment();
        case 2:
            // Games fragment activity
            return new UsersFragment();
        }

        return null;
    }

    @Override
    public int getCount() {
        // get item count - equal to number of tabs
        return 3;
    }

}

Both UsersFragment and FriendsFragment work the same way so I'll just post the code for one.
UsersFragment:

public class UsersFragment extends Fragment {    
    private static final String TAG = "UsersFragment";

    private ArrayList<User> listUsers = new ArrayList<User>();
    private MyCustomAdapter mAdapter;
    private ListView lv;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.v(TAG, "onCreateView here");
        View rootView = inflater.inflate(R.layout.fragment_users, container, false);

        return rootView;
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.v(TAG, "onStart here");
        lv = (ListView) getView().findViewById(R.id.listView1);
        mAdapter = new MyCustomAdapter(getActivity(), listUsers);

        lv.setAdapter(mAdapter);
    }
}

fragment_users:

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

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true" >
    </ListView>

</RelativeLayout>

What I want to do is get the listusers, that I populate in the MainActivity and use it to populate the ListView inside UserFragment/FriendsFragment.

Upvotes: 0

Views: 1701

Answers (1)

Myz
Myz

Reputation: 828

So here a little bit detail... you have two options, 1) either you implement interface with your MainActivity (which I think is a proper solution) 2) OR access your UsersFragment from your MainActivity by calling getSupportFragmentManager.findFragmentByTag(). But this will most probably throw NullPointer exception.. I am a lazy guy so i prefer 2nd option and there is a solution for it too....

In your MainActivity, define:

String TabUsersFragment ;

public void setTabUsersFragment (String t){
    TabUsersFragment  = t;
}

public String getTabUsersFragment(){
    return TabUsersFragment;
}

You can use getTag() method in onCreateView() of UsersFragment. method to get the tag name of current fragment and then pass it to the main activity.

In your UsersFragment define:

public void b_updateText(String t){
    b_received.setText(t);
}

and in onCreateView(),

String myTag = getTag();

((MainActivity)getActivity()).setTabUsersFragment(myTag);

Now you have the tag for your UsersFragment in your MainActivity. You can call methods of your UsersFragment by using this tag to update/modify whatever you want. For example, in your MainActivity

UsersFragment userFrag = (UsersFragment) getSupportFragmentManager()
                        .findFragmentByTag(TabUsersFragment);

            userFrag.b_updateText(textPassToB);

You can find the working example of this whole mechanism in the reference link below.

Caution: But, you have to take care about live-cycle of the Fragments. For example, may be the target Fragment have not yet created when data is passed. Or, the Fragment have been destroyed after data passed.Read more about the fragment life cycle on this link.

Reference: http://android-er.blogspot.fi/2012/06/communication-between-fragments-in.html

Upvotes: 2

Related Questions