0

I'm trying to update an object from a fragment contained within a swipe view. The code I have is taken directly from the Android documentation. What I want to do is pass an object from the main CollectionDemoActivity down into the DemoObjectFragment fragment, update it using a button in that fragment and then pass it back up to the main activity. What's the best way to accomplish this?

I've tried passing the object in a bundle as a serialisable through the DemoCollectionPagerAdapter and then again down to the fragment but this seems really cumbersome. I've also tried declaring the object in the main activity and just referencing it in the fragment class but I get complaints that it can't have a non-static reference in a static context.

public class CollectionDemoActivity extends FragmentActivity {

// When requested, this adapter returns a DemoObjectFragment,
// representing an object in the collection.

DemoCollectionPagerAdapter mDemoCollectionPagerAdapter;
ViewPager mViewPager;

public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_collection_demo);

    // ViewPager and its adapters use support library
    // fragments, so use getSupportFragmentManager.
    mDemoCollectionPagerAdapter =
            new DemoCollectionPagerAdapter(
                    getSupportFragmentManager());
    mViewPager = (ViewPager) findViewById(R.id.pager);
    mViewPager.setAdapter(mDemoCollectionPagerAdapter);
}
}

// Since this is an object collection, use a FragmentStatePagerAdapter,
// and NOT a FragmentPagerAdapter.
public class DemoCollectionPagerAdapter extends FragmentStatePagerAdapter {
public DemoCollectionPagerAdapter(FragmentManager fm) {
    super(fm);
}

@Override
public Fragment getItem(int i) {
    Fragment fragment = new DemoObjectFragment();
    Bundle args = new Bundle();
    // Our object is just an integer :-P
    args.putInt(DemoObjectFragment.ARG_OBJECT, i + 1);
    fragment.setArguments(args);
    return fragment;
}

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

@Override
public CharSequence getPageTitle(int position) {
    return "OBJECT " + (position + 1);
}
}

// Instances of this class are fragments representing a single
// object in our collection.
public static class DemoObjectFragment extends Fragment {
public static final String ARG_OBJECT = "object";

@Override
public View onCreateView(LayoutInflater inflater,
        ViewGroup container, Bundle savedInstanceState) {
    // The last two arguments ensure LayoutParams are inflated
    // properly.
    View rootView = inflater.inflate(
            R.layout.fragment_collection_object, container, false);
    Bundle args = getArguments();
    ((TextView) rootView.findViewById(android.R.id.text1)).setText(
            Integer.toString(args.getInt(ARG_OBJECT)));
    return rootView;
}
}
Darragh.McL
  • 125
  • 1
  • 10

1 Answers1

0

So after a lot of searching and reading I found a nice solution that works for me. For those interested I created an interface in the fragment class that is implemented in the Main activity. The methods were kicked off through a button press in the fragment class. This way I was able to pass variables up to the main class without ever needing to pass the entire object down to the fragment.

So my classes were mostly the same with these bits added:

And the fragment class which contains the interface. The onAttach() method needs to be called which gets a reference to the activity that the fragment will be attached to. This activity reference is binded to an instance of the interface in the fragment.

public class DemoObjectFragment extends Fragment {

....

//Creating the interface
public interface ButtonListener {
 //This method will be called in the main activity. Whatever is passed in as the parameter can be used by the main activity
    public void ButtonPressed(int myInt);
}

//Getting an instance of the interface
ButtonListener updateListener;


//Getting a reference to the main activity when the fragment is attached to it.
//The activity reference is bound to the instance of the interface.
@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

    // Ensures the activity implements the callback interface
    try {
        updateListener = (DayUpdateButtonListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString());
    }
}

....

//On the button click call the method through the activity reference from the onAttach() method
//Creating an int object to pass into the method.
int myNewInt = 5;

myButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            updateListener.ButtonPressed(myNewInt);
        }

    });

}

Finally in the main activity simply implement the interface and add the method from it.

public class CollectionDemoActivity extends FragmentActivity implements DemoObjectFragment.ButtonListener {

....

@Override
public void ButtonPressed(int myInt) {
//Update the object with myInt
}


}
Darragh.McL
  • 125
  • 1
  • 10