How to pass a string between fragments in a viewpager - android

I'm trying to pass a string between two fragments in a viewpager but I didn't found the right way to do it.
Here is my code so far :
public class MyFragmentPagerAdapter extends FragmentPagerAdapter{
final int PAGE_COUNT = 6;
/** Constructor of the class */
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
/** This method will be invoked when a page is requested to create */
#Override
public Fragment getItem(int arg0) {
switch (arg0) {
case 0:
return new MyFragment();
case 1:
return new part2();
case 2:
return new Part3();
case 3:
return new Part4();
case 4:
return new Part5();
case 5:
return new Part6();
default:
return null;
}
}
/** Returns the number of pages */
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public CharSequence getPageTitle(int position) {
return "Page #" + ( position + 1 );
}
}
public class MainActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/** Getting a reference to the ViewPager defined the layout file */
ViewPager pager = (ViewPager) findViewById(R.id.pager);
/** Getting fragment manager */
FragmentManager fm = getSupportFragmentManager();
/** Instantiating FragmentPagerAdapter */
MyFragmentPagerAdapter pagerAdapter = new MyFragmentPagerAdapter(fm);
/** Setting the pagerAdapter to the pager object */
pager.setAdapter(pagerAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
I'm not using tabs with the viewpager. What should I write in the fragments?
UPDATE :
I tried to implement an interface like suggested in the answers :
public interface OnTogglePressListener {
public void onTogglePressed(String msg);
}
On the first fragment :
#Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
try {
buttonListener = (OnTogglePressListener) getActivity();
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement onTogglePressed");
}
super.onAttach(activity);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
// TODO Auto-generated method stub
buttonListener.onTogglePressed("Off");
... }
On the second fragment :
public String getEtat(String etat)
{ state =etat;
return etat;
}
On the main activity :
public void onTogglePressed(String etat)
{
Part5 p = (Part5)getSupportFragmentManager().findFragmentById(R.layout.frag_2);
p.getEtat(etat);
}
But I got a NullPointerException everytime.

You're obviously using ViewPager and you can take advantage of it. You can add a tag to a ViewPager like this:
Activity:
pager.setTag("some text"); // pager is a ViewPager object
Then you can get this data via ViewGroup in a fragment like this:
Fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
String result = container.getTag().toString();
// do something with the result
return view;
You can also setTag() to the container in the fragment.
This is the cleanest solution I found for sending data among fragments and their mother activity. Another solution (not mentioned here so far) is sending data through SharedPreferences, but I would suggest using tags if possible.

So i found the solution, the implementation is correct, the only thing that I should do the treatement I want in the method on the second fragment and that's it !

Related

View pager skipping to irregular position when I click button in second fragment android?

