Good day. I'm trying to use fragments in the application. The first fragment displays the image, the second text. At startup, a fragment with a picture is set, when you select Drawer in the side menu, the picture in the fragment is set, everything is fine, then I click on the button in the activation ( onClick method), the fragment with the picture is replaced with the second fragment with text and the work is done there, everything is fine too. But then when I click the item in the side menu again, I get an NPE error in the line ((ImageView) frag.getView().findViewById(R.id.fragment_horoicon)).setImageResource(R.drawable.oven); (also indicated with a comment in the code), although it seems that before switching to a switch he made a change of a fragment with text to a fragment with a picture. Please tell me where the error lies? Thank.

PS MaterialDrawer is used for side menu

MainActivity.java

 import android.app.Fragment; import android.app.FragmentTransaction; import android.os.AsyncTask; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; import com.mikepenz.materialdrawer.Drawer; import com.mikepenz.materialdrawer.DrawerBuilder; import com.mikepenz.materialdrawer.model.DividerDrawerItem; import com.mikepenz.materialdrawer.model.PrimaryDrawerItem; import com.mikepenz.materialdrawer.model.SecondaryDrawerItem; import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import java.io.IOException; public class MainActivity extends AppCompatActivity { Drawer drawer; Fragment_image frag_image; Fragment_text frag_text; FragmentTransaction frag_trans; Button button_yesterday; String link; String prelink; Parser par; String text; String date; Fragment frag; public void onClick(View view) { frag_trans = getFragmentManager().beginTransaction(); frag_trans.replace(R.id.frag_container, frag_text); // замСняСм Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ с ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΎΠΉ Π½Π° Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ с тСкстом frag_trans.commit(); switch (view.getId()) { case R.id.button_yesterday: link = prelink + "yesterday.html"; break; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); frag_image = new Fragment_image(); frag_text = new Fragment_text(); button_yesterday = (Button) findViewById(R.id.button_yesterday); frag_trans = getFragmentManager().beginTransaction(); frag_trans.add(R.id.frag_container, frag_image); // устанавливаСм ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ с ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΎΠΉ frag_trans.commit(); frag = getFragmentManager().findFragmentById(R.id.frag_container); PrimaryDrawerItem item1 = new PrimaryDrawerItem().withIdentifier(1).withName(R.string.select_sign).withSelectable(false); SecondaryDrawerItem item2 = (SecondaryDrawerItem) new SecondaryDrawerItem().withIdentifier(2).withName(R.string.oven); drawer = new DrawerBuilder() .withActivity(this) .withHeader(R.layout.drawer_header) .withTranslucentStatusBar(true) .withActionBarDrawerToggleAnimated(true) .withSelectedItem(-1) .addDrawerItems( item1, new DividerDrawerItem(), item2 ) .withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() { @Override public boolean onItemClick(View view, int position, IDrawerItem drawerItem) { frag_trans = getFragmentManager().beginTransaction(); frag_trans.replace(R.id.frag_container, frag_image); // ΠΏΡ€ΠΈ ΠΊΠ»ΠΈΠΊΠ΅ Π² Π±ΠΎΠΊΠΎΠ²ΠΎΠΌ мСню ΠΏΠΎ ΠΏΡƒΠ½ΠΊΡ‚Ρƒ списка устанавливаСм Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ с ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΎΠΉ ΠΈ ΠΏΠΎΠ΄Π³Ρ€ΡƒΠΆΠ°ΡŽ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΡƒ Π² ImageView frag_trans.commit(); frag = getFragmentManager().findFragmentById(R.id.frag_container); switch ((int) drawerItem.getIdentifier()) { case 2: ((ImageView) frag.getView().findViewById(R.id.fragment_horoicon)).setImageResource(R.drawable.oven); // Ρ‚ΡƒΡ‚ ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽ NPE break; default: break; } return true; } }) .build(); } } 

UPD

 public class MainActivity extends AppCompatActivity { Fragment_image frag_image; Fragment_text frag_text; FragmentTransaction frag_trans; Fragment frag; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); frag_image = new Fragment_image(); frag_text = new Fragment_text(); frag_trans = getFragmentManager().beginTransaction(); frag_trans.add(R.id.frag_container, frag_image); frag_trans.commit(); getFragmentManager().executePendingTransactions(); frag = getFragmentManager().findFragmentById(R.id.frag_container); Handler handler = new Handler(); handler.postDelayed(new Runnable() { public void run() { ((ImageView)frag.getView().findViewById(R.id.fragment_horoicon)).setImageResource(R.drawable.choose_sign); } }, 100); } } 
  • It seems that there you have not the fragment that you expect. Check the specific class of the fragment in the moment of pressing and look for a mistake in logic - YuriySPb ♦
  • @YuriySPb, when you start, a fragment of the picture normally works, the fragment of the text also changes normally, but back to the fragment with a picture it knocks an error. Although in fact before the switch in Drawer I change the fragment frag_trans.replace(R.id.frag_container, frag_image); If the first time the picture works, then everything is fine with the fragment class itself. Previously, the fragments did not work, so the suspicion that somewhere I make a mistake in the principles of changing fragments. - Pollux
  • Commit does not work synchronously. By this, the Foagment washes do not have time to be replaced. In general, your way of referring to fragment markup is not correct. But try calling commitNow instead of just a com - YuriySPb ♦
  • @YurySPb commitNow there is no such method ... there is only .commitAllowingStateLoss() . I use android.app.Fragment . Regarding the appeal to the markup, I did this lesson - Pollux
  • one
    @Yuriy SPb, and once again you are helping me out) Thank you so much! Added after commit getFragmentManager().executePendingTransactions(); and it all worked. Please write as an answer, I will note. - Pollux

1 answer 1

Try calling getFragmentManager().executePendingTransactions(); right after commit() . You have a problem in that, operations with fragments do not occur synchronously. And there is no markup at the time of addressing it. And this method will cause the immediate, synchronous execution of all current transactions.

  • I did not want to create the same topic, but I really want to ask you. Considered a piece of code updated in the first post after UPD . It took me when I started the application to install the image in the container. I did everything as it should be, added getFragmentManager().executePendingTransactions(); , but again on the line ((ImageView)frag.getView().findViewById(R.id.fragment_horoicon)).setImageResource(R.drawable.choose_sign); the beginning is dying with NPE I think it is necessary to add a pause so that the container has time to load .. Added a pause with the help of Handler and then it worked. - Pollux
  • But here's an interesting point: if I getFragmentManager().executePendingTransactions(); string getFragmentManager().executePendingTransactions(); and put a pause even for 5 seconds in the Handler (well, I think so that the container will probably boot up) and as a result, after 5 seconds, the same crash again ... Now, in general, it’s not clear to me why it crashes anyway, if a lot of time has passed ... And why here does not roll getFragmentManager().executePendingTransactions(); ... - Pollux
  • @Pollux, I think, if you do not cause a synchronous execution of a transaction, then you, looking for a fragment by ID, get the old fragment, but your ImageView doesn’t. Try searching for the fragment also in the postponed task, but not in front of it - YuriySPb ♦
  • Above the post you said that I am referring incorrectly to the markup. Maybe I use outdated methods and therefore these errors. Can you tell me how to do it correctly so that there are no such errors or know where to read about it? - Pollux
  • @Pollux, well ... It's a long story here. I would do it through MVP now. So it would be necessary to change only the state of the presenter, indicating to him what picture he should show. And the fragment at creation / activation from a presenter would take info. So you would not directly manipulate the fragment and this problem would not arise - YuriySPb ♦