3

so i'm using ViewPager to make my app much faster , instead of using an activity for each layout.

the problem is , in activity you can write your code inside onCreate and it will only starts when you start the activity , right?

but when you go with fragments and fragmentPagerAdapter and use ViewPager for them.

all your fragments going to start their (onCreateView) together even if your ViewPager only showing the First Fragment!

if you are you playing a sound or animation on the start of a fragment , it will starts in the background !

here's my fragmentPagerAdapter class:

public class PagerAdapter extends FragmentStatePagerAdapter {

    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitle = new ArrayList<>();

    public PagerAdapter(FragmentManager fm) {

        super(fm);

    }

    @Override
    public Fragment getItem(int position) {

        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    public void addFragment(Fragment fragment, String title) {

        mFragmentList.add(fragment);
        mFragmentTitle.add(title);
    }


}

and i have this (second Fragment) that i don't want it to starts without being seleceted!

public class GameFragment extends Fragment{
    private View gameLayout
    private Animation showBtn;
    private Button button;


    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        gameLayout = inflater.inflate(R.layout.game_layout, container, false);



        button = gameLayout .findViewById(R.id.button);


      // loading my anim xml file
       showBtn = AnimationUtils.loadAnimation(getContext(),R.anim.btn_show);



       button.startAnimation(showBtn);

        loadLevel();






    return  gameLayout 
    }

finally this is my Activity that have ViewPager :

public class ControllerActivity extends AppCompatActivity {

    public CustomPager viewPager;

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


      viewPager = findViewById(R.id.viewPager);
              PagerAdapter adapter = new PagerAdapter(getSupportFragmentManager());

        adapter.addFragment(new HomeFragment(),"Home");
        adapter.addFragment(new GameFragment(),"Game");
        viewPager.setAdapter(adapter);








      viewPager.setCurrentItem(0);


    }

i need your help to show me my mistakes here and what is the correct way

Loving Android
  • 253
  • 5
  • 15

2 Answers2

4

Using an OnPageChangeListener in your View Pager, you can detect which fragment is currently shown in the View Pager. You'll then need to check which fragment is shown and then call a method on that fragment's class to start any sounds for example that you don't want to start until the fragment is the fragment in view.

You should use an interface for this.

Here you can find an example of using an OnPageChangeListener.

Here you can find an example of Activity to Fragment communication using interfaces. This example has a lot of code that won't be relevant to your use case, but demonstrates the use of interfaces.

Tom Alabaster
  • 965
  • 6
  • 12
  • since i'm a beginner one more question , is it bad to write heavy code inside OnCreateView for each fragment ? like initializing things and views.? or where exactly i do it . – Loving Android Feb 13 '18 at 11:47
  • Initialising views inside the onCreateView is just fine, in fact, it's where they should go as this method is only called when the view is being created (funnily enough), so the views will only be created once. – Tom Alabaster Feb 13 '18 at 11:51
  • clear enough! now i just have to learn how to call a method from game fragment inside : @Override public void onPageSelected – Loving Android Feb 13 '18 at 11:56
  • Have a look around online. If you get stuck, ask it as another question :) – Tom Alabaster Feb 13 '18 at 12:00
  • can you please take a look at my new question? nobody cares :( https://stackoverflow.com/q/48912872/8729401 – Loving Android Feb 21 '18 at 22:30
1

One way to do it "Might" be to just initialize the view of the fragment in onCreateView :

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

        return view;
}

Then in the override the setUserVisibleHint() function and do the rest of the initialization there. This function is called when ever the fragment is in view.

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);

// do the rest of the code here.

}

I haven't used setuserVisibleHint for this purpose yet. But you can try it. Let me know too.

Mohit
  • 134
  • 7
  • have you tried this ? it gives me an error : Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference – Loving Android Feb 13 '18 at 11:51
  • I haven't used setUserVisibleHint specifically for this purpose, but i will check it out and update my answer. – Mohit Feb 13 '18 at 11:54
  • Hey Buddy , i tried executing some non ui functions from the same, and it worked. – Mohit Feb 21 '18 at 12:01
  • @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if (isVisibleToUser) { Log.e(this.getClass().toString(), "getting all accounts"); fetchAccountsFromServer(); } } – Mohit Feb 21 '18 at 12:01
  • and some UI work too... that also worked :) :) I initialized the main View from onCreateView, and then rest of the things in setUserVisibleHint. worked fine. :) – Mohit Feb 21 '18 at 12:07
  • can you please take a look at my new question ? nobody cares :( https://stackoverflow.com/q/48912872/8729401 – Loving Android Feb 21 '18 at 22:31
  • sure i will do my best – Mohit Feb 23 '18 at 15:40