I am using view pager in activity and the sequence is - when I click the next button in first page, it should go to the second page. If I click the button in second page, it should go to third and so on. But my current app is behaving weird, i.e, When I click next button in second page, it goes to fourth page. Once again when I click first button in first page, it jumps to third page and so on..
Here is code.
public class ViewPagerActivity extends AppCompatActivity {
private ViewPager pager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewpager_act);
setViewPager();
/*pager.setPageTransformer(true, new ZoomPageTransformer());
pager.setAdapter(new MyViewPagerAdapter(getSupportFragmentManager()));
pager.post(new Runnable() {
#Override
public void run() {
pager.setCurrentItem(position); //don't know how to use this from fragment
}
});*/
}
private void setViewPager() {
pager = (ViewPager) findViewById(R.id.viewPager);
FragmentManager fm = getSupportFragmentManager();
ViewPagerAdapter adapter = new ViewPagerAdapter(fm);
pager.setAdapter(adapter);
}
public void setCurrentItem(int selectedPosition) {
pager.setCurrentItem(selectedPosition, true);
}
private class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager supportFragmentManager) {
super(supportFragmentManager);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return FirstPager.newInstance();
case 1:
return SecondPager.newInstance();
case 2:
return ThirdPager.newInstance();
case 3:
return FourthPager.newInstance();
case 4:
return FifthPager.newInstance();
case 5:
return SixthPager.newInstance();
default:
return null;
}
}
#Override
public int getCount() {
return 6;
}
}
FirstPager:
public class FirstPager extends Fragment {
private ImageView slideArrow;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.first_pager, container, false);
return v;
}
public static FirstPager newInstance() {
FirstPager fragment = new FirstPager ();
return fragment;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initUI();
}
private void initUI() {
slideArrow = (ImageView) getActivity().findViewById(R.id.next_arrow);
slideArrow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((ViewPagerActivity)getActivity()).setCurrentItem (1);
}
});
}
}
Similarly in other fragments, I gave currentItem as 2,3,4,5 and 6. But it’s position behavior is not correct.
I referred some post but how in my case, how I will apply for a method to pass from fragment to make the position to work correctly?
I think the best approach would be this:
viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
slideArrow = (ImageView) getActivity().findViewById(R.id.next_arrow);
Are you sure, you're calling this correctly? You're not.
You're calling findViewById of the arrow inside your activity. A ViewPager works by loading this page, and pre-loading next and previous pages for smooth swipe. And when you click the button on your 1st page, the last loaded page's (in your case 2nd page's) button click event gets called.
You must use the arrow button in each of your fragments
You can do something like this:
public class FirstPager extends Fragment {
private ImageView slideArrow;
View v;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
v = inflater.inflate(R.layout.first_pager, container, false);
return v;
}
public static FirstPager newInstance() {
FirstPager fragment = new FirstPager ();
return fragment;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initUI();
}
private void initUI() {
slideArrow = (ImageView) v.findViewById(R.id.next_arrow); // Note the difference in this line.
slideArrow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((ViewPagerActivity)getActivity()).setCurrentItem (1);
}
});
}
}
You can do two things here:
Firstly,Your viewpager has a override method onPageSelected() which return the select page positon. using this poistion element get the view and bind your button there and write listener there itself and write viewpager.setCurrentItem(i++); //if i is ur current position,but be sure to check if it is the last item.
secondly,you hold the position of the current fragment and
((ViewPagerActivity)getActivity()).setCurrentItem (next_frag_pos);
This code try working perfect.
public class ViewPagerActivity extends FragmentActivity {
private ViewPager pager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewpager_act);
setViewPager();
/*pager.setPageTransformer(true, new ZoomPageTransformer());
pager.setAdapter(new MyViewPagerAdapter(getSupportFragmentManager()));
pager.post(new Runnable() {
#Override
public void run() {
pager.setCurrentItem(position); //don't know how to use this from fragment
}
});*/
}
private void setViewPager() {
pager = (ViewPager) findViewById(R.id.viewPager);
FragmentManager fm = getSupportFragmentManager();
ViewPagerAdapter adapter = new ViewPagerAdapter(fm);
pager.setAdapter(adapter);
}
public void setCurrentItem(int selectedPosition) {
pager.setCurrentItem(selectedPosition, true);
}
private class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager supportFragmentManager) {
super(supportFragmentManager);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new FirstPager();
case 1:
return new SecondPager();
case 2:
return new ThirdPager();
case 3:
return new FourthPager();
case 4:
return new FifthPager();
case 5:
return new SixthPager();
default:
return null;
}
}
#Override
public int getCount() {
return 6;
}
}
}

ViewPager recreate fragments all the time

