I am creating a radio streaming app for a friend. I decided go down the Exo player route. Everything works fine, apart from if I load a new fragment or turn the screen round. Then I get a new instance of Exo player that starts behind the original. It can get really messy - how can I avoid this?
Here is my code. I open the fragment using:
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
root = inflater.inflate(R.layout.fragment_home, container, false);
initializeUIElements(root);
return root;
}
This is how I call Exo player:
private void initializeUIElements(View root) {
playSeekBar = root.findViewById(R.id.progressBar1);
playSeekBar.setMax(100);
playSeekBar.setVisibility(View.INVISIBLE);
}
#Override
public void onStop() {
super.onStop();
if (Util.SDK_INT >= 24) {
initializeMediaPlayer(root);
}
}
private void initializeMediaPlayer(View root) {
playerView = root.findViewById(R.id.video_view);
player = new SimpleExoPlayer.Builder(getContext()).build();
playerView.setPlayer(player);
MediaItem media = MediaItem.fromUri(revurl);
player.setMediaItem(media);
player.setPlayWhenReady(playWhenReady);
player.seekTo(currentWindow, playbackPosition);
player.prepare();
}
#Override
public void onPause() {
super.onPause();
if (Util.SDK_INT < 24) {
releasePlayer();
}
}
#Override
public void onStart() {
super.onStart();
if (Util.SDK_INT >= 24) {
initializeMediaPlayer(root);
}
}
#Override
public void onResume() {
super.onResume();
if ((Util.SDK_INT < 24 || player == null)) {
initializeMediaPlayer(root);
}
}
#SuppressLint("InlinedApi")
private void hideUi() {
playerView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
}
private boolean playWhenReady = true;
private int currentWindow = 0;
private long playbackPosition = 0;
private void releasePlayer() {
if (player != null) {
playWhenReady = player.getPlayWhenReady();
playbackPosition = player.getCurrentPosition();
currentWindow = player.getCurrentWindowIndex();
player.release();
player = null;
}
}
This is an example of the fragment I'm opening:
public class FacebookFragment extends Fragment {
Context c;
private WebView mwebview;
private String url = "https://www.facebook.com/Revotionofdance";
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.facebook_fragment, container, false);
mwebview = (WebView) root.findViewById(R.id.webview);
mwebview.setWebViewClient(new WebViewClient());
mwebview.addJavascriptInterface(new WebAppInterface(c), "Android");
WebSettings webSettings = mwebview.getSettings();
webSettings.setJavaScriptEnabled(true);
mwebview.loadUrl(url);
return root;
}
public class MyWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if ("https://www.facebook.com/Revotionofdance".equals(Uri.parse(url).getHost())) {
// This is my website, so do not override; let my WebView load the page
return false;
}
// Otherwise, the link is not for a page on my site, so launch another Activity that handles URLs
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
return true;
}
}
public class WebAppInterface {
Context mContext;
/**
* Instantiate the interface and set the context
*/
WebAppInterface(Context c) {
mContext = c;
}
/**
* Show a toast from the web page
*/
#JavascriptInterface
public void showToast(String toast) {
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
}
}
This is my main activity where I call the fragments from:
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.nav_home, R.id.nav_facebook, R.id.nav_insta,R.id.nav_snap,R.id.nav_rodr)
.setDrawerLayout(drawer)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|| super.onSupportNavigateUp();
}
According to your code above currently in your onStop() method you initialise a new instance of SimpleExoPlayer instead of release it. You initialize the player in the onStart() or onResume() methods depending on the API level and release the created player in your onPause() or onStop() methods.
Currently you have:
#Override
public void onStop() {
super.onStop();
if (Util.SDK_INT >= 24) {
initializeMediaPlayer(root);
}
}
Change it to:
#Override
public void onStop() {
super.onStop();
if (Util.SDK_INT >= 24) {
releasePlayer();
}
}
If you have only instance ExoPlayer in whole app. You can using singleton pattern to provide instance ExoPlayer.
If you want only instance Exoplayer in each fragment. I recommend you using ViewModel to init and store ExoPlayer instance because ViewModel isn't reset when you add new fragment or rotate screen.
Related
I have two fragments and one activity (Main Activity). Now when I go from fragment 1 to fragment 2 data in fragment 2 loads from api. But when I press back button, navigates to fragment 1 and again I go from fragment 1 to fragment 2 then the previous loaded data is there for some secs and then fragment loads new data. Why it is so? I want that whenever I go to the fragment 2 it should reload again all the data (without showing the previous data for some secs first). Which method I should use?
Here is my onclick method from fragment 1 for navigating to fragment 2.
private void bind(FragmentUserInputFormBinding binding) {
binding.btnFetchOffer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
isAllFieldChecked = validateAllFields(binding);
if (isAllFieldChecked) {
Bundle bundle = new Bundle();
bundle.putString("appid", binding.etAppId.getText().toString());
bundle.putString("uid", binding.etUserId.getText().toString());
bundle.putString("token", binding.etToken.getText().toString());
OfferWallListFragment offerWallListFragment = new OfferWallListFragment();
offerWallListFragment.setArguments(bundle);
requireActivity().getSupportFragmentManager().beginTransaction()
.replace(((ViewGroup) requireView().getParent()).getId(), offerWallListFragment,"offerListFragment")
.setReorderingAllowed(true)
.addToBackStack("offerListFragment")
.commit();
}
}
});
}
Now I have my second fragment designed as follows fragment 2.
#AndroidEntryPoint
public class OfferWallListFragment extends BaseFragment<FragmentOfferWallListBinding> {
private RecyclerViewAdapter recyclerViewAdapter;
private int currentPage = FIRST_PAGE;
public OfferWallListFragment() {
// Required empty public constructor
}
#Override
public void onViewCreated(#NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Objects.requireNonNull(((AppCompatActivity) requireActivity()).getSupportActionBar()).setTitle("Offers List");
initViewModel(FragmentOfferWallListBinding.bind(view));
}
#NonNull
#Override
protected FragmentOfferWallListBinding initBinding(#NonNull LayoutInflater inflater, #Nullable ViewGroup container) {
return FragmentOfferWallListBinding.inflate(inflater, container, false);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_offer_wall_list, container, false);
}
private void initViewModel(FragmentOfferWallListBinding binding) {
OfferWallViewModel offerWallViewModel = new ViewModelProvider(this).get(OfferWallViewModel.class);
offerWallViewModel.getLiveData(currentPage).observe(getViewLifecycleOwner(), new Observer<OfferResponse>() {
#Override
public void onChanged(OfferResponse offerResponse) {
if (offerResponse != null) {
recyclerViewAdapter = new RecyclerViewAdapter();
recyclerViewAdapter.setOfferResponse(offerResponse);
binding.rvOfferData.setHasFixedSize(true);
binding.rvOfferData.setLayoutManager(new LinearLayoutManager(getContext()));
binding.rvOfferData.setAdapter(recyclerViewAdapter);
binding.rvOfferData.setVisibility(View.VISIBLE);
}
RecyclerViewPaginator recyclerViewPaginator = new RecyclerViewPaginator(binding.rvOfferData) {
#Override
public boolean isLastPage() {
return currentPage == offerResponse.getPages();
}
#Override
public void loadMore(int _currentPage) {
currentPage = _currentPage;
offerWallViewModel.getLiveData(Math.toIntExact(_currentPage));
}
};
binding.rvOfferData.addOnScrollListener(recyclerViewPaginator);
}
});
offerWallViewModel.getNetworkStateMutableLiveData().observe(getViewLifecycleOwner(), new Observer<NetworkState>() {
#Override
public void onChanged(NetworkState networkState) {
if (networkState == NetworkState.Companion.getLOADING()) {
binding.pbLoadingItems.setVisibility(View.VISIBLE);
} else if (networkState == NetworkState.Companion.getERROR()) {
Toast.makeText(getContext(), "Something went wrong, please check the parameters are filled perfectly", Toast.LENGTH_SHORT).show();
if (!CheckInternetConnection.isInternetAvailable(getContext())) {
Toast.makeText(getContext(), "No Internet Connection Available", Toast.LENGTH_SHORT).show();
binding.txtNoConnection.setText("No Internet Connection Available");
binding.txtNoConnection.setVisibility(View.VISIBLE);
}
binding.pbLoadingItems.setVisibility(View.GONE);
} else {
binding.pbLoadingItems.setVisibility(View.GONE);
}
}
});
}
}
Also I have handled onBackPressed method from MainActivity as follows.
#AndroidEntryPoint
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragmentContainerView);
if (navHostFragment != null) {
NavController navController = navHostFragment.getNavController();
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
R.id.userInputFormFragment, R.id.offerWallListFragment
).build();
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
}
}
#Override
public void onBackPressed(){
int count = getSupportFragmentManager().getBackStackEntryCount();
if(count == 0) {
super.onBackPressed();
} else {
getSupportFragmentManager().popBackStack();
}
}
}
Please have a look on it ?
I have 2 activities with a separate NavHostFragment which hosts 3 fragments, these 3 fragments are then displayed in my activity's layout ContainerView.
Note: My 2 activities have the same name and use the same layout, the only difference is that they are in different directories and handle slightly different tasks.
Initially, I planned on using all fragments for the app but now, I decided to use only one for the first release, then work on the others later because it was tasking to handle all at once
So I want to safely remove the bottom navigation view and the other two fragments(second & third fragment).
Already, I have initially tried doing it on my own by deleting those fragments and erasing any code related to it but it came up with a lot of errors, so I decided to bring it here to see if anyone could help with the safest possible way that I could remove them so that my first fragment
can continue to function without any issues.
It is a weather app, so I receive current city updates on the first fragment. I was supposed to receive hourly & daily updates on the second & third fragments but I've halted my plan, for now, I want to use only the first fragment.
Here are the principal codes:
Activity\HomeActivity:
public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
private DrawerLayout drawer;
// Last update time, click sound, search button, search panel.
TextView timeField;
MediaPlayer player;
ImageView Search;
EditText textfield;
// For scheduling background image change(using constraint layout, start counting from dubai, down to statue of liberty.
ConstraintLayout constraintLayout;
public static int count = 0;
int[] drawable = new int[]{R.drawable.nyc, R.drawable.lofoten_islands, R.drawable.parque, R.drawable.moraine_lake, R.drawable.eiffel_tower,
R.drawable.whitehaven_beach, R.drawable.london, R.drawable.cape_town, R.drawable.burj_al_arab,R.drawable.atuh_beach};
Timer _t;
private WeatherDataViewModel viewModel;
private AppBarConfiguration appBarConfiguration;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
// use home activity layout.
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Allow activity to make use of the toolbar
drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
// Hiding default Drawer fragment that has the BottomNavView
navigationView.getMenu().findItem(R.id.main_id).setVisible(false);
viewModel = new ViewModelProvider(this).get(WeatherDataViewModel.class);
// Trigger action to open & close navigation drawer
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar
, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
timeField = findViewById(R.id.textView9);
Search = findViewById(R.id.imageView4);
textfield = findViewById(R.id.textfield);
// find the id's of specific variables.
BottomNavigationView bottomNavigationView = findViewById(R.id.bottomNavigationView);
// host 3 fragments along with bottom navigation.
final NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment);
assert navHostFragment != null;
final NavController navController = navHostFragment.getNavController();
// Make hourly & daily tab unusable
bottomNavigationView.setOnNavigationItemSelectedListener(item -> {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStack();
}
return false;
});
toggle.setToolbarNavigationClickListener(v -> {
// Enable the functionality of opening the side drawer, when the burger icon is clicked
toggle.setDrawerIndicatorEnabled(true);
navController.navigate(R.id.main_id);
});
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
// remove up button from all these fragments
appBarConfiguration = new AppBarConfiguration.Builder(
R.id.main_id) // remove up button from all these fragments >> Keep up button in R.id.nav_setting, R.id.nav_slideshow
.setOpenableLayout(drawer)
.build();
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
// navController.addOnDestinationChangedListener((controller, destination, arguments) -> navController.popBackStack(destination.getId(), false));
// navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
// });
navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
// Hide/show top search bar
if (destination.getId() == R.id.main_id) {
Search.setVisibility(View.VISIBLE);
textfield.setVisibility(View.VISIBLE);
} else {
Search.setVisibility(View.GONE);
textfield.setVisibility(View.GONE);
}
// Fragments that you want to show the back button
if (destination.getId() == R.id.about_id || destination.getId() == R.id.privacy_policy_id) {
// Disable the functionality of opening the side drawer, when the burger icon is clicked
toggle.setDrawerIndicatorEnabled(false);
}
});
// For scheduling background image change
constraintLayout = findViewById(R.id.layout);
constraintLayout.setBackgroundResource(R.drawable.nyc);
_t = new Timer();
_t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// run on ui thread
runOnUiThread(() -> {
if (count < drawable.length) {
constraintLayout.setBackgroundResource(drawable[count]);
count = (count + 1) % drawable.length;
}
});
}
}, 5000, 5000);
Search.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// make click sound when search button is clicked.
player = MediaPlayer.create(HomeActivity.this, R.raw.click);
player.start();
getWeatherData(textfield.getText().toString().trim());
// make use of some fragment's data
Fragment currentFragment = navHostFragment.getChildFragmentManager().getFragments().get(0);
if (currentFragment instanceof FirstFragment) {
FirstFragment firstFragment = (FirstFragment) currentFragment;
firstFragment.getWeatherData(textfield.getText().toString().trim());
} else if (currentFragment instanceof SecondFragment) {
SecondFragment secondFragment = (SecondFragment) currentFragment;
secondFragment.getWeatherData(textfield.getText().toString().trim());
} else if (currentFragment instanceof ThirdFragment) {
ThirdFragment thirdFragment = (ThirdFragment) currentFragment;
thirdFragment.getWeatherData(textfield.getText().toString().trim());
}
}
private void getWeatherData(String name) {
ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
Call<Example> call = apiInterface.getWeatherData(name);
call.enqueue(new Callback<Example>() {
#Override
public void onResponse(#NonNull Call<Example> call, #NonNull Response<Example> response) {
try {
assert response.body() != null;
timeField.setVisibility(View.VISIBLE);
timeField.setText("First Updated:" + " " + response.body().getDt());
} catch (Exception e) {
timeField.setVisibility(View.GONE);
timeField.setText("First Updated: Unknown");
Log.e("TAG", "No City found");
Toast.makeText(HomeActivity.this, "No City found", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(#NotNull Call<Example> call, #NotNull Throwable t) {
t.printStackTrace();
}
});
}
});
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.about_id:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment,
new About()).commit();
break;
case R.id.privacy_policy_id:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment,
new Privacy_Policy()).commit();
break;
}
drawer.closeDrawer(GravityCompat.START);
return true;
}
#Override
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
// Open/close drawer animation
}
}
#Override
protected void onPause () {
super.onPause();
if (viewModel.getMediaPlayer() != null)
viewModel.getMediaPlayer().pause();
}
#Override
protected void onResume () {
super.onResume();
if (viewModel.getMediaPlayer() != null) {
viewModel.getMediaPlayer().start();
viewModel.getMediaPlayer().setLooping(true);
}
}
#Override
public boolean onSupportNavigateUp() {
final NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment);
assert navHostFragment != null;
final NavController navController = navHostFragment.getNavController();
return NavigationUI.navigateUp(navController, appBarConfiguration)
|| super.onSupportNavigateUp(); // navigateUp tries to pop the backstack
}
}
Lightweatherforecast\HomeActivity:
public class HomeActivity extends AppCompatActivity {
private DrawerLayout drawer;
// Last update time, click sound, search button, search panel.
TextView timeField;
MediaPlayer player;
ImageView Search;
ConstraintLayout searchbar;
EditText textfield;
// For scheduling background image change(using constraint layout, start counting from dubai, down to statue of liberty.
ConstraintLayout constraintLayout;
public static int count = 0;
int[] drawable = new int[]{R.drawable.nyc, R.drawable.lofoten_islands, R.drawable.parque, R.drawable.moraine_lake, R.drawable.eiffel_tower,
R.drawable.whitehaven_beach, R.drawable.london, R.drawable.cape_town, R.drawable.burj_al_arab, R.drawable.atuh_beach};
Timer _t;
private WeatherDataViewModel viewModel;
private AppBarConfiguration appBarConfiguration;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
// use home activity layout.
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Allow activity to make use of the toolbar
drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
// host 3 fragments along with bottom navigation.
final NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment);
assert navHostFragment != null;
final NavController navController = navHostFragment.getNavController();
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
// remove up button from all these fragments
appBarConfiguration = new AppBarConfiguration.Builder(
R.id.main_id) // remove up button from all these fragments >> Keep up button in R.id.nav_setting, R.id.nav_slideshow
.setOpenableLayout(drawer)
.build();
// Hiding default Drawer fragment that has the BottomNavView
navigationView.getMenu().findItem(R.id.main_id).setVisible(false);
viewModel = new ViewModelProvider(this).get(WeatherDataViewModel.class);
// Trigger action to open & close navigation drawer
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar
, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
timeField = findViewById(R.id.textView9);
Search = findViewById(R.id.imageView4);
textfield = findViewById(R.id.textfield);
searchbar = findViewById(R.id.searchbar);
// find the id's of specific variables.
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
toggle.setToolbarNavigationClickListener(v -> {
// Enable the functionality of opening the side drawer, when the burger icon is clicked
toggle.setDrawerIndicatorEnabled(true);
navController.navigate(R.id.main_id);
});
navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
// Hide/show top search bar
if (destination.getId() == R.id.main_id) {
searchbar.setVisibility(View.VISIBLE);
toggle.setHomeAsUpIndicator(R.drawable.nav_back_arrow);
toggle.setDrawerIndicatorEnabled(true); // <<< Add this line of code to enable the burger icon
} else {
searchbar.setVisibility(View.GONE);
}
// Fragments that you want to show the back button
if (destination.getId() == R.id.about_id || destination.getId() == R.id.privacy_policy_id) {
// Disable the functionality of opening the side drawer, when the burger icon is clicked
toggle.setDrawerIndicatorEnabled(false);
}
});
// For scheduling background image change
constraintLayout = findViewById(R.id.layout);
constraintLayout.setBackgroundResource(R.drawable.nyc);
_t = new Timer();
_t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// run on ui thread
runOnUiThread(() -> {
if (count < drawable.length) {
constraintLayout.setBackgroundResource(drawable[count]);
count = (count + 1) % drawable.length;
}
});
}
}, 5000, 5000);
Search.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// make click sound when search button is clicked.
player = MediaPlayer.create(HomeActivity.this, R.raw.click);
player.start();
getWeatherData(textfield.getText().toString().trim());
// make use of some fragment's data
Fragment currentFragment = navHostFragment.getChildFragmentManager().getFragments().get(0);
if (currentFragment instanceof MainFragment) {
((MainFragment) currentFragment).getWeatherData(textfield.getText().toString().trim());
}
}
private void getWeatherData(String name) {
ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
Call<Example> call = apiInterface.getWeatherData(name);
call.enqueue(new Callback<Example>() {
#Override
public void onResponse(#NonNull Call<Example> call, #NonNull Response<Example> response) {
try {
assert response.body() != null;
} catch (Exception e) {
Log.e("TAG", "No City found");
Toast.makeText(HomeActivity.this, "No City found", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(#NotNull Call<Example> call, #NotNull Throwable t) {
t.printStackTrace();
}
});
}
});
}
#Override
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
// Open/close drawer animation
}
}
#Override
protected void onPause() {
super.onPause();
if (viewModel.getMediaPlayer() != null)
viewModel.getMediaPlayer().pause();
}
#Override
protected void onResume() {
super.onResume();
if (viewModel.getMediaPlayer() != null) {
viewModel.getMediaPlayer().start();
viewModel.getMediaPlayer().setLooping(true);
}
}
#Override
public boolean onSupportNavigateUp() {
final NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment);
assert navHostFragment != null;
final NavController navController = navHostFragment.getNavController();
// return NavigationUI.navigateUp(navController,drawer);
return NavigationUI.navigateUp(navController, appBarConfiguration)
|| super.onSupportNavigateUp(); // navigateUp tries to pop the backstack
}
}
MainFragment(The Navhost fragment):
public class MainFragment extends Fragment {
private NavHostFragment navHostFragment;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
//
BottomNavigationView bottomNavigationView = rootView.findViewById(R.id.bottomNavigationView);
navHostFragment = (NavHostFragment) getChildFragmentManager().findFragmentById(R.id.nav_host_fragment_content_bottom_nav_view);
if (navHostFragment != null) {
NavController navController = navHostFragment.getNavController();
NavigationUI.setupWithNavController(bottomNavigationView, navController);
}
requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) {
#Override
public void handleOnBackPressed() {
// Exit the app when back is pressed
requireActivity().finish();
}
});
return rootView;
}
public void getWeatherData(String name) {
Fragment currentFragment = navHostFragment.getChildFragmentManager().getFragments().get(0);
if (currentFragment instanceof FirstFragment) {
FirstFragment firstFragment = (FirstFragment) currentFragment;
firstFragment.getWeatherData(name);
} else if (currentFragment instanceof SecondFragment) {
SecondFragment secondFragment = (SecondFragment) currentFragment;
secondFragment.getWeatherData(name);
} else if (currentFragment instanceof ThirdFragment) {
ThirdFragment thirdFragment = (ThirdFragment) currentFragment;
thirdFragment.getWeatherData(name);
}
}
}
Others include:
*FirstFragment
*SecondFragment
*ThirdFragment with their respective layouts
*Navigation and menu layouts.
I will not post them, for now, to reduce complexity if needed please don't
hesitate to ask.
So, the current navigation in summary would be:
HomeActivity
MainFragment
BottomNavigationView navGraph
FirstFragment
SecondFragment
ThirdFragment
Other fragments...
And you need to:
Safely remove the BottomNavigationView
Keep only FirstFragment and Get rid of SecondFragment & ThirdFragment
As the MainFragment only hosts the BottomNavigationView; then you can replace it directly with the FirstFragment; so the navigation would be:
HomeActivity
FirstFragment
Other fragments...
And to do that:
1. In the main navGraph of the HomeActivity:
Replace the MainFragment with FirstFragment (copy the FirstFragment section from the BottomNavigationView navGraph to the main navGraph.
Refactor the id of the FirstFragment to the one associated with the MainFragment, because this id is utilized in HomeActivity (or you can do the other way by refactoring it to the FirstFragment)
2. In HomeActivity, Replace the MainFragment in below snippet with the FirstFragment:
if (currentFragment instanceof MainFragment) {
((MainFragment) currentFragment).getWeatherData(textfield.getText().toString().trim());
}
So, it'll be:
if (currentFragment instanceof FirstFragment) {
((FirstFragment) currentFragment).getWeatherData(textfield.getText().toString().trim());
}
This is what appears in the shared code; but you'd replace every single occurrence of MainFragment with FirstFragment, and do any needed refactoring.
Now, you can safely remove the MainFragment will all of its descendants, BottomNavigationView, second & third fragments; and their resources (layouts, menus...), or keep them aside if you're planning to reuse them in the future.
Are you try this for bottom navigation?
android:visibility="gone"
I do the samething before.
navController.addOnDestinationChangedListener { _, destination, _ ->
if(destination.id == R.id.first_fragment) {
// your intro fragment will hide your bottomNavigationView
bottomNavigationView.visibility = View.GONE
} else if (destination.id == R.id.second_fragment){
// your second fragment will show your bottomNavigationView
bottomNavigationView.visibility = View.VISIBLE
}
}
You can hide and show according to the relevant destination.
i have Activity MainActivity and use some Fragment.
i try the code in google developer and put the code ad in onAttach and onCreate but Interstitial ad show after the the fragment loaded
i worked in the past for ad with activity it's very easy , but it's first time to use ad in fragment class and i search in google search and youtube and no't found any thing help me. so I decided to ask the experts here. I wish you a good day.
public class MainActivity extends AppCompatActivity {
NavController navController ;
NavHostFragment navHostFragment;
AdView adView;
FrameLayout adContainerView;
public static InterstitialAd mInterstitialAd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView bottomNavigationView = findViewById(R.id.bottomNavigationView);
navHostFragment = (NavHostFragment) getSupportFragmentManager()
.findFragmentById(R.id.nav_host_fragment);
if (navHostFragment != null) {
navController = navHostFragment.getNavController();
}
NavigationUI.setupWithNavController(bottomNavigationView, navController);
}
The Fragment i want to show ad befor loding and onBackPressed Fragment before back to MainActivity
public class Report_Fragment extends Fragment {
View view;
NavController navController;
DatabaseAccess dp;
int bundle_mor, bundle_even;
int dp_count_mor, dp_count_even;
int total_az;
boolean statusAnimation = false;
Handler handlerAnimation = new Handler(Looper.getMainLooper());
ImageView imgAnimation1, imgAnimation2;
Button button;
public static InterstitialAd mInterstitialAd;
private static final String TAG = "##Report_Fragment##";
public Report_Fragment() {
// Required empty public constructor
}
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
//////*******////
//Ads
//Interstitial
MobileAds.initialize(getActivity(), initializationStatus -> {});
AdRequest adRequest = new AdRequest.Builder().build();
InterstitialAd.load(getActivity(),(getResources().getString(R.string.Interstitial_id_Forward)),
adRequest,
new InterstitialAdLoadCallback() {
#Override
public void onAdLoaded(#NonNull InterstitialAd interstitialAd) {
// The mInterstitialAd reference will be null until
// an ad is loaded.
mInterstitialAd = interstitialAd;
Log.i(TAG, "onAdLoaded");
}
#Override
public void onAdFailedToLoad(#NonNull LoadAdError loadAdError) {
// Handle the error
Log.i(TAG, loadAdError.getMessage());
mInterstitialAd = null;
}
});
///////////////**************////////////////
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
showAds();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.report_fragment, container, false);
TextView tv_az_count = view.findViewById(R.id.count_athkar);
TextView tv_total_dp = view.findViewById(R.id.count_total);
button = view.findViewById(R.id.button_text);
imgAnimation1 = view.findViewById(R.id.imgAnimation1);
imgAnimation2 = view.findViewById(R.id.imgAnimation2);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (getActivity() != null)
showAds();
getActivity().onBackPressed();
}
});
dp = DatabaseAccess.getInstance(getActivity());
dp.open();
Bundle bundle = getArguments();
if (bundle != null) {
bundle_mor = bundle.getInt("bundle_morning");
bundle_even = bundle.getInt("bundle_evening");
}
if (bundle_mor > 0) {
tv_az_count.setText(String.valueOf(bundle_mor));
dp_count_mor = dp.getCount_mor();
total_az = bundle_mor + dp_count_mor;
dp.update_n(new Items(1, total_az));
dp.close();
tv_total_dp.setText(String.valueOf(total_az));
} else if (bundle_even > 0) {
tv_az_count.setText(String.valueOf(bundle_even));
dp_count_even = dp.getCount_ev();
total_az = bundle_even + dp_count_even;
dp.update_even(new Items(1, total_az));
dp.close();
tv_total_dp.setText(String.valueOf(total_az));
}
return view;
}
#Override
public void onDestroy() {
if (getActivity() != null) {
BottomNavigationView bottomNavigationView = getActivity().findViewById(R.id.bottomNavigationView);
bottomNavigationView.setVisibility(View.VISIBLE);
Toast.makeText(getContext(), "Destroy_Fragment", Toast.LENGTH_SHORT).show();
}
super.onDestroy();
}
private void showAds() {
if (mInterstitialAd != null) {
mInterstitialAd.show(getActivity());
} else {
Log.d("TAG", "The interstitial ad wasn't ready yet.");
}
}
}
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 2 years ago.
I am getting the following error in my logcat
2020-03-21 16:58:54.611 20322-20322/com.example.bookitup E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.bookitup, PID: 20322
java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.recyclerview.widget.RecyclerView.setLayoutManager(androidx.recyclerview.widget.RecyclerView$LayoutManager)' on a null object reference
at com.example.bookitup.RecyclerView_Config.setConfig(RecyclerView_Config.java:22)
at com.example.bookitup.MainActivity$2.DataIsLoaded(MainActivity.java:90)
at com.example.bookitup.BookDatabaseEdit$1.onDataChange(BookDatabaseEdit.java:40)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database##19.2.1:75)
at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database##19.2.1:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database##19.2.1:55)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
2020-03-21 16:58:54.622 2004-2019/? W/ActivityTaskManager: Force finishing activity com.example.bookitup/.MainActivity
2020-03-21 16:58:54.622 2004-20389/? I/DropBoxManagerService: add tag=data_app_crash isTagEnabled=true flags=0x2
And here is my code that is causing this NPE of RecyclerView_Config.
public class RecyclerView_Config {
private Context mContext;
private BooksAdapter mBooksAdapter;
public void setConfig(RecyclerView recyclerView, Context context, List<BookActivity> books, List<String> keys){
mContext = context;
mBooksAdapter = new BooksAdapter(books,keys);
recyclerView.setLayoutManager(new LinearLayoutManager(context));/*here!!!!!!!!!!!!!!!!!!!!!!!!!*/
recyclerView.setAdapter(mBooksAdapter);
}
class BookItemView extends RecyclerView.ViewHolder {
private TextView mTitle;
private TextView mAuthor;
private TextView mISBN;
private TextView mCategory;
private String key;
public BookItemView(ViewGroup parent){
super(LayoutInflater.from(mContext).inflate(R.layout.book_list_item,parent,false));
mTitle = (TextView) itemView.findViewById(R.id.title_txtView);
mAuthor = (TextView) itemView.findViewById(R.id.author_txtView);
mCategory = (TextView) itemView.findViewById(R.id.category_txtView);
mISBN = (TextView) itemView.findViewById(R.id.isbn_txtView);
}
public void bind(BookActivity book, String key){
mTitle.setText(book.getXbook());
mAuthor.setText(book.getXauthor());
mCategory.setText(book.getXdescription());
mISBN.setText(book.getXisbn());
this.key = key;
}
}
class BooksAdapter extends RecyclerView.Adapter<BookItemView>{
private List<BookActivity> mBookList;
private List<String> mKeys;
public BooksAdapter(List<BookActivity> mBookList, List<String> mKeys) {
this.mBookList = mBookList;
this.mKeys = mKeys;
}
#NonNull
#Override
public BookItemView onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new BookItemView((parent));
}
#Override
public void onBindViewHolder(#NonNull BookItemView holder, int position) {
holder.bind(mBookList.get(position), mKeys.get(position));
}
#Override
public int getItemCount() {
return mBookList.size();
}
}
}
Here is the code from my activity
public class MainActivity extends AppCompatActivity {
private AppBarConfiguration mAppBarConfiguration;
private RecyclerView mRecyclerView;
//private ProgressBar progressBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.AppTheme_NoActionBar);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FirebaseUser user= FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
//setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.fab);
Toast.makeText(getApplicationContext(), "on the main page", Toast.LENGTH_LONG).show();
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Snackbar.make(view, "Adding new book, please wait!", Snackbar.LENGTH_LONG).setAction("Action", null).show();
Toast.makeText(getApplicationContext(), "Adding new book, please wait ", Toast.LENGTH_LONG).show();
//progressBar.setVisibility(View.GONE);
Intent intent = new Intent(MainActivity.this, AddBookActivity.class);
startActivity(intent);
}
});
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow,
R.id.nav_tools, R.id.nav_share, R.id.nav_send, R.id.nav_profile_edit)
.setDrawerLayout(drawer)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
//piling all books on the main page
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview_books);
new BookDatabaseEdit().readBooks(new BookDatabaseEdit.DataStatus() {
#Override
public void DataIsLoaded(List<BookActivity> books, List<String> keys) {
new RecyclerView_Config().setConfig(mRecyclerView,MainActivity.this,books,keys);
}
#Override
public void DataIsInserted() {
}
#Override
public void DataIsUpdated() {
}
#Override
public void DataIsDeleted() {
}
});
}
else {
Intent intent = new Intent(MainActivity.this, RegistrationActivity.class);
startActivity(intent);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
// User chose the "Settings" item, show the app settings UI...
return true;
case R.id.action_logout:
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
FirebaseAuth.getInstance().signOut();
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(new Intent(intent));
return true;
default:
// If we got here, the user's action was not recognized.
// Invoke the superclass to handle it.
return super.onOptionsItemSelected(item);
}
}
#Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|| super.onSupportNavigateUp();
}
}
My BookDatabaseEdit.java
public class BookDatabaseEdit {
private FirebaseDatabase mDatabase;
private DatabaseReference mReferenceBooks;
private List<BookActivity> books = new ArrayList<>();
public interface DataStatus{
void DataIsLoaded(List<BookActivity> books, List<String> keys);
void DataIsInserted();
void DataIsUpdated();
void DataIsDeleted();
}
public BookDatabaseEdit() {
mDatabase = FirebaseDatabase.getInstance();
mReferenceBooks = mDatabase.getReference("Booklist");
}
public void readBooks(final DataStatus dataStatus){
mReferenceBooks.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange( DataSnapshot dataSnapshot) {
books.clear();
List<String> keys = new ArrayList<>();
for(DataSnapshot keyNode : dataSnapshot.getChildren()){
keys.add(keyNode.getKey());
BookActivity book = keyNode.getValue(BookActivity.class);
books.add(book);
}
dataStatus.DataIsLoaded(books,keys);
System.out.println(keys);
System.out.println(books);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
I think you should implement a getter and setter for Context and use getter to get context with a null check.
So, I fixed this error and my code is working now. The problem was with the RecyclerView_Config.java . The problem was that, basically, my program was trying to populate data from firebase into the app before creating the app.
It is fixed, thanks everyone.
I have been investigating for like 4 hours about this problem, but I didnt get any help.
On summary, I am trying to navigate between fragments in Android Studio, using Navigation View. I want to go from Home Fragment to Services Fragment.
The first Home Fragment always load, but when I click on Services item, the fragment Services load, but the data from Home always keeps on the fragment too.
This is my code:
HOME FRAGMENT CLASS
public class HomeFragment extends Fragment {
private HomeViewModel homeViewModel;
private PieChart pieChart;
private UserService userService;
private Calendar calendar;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
homeViewModel = ViewModelProviders.of(this).get(HomeViewModel.class);
View root = inflater.inflate(R.layout.fragment_home, container, false);
pieChart = root.findViewById(R.id.pieChart);
userService = UserRepository.getUserService();
getData();
return root;
}
private void getData(){
calendar = Calendar.getInstance();
int month = calendar.get(Calendar.MONTH)+1;
Log.i("INT MONTH", String.valueOf(month));
userService.getHoursPerService(String.valueOf(UserCache.empleado.getId_emp()),String.valueOf(month)).enqueue(new Callback<List<Servicio>>() {
#Override
public void onResponse(Call<List<Servicio>> call, Response<List<Servicio>> response) {
if(response.body().size() == 0){
pieChart.setNoDataText("Sin horas actuales.");
pieChart.setNoDataTextColor(ContextCompat.getColor(getContext(), R.color.colorPrimaryDark));
pieChart.invalidate();
}else{
List<Servicio> list = response.body();
List<PieEntry> pieEntries = new ArrayList<>();
for(int cont=0;cont<list.size();cont++){
pieEntries.add(new PieEntry(list.get(cont).getTotalHoras(), list.get(cont).getLugarServicio()));
}
SimpleDateFormat sdf = new SimpleDateFormat("MMMM");
String actual_month = sdf.format(calendar.getTime());
PieDataSet dataSet = new PieDataSet(pieEntries, getResources().getString(R.string.txt_hours_of)+" "+actual_month);
dataSet.setSliceSpace(3f);
dataSet.setSelectionShift(5f);
dataSet.setColors(ColorTemplate.MATERIAL_COLORS);
PieData data = new PieData(dataSet);
data.setValueTextSize(10f);
data.setValueTextColor(ContextCompat.getColor(getContext(), R.color.colorPrimaryDark));
pieChart.getDescription().setEnabled(true);
pieChart.getDescription().setText(getResources().getString(R.string.txt_hours_of)+" "+actual_month+".");
pieChart.getDescription().setTextSize(12f);
pieChart.getDescription().setTextColor(ContextCompat.getColor(getContext(), R.color.colorPrimaryDark));
pieChart.setExtraOffsets(5, 10, 5, 5);
pieChart.setDragDecelerationFrictionCoef(0.99f);
pieChart.setDrawHoleEnabled(true);
pieChart.setHoleColor(Color.WHITE);
pieChart.setTransparentCircleRadius(61f);
pieChart.animateY(2000, Easing.EaseInOutCubic);
pieChart.setEntryLabelColor(ContextCompat.getColor(getContext(),R.color.colorPrimaryDark));
pieChart.setData(data);
pieChart.invalidate();
}
}
#Override
public void onFailure(Call<List<Servicio>> call, Throwable t) {
}
});
}
}
SERVICES FRAGMENT CLASS
public class ServicesFragment extends Fragment {
private ServicesViewModel servicesViewModel;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
servicesViewModel = ViewModelProviders.of(this).get(ServicesViewModel.class);
View root = inflater.inflate(R.layout.fragment_myservices, container, false);
final TextView textView = root.findViewById(R.id.text_gallery);
servicesViewModel.getText().observe(this, new Observer<String>() {
#Override
public void onChanged(#Nullable String s) {
textView.setText(s);
}
});
return root;
}
}
MAIN ACTIVITY
public class MainActivityView extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
private AppBarConfiguration mAppBarConfiguration;
private NavigationView navigationView;
private ActionBarDrawerToggle toggle;
private TextView userNameNav;
private TextView userEmailNav;
private DrawerLayout drawer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_view);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
/*FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});*/
drawer = findViewById(R.id.drawer_layout);
navigationView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.nav_home, R.id.nav_myservices, R.id.nav_startservice)
.setDrawerLayout(drawer)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
View headerView = navigationView.getHeaderView(0);
navigationView.setNavigationItemSelectedListener(this);
userNameNav = headerView.findViewById(R.id.userNameNav);
userEmailNav = headerView.findViewById(R.id.userEmailNav);
userNameNav.setText(UserCache.empleado.getNombre()+" "+UserCache.empleado.getApellidos());
userEmailNav.setText(UserCache.empleado.getEmail());
navigationView.bringToFront();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main_activity_view, menu);
return true;
}
#Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|| super.onSupportNavigateUp();
}
#Override
public void onBackPressed() {
if(drawer.isDrawerOpen(GravityCompat.START)){
drawer.closeDrawer(GravityCompat.START);
}else{
AlertDialog.Builder alerta = new AlertDialog.Builder(this);
alerta.setTitle(getResources().getString(R.string.txt_dialog_exit_app));
alerta.setPositiveButton(getResources().getString(R.string.txt_yes_option), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
finish();
}
});
alerta.setNegativeButton(getResources().getString(R.string.txt_no_option), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
alerta.show();
}
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
switch (menuItem.getItemId()){
case R.id.nav_home:
getSupportFragmentManager().popBackStack(null,FragmentManager.POP_BACK_STACK_INCLUSIVE);
getSupportFragmentManager().beginTransaction().replace(R.id.nav_host_fragment,new HomeFragment()).commit();
case R.id.nav_myservices:
getSupportFragmentManager().popBackStack(null,FragmentManager.POP_BACK_STACK_INCLUSIVE);
getSupportFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, new ServicesFragment()).commit();
//NavHostFragment.findNavController(new ServicesFragment());
break;
case R.id.nav_startservice:
getSupportFragmentManager().popBackStack(null,FragmentManager.POP_BACK_STACK_INCLUSIVE);
getSupportFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, new StartServiceFragment()).commit();
break;
}
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
onNavigationItemSelected is where I do the navigation.
I tried everything, changing the ConstraintLayout to Relative, insert the fragments from xml into framelayout...
Also, I am using MVVM.
If more information is needed i can post here then.
PD: Sorry if I posting something wrong, this is my first time here.
SOLUTION: I forgot completly to break the first case onNavigationItemSelected.