Reputation: 101
Okay, this must be so simple and obvious that no one can believe that anyone would ask it. I have researched it for over a day and I can't find an answer. It's possible that my entire understanding of how this should work is flawed, but, here is my issue.
I have 2 fragment tabs ParFragment
and HandicapFragment
running under an activity called EnterCourseData
via a FragmentStatePagerAdapter
called TabsPagerAdapter
. Both fragments show 2 EditText
views that display the same values and both fragments have a save button that grabs these values from the EditText views and saves these values. The button also initiates a callback to notify the EnterCourseData
activity that the values may have changed. I want EnterCourseData
to force both fragments to update with the new values. My assumption is that since both tabs exist during this time, both are accessible. I am trying to get to one using findFragmentByTag("ParFragment")
, but I am getting a null value.
Please, either tell me what I am doing is best handled some other way, or tell me how to fix what I am doing. Here's the code...
Here's the TabsPagerAdapter
:
public class TabsPagerAdapter extends FragmentStatePagerAdapter {
int courseNumber, teeNumber;
public TabsPagerAdapter(FragmentManager fm, int courseNumber, int teeNumber) {
super(fm);
this.courseNumber = courseNumber;
this.teeNumber = teeNumber;
}
@Override
public Fragment getItem(int index) {
switch (index) {
case 0:
// Par Entry activity
Fragment parFragment = new ParFragment();
Bundle args = new Bundle();
args.putInt(ParFragment.ARG_COURSE_NUMBER, courseNumber);
args.putInt(ParFragment.ARG_TEE_NUMBER, teeNumber);
parFragment.setArguments(args);
return parFragment;
case 1:
// Handicap Entry fragment activity
Fragment hcpFragment = new HandicapFragment();
args = new Bundle();
args.putInt(HandicapFragment.ARG_COURSE_NUMBER, courseNumber);
args.putInt(HandicapFragment.ARG_TEE_NUMBER, teeNumber);
hcpFragment.setArguments(args);
return hcpFragment;
}
return null;
}
@Override
public int getCount() {
// get item count - equal to number of tabs
return 2;
}
}
Here's one of the two (almost) identical fragments:
public class ParFragment extends Fragment {
public static final String ARG_COURSE_NUMBER = "courseNumber", ARG_TEE_NUMBER = "teeNumber";
Tee tee;
String courseName;
View rootView;
OnParSavedListener mCallback;
// Container Activity must implement this interface
public interface OnParSavedListener {
public void onParSaved();
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (OnParSavedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnParSavedListener");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_par, container, false);
Button buttonSave = (Button) rootView.findViewById(R.id.savePars);
buttonSave.setOnClickListener(savePars);
Bundle args = getArguments();
Course course = Global.getCourse(args.getInt(ARG_COURSE_NUMBER));
courseName = course.getName();
((TextView) rootView.findViewById(R.id.display_course_name)).setText(course.getName());
tee = course.getTee(args.getInt(ARG_TEE_NUMBER));
((TextView) rootView.findViewById(R.id.display_tee_name)).setText(tee.getTeeName());
refreshParScreen();
return rootView;
}
View.OnClickListener savePars = new View.OnClickListener() {
public void onClick(View v) {
tee.setSlope(Integer.parseInt(((EditText) rootView.findViewById(R.id.enter_tee_slope)).getText().toString()));
tee.setRating(Double.parseDouble(((EditText) rootView.findViewById(R.id.enter_tee_rating)).getText().toString()));
GolfTools.addUpdateCourse(rootView.getContext(), Global.getCourse(courseName));
mCallback.onParSaved();
}
};
public void refreshParScreen(){
((TextView) rootView.findViewById(R.id.enter_tee_slope)).setText(Integer.toString(tee.getSlope()));
((TextView) rootView.findViewById(R.id.enter_tee_rating)).setText(Double.toString(tee.getRating()));
}
}
and here's most of the activity:
public class EnterCourseData extends FragmentActivity implements ActionBar.TabListener, ParFragment.OnParSavedListener{
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
// Tab titles
private String[] tabs = { "Pars", "Handicaps" };
private int courseNumber, teeNumber;
public void onParSaved() {
// The user saved the Par sheet
// Refresh par and Handicap tabs
ParFragment parFrag = (ParFragment) getSupportFragmentManager().findFragmentByTag("ParFragment");
if (parFrag != null) {
parFrag.refreshParScreen();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_enter_tees);
// Initialization
Intent mIntent = getIntent();
courseNumber = mIntent.getIntExtra("courseNumber",0);
teeNumber = mIntent.getIntExtra("teeNumber",0);
viewPager = (ViewPager) findViewById(R.id.fragment_container);
actionBar = getActionBar();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager(), courseNumber, teeNumber);
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() {
.
.
.
I get all the way to the Activity after the button is pressed in the fragment and I want to call the fragment method to repopulate the screen. I use ParFragment parFrag = (ParFragment) getSupportFragmentManager().findFragmentByTag("ParFragment");
and I get a null value. I know "ParFragment" exists because that's how we got here. My understanding is 1) get a pointer to the fragment and, 2) call the method using the pointer.
Please, tell me where my thinking is flawed and exactly how to make this happen.
Thank you
Upvotes: 1
Views: 354
Reputation: 10530
FragmentStatePagerAdapter
does not use tags when adding fragments to the Activity. That is why findFragmentByTag
is returning null.
You need to use the method instantiateItem
to get the fragment. To get fragment #0.
ParFragment parFrag = (ParFragment) mAdapter.instantiateItem(viewPager, 0)
See this answer.
Upvotes: 2