I am using ViewPager with my fragments. All fragments has animation and it does not work when switching back maybe because ViewPager saves somehow state of near Fragments, do you have some idea how to avoid it?
getItemPosition() doesn't make anything in this case
private class MyFragmentPagerAdapter extends FragmentPagerAdapter {
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public CharSequence getPageTitle(int position) {
return null;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return GetStartedOneFragment.newInstance();
case 1:
return GetStartedTwoFragment.newInstance();
case 2:
return GetStartedThreeFragment.newInstance();
case 3:
return GetStartedFourFragment.newInstance();
case 4:
return GetStartedFiveFragment.newInstance();
case 5:
return GetStartedSixFragment.newInstance();
default:
return GetStartedOneFragment.newInstance();
}
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
I used a Fragment as a slider content, see the sample code below. Feel free to ask more details if required.
I have 4 flight modes in the example. The ViewPager is used with the associated adapter (ScreenSlidePagerAdapter).
You can see the app in the Play Store to see the slider (search "Flight Recorder 24").
// In the main fragment java code
private View headerView;
private ViewPager mPager;
public ScreenSlidePagerAdapter mPagerAdapter;
// ...
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
super.onCreateView(inflater, container, savedInstanceState);
View mainView = inflater.inflate(R.layout.monitoring_fragment,container, false);
// The header of the list
View view = inflater.inflate(R.layout.header_monitoring_fragment, mListView, false);
headerView = view;
//...
mPager = (ViewPager) view.findViewById(R.id.pager);
FragmentManager fm = getChildFragmentManager();
mPagerAdapter = new ScreenSlidePagerAdapter(fm);
mPager.setAdapter(mPagerAdapter);
mPager.setCurrentItem(UserConfiguration.getUserConf().getPositionFromFlightMode());
// Attach the page change listener inside the activity
mPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener()
{
// This method will be invoked when a new page becomes selected.
#Override
public void onPageSelected(int position)
{
int flight_mode = UserConfiguration.getFlightModeFromPosition(position);
UserConfiguration.getUserConf().setFlightMode(flight_mode);
}
// This method will be invoked when the current page is scrolled
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
{
// Code goes here
}
// Called when the scroll state changes:
// SCROLL_STATE_IDLE, SCROLL_STATE_DRAGGING, SCROLL_STATE_SETTLING
#Override
public void onPageScrollStateChanged(int state)
{
// Code goes here
}
});
// ...
}
// ...
// Slider adapter
private class ScreenSlidePagerAdapter extends FragmentPagerAdapter
{
public ScreenSlidePagerAdapter(FragmentManager fm)
{
super(fm);
}
#Override
public Fragment getItem(int position)
{
// position to flight mode
int flight_mode = UserConfiguration.getFlightModeFromPosition(position);
FlightModeFragment flightModeFragment = FlightModeFragment.newInstance(flight_mode);
return flightModeFragment;
}
public int getItemPosition(Object object)
{
return POSITION_NONE;
}
#Override
public int getCount()
{
return 4;
}
}
Then you have to create a Fragment with your slider content (here the class FlightModeFragment), it will be instanciated with an integer to identify the page embedded into a Bundle savedInstanceState (I have 4 pages).
public class FlightModeFragment extends Fragment
{
LinearLayout mainLayout;
ImageView live15minImageView;
ImageView modeImageView;
ImageView imageViewLeft;
ImageView imageViewRight;
private TextView textViewRecord;
private TextView textViewGps;
int flight_mode = UserConfiguration.AC_LISTENER_TRAVEL_RECORDER_MODE;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// handle fragment arguments
Bundle arguments = getArguments();
if(arguments != null)
{
flight_mode = arguments.getInt("flight_mode");
}
}
// ...
}

Get fragment activity outside of Fragment.OnCreateView()

