2

I'm currently trying to programmatically add a fragment which has a view that I need to initializate immediately after the fragment is created. I tried to use FragmentManager.executePendingTransactions() right after FragmentTransition.commit(), but it doesn't work as it supposed to. I've made a research and found this, so I realized that FragmentManager.executePendingTransactions() doesn't work from onCreate() and then put code to onStart(), but it still doesn't work. Although in my case it's called from onItemClickListener(), I don't think it makes any difference. Here's my code:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.vk_music_list);
    musicProgressBar = new MusicProgressBar();
    listView = (ListView) findViewById(R.id.listView);
}

@Override
protected void onStart() {
    super.onStart();
    listView.setOnItemClickListener(this);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    String audioUrl = ((VKApiAudio) parent.getAdapter().getItem(position)).url;
    serviceIntent.putExtra("audioUrl", audioUrl);

    //Inflate music progress bar
    fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragment = fragmentManager.findFragmentById(R.id.musicBarContainer);
    if(fragment == null) {
        fragmentTransaction.add(R.id.musicBarContainer, musicProgressBar)
                .setTransition(R.anim.move_from_the_bottom)
                .commit();
    }

    //This guy doesn't work
    fragmentManager.executePendingTransactions();

    //Never get into this, because fragment is always == null
    if(fragment != null) {
        SeekBar seekBar = (SeekBar) fragment.getView().findViewById(R.id.progressBar);
        seekBar.setMax(((VKApiAudio) parent.getAdapter().getItem(position)).duration);
    }
    startService(serviceIntent);
}
Community
  • 1
  • 1
ulmaxy
  • 820
  • 2
  • 14
  • 22

1 Answers1

3

Alright, I finally found out what the issue is. The reason of the problem is that neither fragmentTransaction.commit() nor fragmentManager.executePendingTransactions() change reference that is stored in fragment variable. Therefore, after executePendingTransactions() I need to call findFragmentById() again, so reference that it stores will refer to the created fragment. Here's a working code:

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    String audioUrl = ((VKApiAudio) parent.getAdapter().getItem(position)).url;
    serviceIntent.putExtra("audioUrl", audioUrl);

    //Inflate music progress bar
    fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragment = fragmentManager.findFragmentById(R.id.musicBarContainer);
    if(fragment == null) {
        fragmentTransaction.add(R.id.musicBarContainer, musicProgressBar)
                .commit();
    }

    //Force to create fragment without scheduling so it's not necessarily to wait until it get scheduled
    fragmentManager.executePendingTransactions();

    //This is what I needed
    fragment = fragmentManager.findFragmentById(R.id.musicBarContainer);

    //Set song duration as a seekBar's maximum
        if (fragment != null) {
            SeekBar seekBar = (SeekBar) fragment.getView().findViewById(R.id.progressBar);
            seekBar.setMax(((VKApiAudio) parent.getAdapter().getItem(position)).duration);
        }
    startService(serviceIntent);
}

I hope it will be helpful for somebody.

ulmaxy
  • 820
  • 2
  • 14
  • 22