Switch between Fragments with onNavigationItemSelected in new Navigation Drawer Activity template (Android Studio 1.4 onward)
So, based on @L.L.'s answer I was able to solve this problem.
First of all, add your FrameLayout to your content_main.xml
file:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent" android:id="@+id/content_frame"/>
In your MainActivity
(or whatever you have named the Activity with the navigation drawer) define a method named displayView
public void displayView(int viewId) {
Fragment fragment = null;
String title = getString(R.string.app_name);
switch (viewId) {
case R.id.nav_news:
fragment = new NewsFragment();
title = "News";
break;
case R.id.nav_events:
fragment = new EventsFragment();
title = "Events";
break;
}
if (fragment != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.commit();
}
// set the toolbar title
if (getSupportActionBar() != null) {
getSupportActionBar().setTitle(title);
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
}
Am switching between 3 custom Fragments; NewsFragment, EventsFragment and GalleryFragment.
in my menu activity_main_drawer
I have changed the content to this:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item android:id="@+id/nav_news"
android:icon="@android:drawable/ic_menu_news"
android:title="News" />
<item android:id="@+id/nav_events"
android:icon="@android:drawable/ic_menu_events"
android:title="Events" />
<item android:id="@+id/nav_gallery"
android:icon="@android:drawable/ic_menu_gallery"
android:title="Gallery" />
</group>
</menu>
Going back to the Activity class, in your onNavigationItemSelected
method
do this:
@Override
public boolean onNavigationItemSelected(MenuItem item) {
displayView(item.getItemId());
return true;
}
Finally, the last statement in your onCreate method:
@Override
protected void onCreate(Bundle savedInstanceState) {
....
....
displayView(R.id.nav_news);
}
This is because I want the first view my user sees to be News.Change it to whatever you choose.
Handle back press event:
As it stands, if you press the back button from any of the Fragments, the app exits.I want my app to go back to the News Fragment (my home fragment) when the user presses the back button. So I did this:
Declared a boolean variable:
private boolean viewIsAtHome;
then in the displayView()
method I did this:
public void displayView(int viewId){
Fragment fragment = null;
String title = getString(R.string.app_name);
switch (viewId) {
case R.id.nav_news:
fragment = new NewsFragment();
title = getString(R.string.news_title);
viewIsAtHome = true;
break;
case R.id.nav_events:
fragment = new EventsFragment();
title = getString(R.string.events_title);
viewIsAtHome = false;
break;
case R.id.nav_gallery:
fragment = new GalleryFragment();
title = getString(R.string.gallery_title);
viewIsAtHome = false;
break;
Finally, delete your old onBackPressed
method and create a new one like this outside the onCreate()
method:
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
}
if (!viewIsAtHome) { //if the current view is not the News fragment
displayView(R.id.nav_news); //display the News fragment
} else {
moveTaskToBack(true); //If view is in News fragment, exit application
}
}
Works for me.
Switching Fragments in navigation drawer using onNavigationItemSelected()
By your logcat, error is:
com.internetwarz.sploon.MainActivity@3caae0bc must implement OnFragmentInteractionListener
I think the error happened because your parent activity (MainActivity.java) did not implement this method: OnFragmentInteractionListener
You can see by the comments:
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
So, the solution would be:
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener,
FacebookFragment.OnFragmentInteractionListener {
....
// Add the method below to MainActivity.java
private void onFragmentInteraction(Uri uri) {
// Do something or just return
Toast.makeText(this, "Success", Toast.LENGTH_SHORT).show();
}
}
How to switch between fragments in android like drawer menu without FrameLayout?
If you are using the Navigation Component as the template does, you should navigate to a destination by calling navigate()
- this is precisely what the NavigationUI.setupWithNavController()
is doing for you when you tap on an item in the NavigationView
via NavigationUI.onNavDestinationSelected()
.
You do not use a FragmentTransaction
at all when using the Navigation Component.
onNavigationItemSelected() function not present in MainActivity of Navigation Drawer Activity
MainActivity needs to implement NavigationView.OnNavigationItemSelectedListener
in order to override its functions:
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
...
@Override
public boolean onNavigationItemSelected(MenuItem item){
int id = item.getItemId();
// any code
}
...
}
How to open Activity from Android's built-in navigation drawer
navigationView.setNavigationItemSelectedListener(this)
I did not see this line of code in your code. Apparently you didn’t set a listener
Navigation drawer with Activity and child Fragments
I solved this issue by simply overriding the up carat behavior by calling the mDrawerToggle.setDrawerIndicatorEnabled(enable)
and passing the boolean enable
or disable
as needed.
(The fragments where I didn't want the drawer to show called this method with false and where I wanted the drawer to be shown called this method with true. I put the call inside the onResume()
of the respective fragment for obvious reasons.)
This works exactly like I want, and I did not have to change the design of my project :).
Related Topics
App Crash After Activity Has Been Killed in Background
Google Cloud Messaging (Gcm) with Local Device Groups on Android Gives Http Error Code 401
Making Sense of Android Meta-Viewport Scaling: What Am I Missing
Android Studio on a Hardware That Does Not Support Virtualization Technology
How to Encode Bitmaps into a Video Using Mediacodec
How to Create a Release Android Library Package (Aar) in Android Studio (Not Debug)
When Does Adt Set Buildconfig.Debug to False
How to Check If User Is Logged in with Fb Sdk 4.0 for Android
Kotiln: Pass Data from Adapter to Activity
Failed to Execute Tools\Android.Bat: Solution
Android Emulator Failed to Allocate Memory 8
Android: How to Implement First Time Tutorial Like Go Launcher in My App
Add Maven Repository to Build.Gradle
JSONarray Cannot Be Converted to JSONobject Error
Mediaplayer Stop Playing After About 5 Seconds
How to Create a Service Which Continuously Monitors App Usage Information
How to Remove Child Nodes in Firebase Android
I'M Getting a Nullpointerexception When I Use Action_Image_Capture to Take a Picture