I have a Fragment with a TableLayout. The data in the table is from a SQLite db. The SQLite db is populated from a RESTful webservice in an AsyncTask in the MainActivity. The Fragment must wait for the task to complete before populating the table. The Fragment listens for the task onPostExecute() method to be called. When it is, the method onLoadAndStoreComplete in the Fragment is called. This all works.
What doesn't work is that I need the fragment activity in order to create new TableRows and TextViews in onLoadAndStoreComplete and I can't get it.
I've tried:
- making a class member fragmentActivity and assigning in onCreateView(), but by the time it gets to onLoadAndStoreComplete(), it is null.
- calling this.getActivity() again in onLoadAndStoreComplete(), but it returns null.
How do I get the fragment activity?
MyFragment.java:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
fragmentActivity = this.getActivity(); // return value is valid
...
}
#Override
public void onLoadAndStoreComplete() {
fragmentActivity = this.getActivity(); // returns null
...
}
from MainActivity.java (extends ActionBarActivity)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mainActivity = this;
setContentView(R.layout.activity_main);
Resources resources = getResources();
String[] tabTitleArray = { resources.getString(R.string.first_fragment),
resources.getString(R.string.second_fragment),
resources.getString(R.string.help_fragment) };
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getSupportActionBar();
mAdapter = new TabsPagerAdapter(this.getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
for (String tab_name : tabTitleArray) {
actionBar.addTab(actionBar.newTab().setText(tab_name).setTabListener(this));
}
// On swiping the ViewPager, select the respective tab
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position) ;// on changing the page, make respected tab selected
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
String url = "http://myrestfulwebservice";
Fragment secondFragment = mAdapter.getItem(SECOND_TAB);
new LoadAndStoreDataTask((OnLoadAndStoreCompleteListener)secondFragment).execute(url);
}
} // end OnCreate
TabsPagerAdapter.java
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new FirstFragment();
case 1:
return new SecondFragment();
case 2:
return new HelpFragment();
}
return null;
}
#Override
public int getCount() {
return 3; // get item count - equal to number of tabs
}
public static void setTabColor(TabHost tabhost) {
for(int i=0;i<tabhost.getTabWidget().getChildCount();i++) {
tabhost.getTabWidget().getChildAt(i).setBackgroundColor(Color.parseColor("#FF0000")); //unselected
}
tabhost.getTabWidget().getChildAt(tabhost.getCurrentTab()).setBackgroundColor(Color.parseColor("#0000FF")); // selected
}
}
I haven't tested this, but it seems to me that it would work.
Add a Context parameter to the constructor for both TabsPagerAdapter and MyFragment.
Something like this:
TabsPagerAdapter.java:
public class TabsPagerAdapter extends FragmentPagerAdapter {
private Context mCtx;
public TabsPagerAdapter(FragmentManager fragmentManager, Context context) {
super(fragmentManager);
mCtx = context;
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new FirstFragment(mCtx);
case 1:
return new SecondFragment(mCtx);
case 2:
return new HelpFragment(mCtx);
}
return null;
}
#Override
public int getCount() {
return 3; // get item count - equal to number of tabs
}
public static void setTabColor(TabHost tabhost) {
for(int i=0;i<tabhost.getTabWidget().getChildCount();i++) {
tabhost.getTabWidget().getChildAt(i).setBackgroundColor(Color.parseColor("#FF0000")); //unselected
}
tabhost.getTabWidget().getChildAt(tabhost.getCurrentTab()).setBackgroundColor(Color.parseColor("#0000FF")); // selected
}
}
MainActivity.java:
mAdapter = new TabsPagerAdapter(this.getSupportFragmentManager(), this);
MyFragment.java (do this in FirstFragment, SecondFragment, and HelpFragment):
public static class MyFragment extends Fragment {
private Context fragmentActivity ;
public MyFragment(Context context){
fragmentActivity = context;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//.........
return rootView;
}
#Override
public void onLoadAndStoreComplete() {
//do something with fragmentActivity
}
}
It seems the AsyncTask starts too early. suggest loading the db in onActivityCreated(), it's be called after onCreateView
#Override
public void onActivityCreated (Bundle savedInstanceState) {
//load your db here
}

How to get the selected page index of ViewPager in fragment

I'm making use of ViewPagerIndicator, and I have my adapter defined like this:
public class MyPagerAdapter extends FragmentPagerAdapter implements
IconPagerAdapter {
private final static String TAB_ITEMS[] = { "Tab 1", "Tab 2", "Tab 3", "Tab 4"};
private int count = TAB_ITEMS.length;
public MyPagerAdapter (FragmentManager fm) {
super(fm);
}
#Override
public int getIconResId(int index) {
// TODO Auto-generated method stub
return 0;
}
#Override
public Fragment getItem(int position) {
Fragment fragment = new BaseFragment();
return fragment;
}
#Override
public int getCount() {
return count;
}
And this is my activity that will contain my fragments:
public class MyActivity extends FragmentActivity implements
OnPageChangeListener {
private int tabPosition;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager pager = (ViewPager) findViewById(R.id.pager);
MyPagerAdapter adapter = new MyPagerAdapter (
getSupportFragmentManager());
pager.setAdapter(adapter);
UnderlinePageIndicator indicator = (UnderlinePageIndicator) findViewById(R.id.indicator);
indicator.setFades(false);
indicator.setViewPager(pager);
indicator.setOnPageChangeListener(this);
}
#Override
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
}
#Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
// TODO Auto-generated method stub
}
#Override
public void onPageSelected(int position) {
// TODO Auto-generated method stub
setTabPosition(position);
Toast.makeText(MyActivity.this,
"Changed to page: " + position, Toast.LENGTH_SHORT).show();
}
public void setTabPosition(int position) {
this.tabPosition = position;
}
public int getTabPosition() {
return this.tabPosition;
}
}
Finally the definition of BaseFragment:
public class BaseFragment extends Fragment implements OnItemClickListener {
private final static String TAG = "BaseFragment";
private int tabPosition;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_base, container,
false);
return view;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
tabPosition = ((MyActivity) getActivity()).getTabPosition();
Toast.makeText(getActivity(), "page " + tabPosition, Toast.LENGTH_SHORT)
.show();
}
Now , this is my problem:
The toast in onPageSelected of the activity always shows the correct page when a new page is selected or swiped to.
However, the toast in my fragment only shows the correct page when you swipe to either page 1 or page 2. The only time it toasts page 0 is anytime the app is launched. After that, when the user swipes to page 0 or page 4, no toast is shown at all, not even an empty toast.
I wrote the getTabPosition() and setTabPosition() methods with the intention of getting the current selected tab position in the fragment, but it obviously doesn't work correctly hence I dont get toasts on pages 0 and 4.
My question is: how do I get the selected page position in my BaseFragment, since I need that position to load the appropriate data?
Hope I was clear enough?
Each Fragment will display a different set of data, then maybe it is a good idea to have one fragment for each. Here is what I did to display different Fragments for different data in the FragmentPagerAdapter:
#Override
public Fragment getItem(int index) {
Fragment fragment = null;
// Define the page for each index
switch(index){
case 0:
fragment = new Fragment1();
break;
case 1:
fragment = new Fragment2();
break;
case 2:
fragment = new Fragment3();
break;
}
This may not be the best approach but in your activity that holds reference to ViewPager try this:
public class TabbedViewActivity extends FragmentActivity {
ViewPager viewPager;
public static int tabIndex = 0;
#Override
protected void onCreate(Bundle bundle) {
......
viewPager = (ViewPager)findViewById(R.id.pager);
TabbedViewActivity.tabIndex = 0; // in the start index is always 0 unless coded otherwise
viewPager.setOnPageChangeListener(
new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
TabbedViewActivity.tabIndex = position;
}
});
}
Then you can always access this variable statically like this in your Fragment TabbedViewActivity.tabIndex
pager.getCurrentItem();
it return current fragment index

Refresh fragment view when button is clicked

I have a fragment activity that uses a ViewPager to display a set of fragments. On the fragment activity I have a button that when clicked, it sends a message to the current fragment to refresh its contents. Everything works ok (activity / current fragment communication) except the fact that I cannot refresh the fragment's view. Accessing the current view by getView() does not work as this function returns null; it seems that after the fragment is created (on ViewCreated is called) getView gets destroyed. Am I missing something here? How to I cause a fragment to redraw its contents programmatically? It seems that the only way this works is when the fragment is created from the parent activity. Do I have to remove and re-add the fragment again to do this?
Here is the code:
The main activity:
public class MainActivity extends FragmentActivity {
private MyAdapter mAdapter;
private static ViewPager mPager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupViewPager();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
return super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_test:
updateFragment();
return true;
default: return true;
}
}
private void updateFragment() {
for (int i=0; i< mAdapter.getCount(); i++) {
SampleFragment fragment = (SampleFragment) mAdapter.getItem(i);
fragment.update();
}
}
private void setupViewPager() {
try {
mAdapter = new MyAdapter(getSupportFragmentManager());
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(this.mAdapter);
} catch (Exception e) {
e.printStackTrace();
}
}
public class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
SampleFragment fragment = new SampleFragment(position);
return fragment;
}
#Override
public int getCount() {
return 5;
}
}
}
and the fragment class:
public class SampleFragment extends Fragment{
private int myPosition = -1;
public SampleFragment(int position) {
this.myPosition = position;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment, container, false);
update(view, "Updated from onCreateView");
return view;
}
#Override
public void onActivityCreated(Bundle bundle) {
super.onActivityCreated(bundle);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.textTitle).setOnClickListener(myClickListener);
}
private OnClickListener myClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.textTitle:
break;
}
}
};
public void update() {
update(getView(), "Updated from main");
}
private void update(View view, String subtitleText) {
TextView title = (TextView) view.findViewById(R.id.textTitle);
TextView subtitle = (TextView) view.findViewById(R.id.textSubtitle);
title.setText("Fragment " + myPosition);
subtitle.setText(subtitleText);
}
}
The error happens on view.FindViewById (view is null) when called from the menu item in the main activity.
You can take a look at this article which explains how to keep references to the fragments in your ViewPager.
There are two methods described on the page. The first one involves setting a tag when you add the fragment using the FragmentManager. Then you can retrieve the fragment using findFragmentByTag(). However, I did not see how to make this work using FragmentPagerAdapter or FragmentStatePagerAdapter, since these implementations add the fragments for you. If you are using your own custom PagerAdapter, this may work for you.
The other method, which does work for FragmentPagerAdapter or FragmentStatePagerAdapter, involves keeping a map of all your fragments, updating inside your getItem() and destroyItem() implementations. This method has worked for me.
Once you have a reference to the current fragment, you can just call a method in your fragment to refresh its view.

Categories

Resources