I have extended my newActivity to mainActivity fine and I got the navigation drawer working, but now it sort of forms a loop as it again picks up the click of newActivity in navigation drawer and opens up a new intent again,so basically I am opening intent inside intent inside intent, I want to move between items in drawer and not open a new intent for every click, what am I doing wrong?
My navigation Drawer(below) Listening for click event and opens a activity called main acitvity
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_camera) {
startActivity(new Intent(Main2Activity.this, MainActivity.class));
} else if (id == R.id.nav_gallery) {
} else if (id == R.id.nav_slideshow) {
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
Now as this drawer will also come with main activity as I have extended it from the activity with drawer, I get the option of clicking on the mainactivity option in new intent again, so this sort of gives me ability to open mainActivity any number of times, i dont want this
You should use fragments. Activity holds your main view and your activity drawer seperately. When you click some item in drawer, just replace your fragment on main container.
Check this : https://developer.android.com/training/implementing-navigation/nav-drawer.html#ListItemClicks
Edit
public void replaceFragment(Fragment fragment) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.mainContainer, fragment);
ft.commit();
}
put this method into your activity. And create a FrameLayout in your Main Layout.
<android.support.v4.widget.DrawerLayout...
<FrameLayout
android:id="#+id/mainContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Now you can set a fragment in onCreate() for the first screen using replaceFragment(Blala.newInstance()). When you click and item on Drawer just call replaceFragment(...) again.
Related
Hey guys new to all this and can't seem to figure a way to change the Navigation Title with my navigation drawer selection. Made a stock standard navigation drawer with android studio.
I feel it's really simple but hope someone will give me an answer.
i watch a youtube 2014 by Derek Banas and all he added in his fragment class was
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((MainActivity) activity).onSectionAttached(2);
}
but that doesnt seem to work anymore. is there something similair for Studio 3.0.1?
If you go to Android Studio, create New Project with the Navigation Drawer template, in MainActivity, you'll find the method onNavigationItemSelected. In that method, you can easily change activity title depending on your navigation option selection -
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_camera) {
// Handle the camera action
setTitle("Camera");
} else if (id == R.id.nav_gallery) {
setTitle("Gallery");
} else if (id == R.id.nav_slideshow) {
setTitle("Slideshow");
} else if (id == R.id.nav_manage) {
setTitle("Manage");
} else if (id == R.id.nav_share) {
setTitle("Share");
} else if (id == R.id.nav_send) {
setTitle("Send");
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
What function should i use to open an activity when a DrawerLayout navigationView item is clicked, and do i need to make object for that activity?
Here is my code so far:
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_profile) {
// Handle the camera action
} else if (id == R.id.nav_cv) {
} else if (id == R.id.nav_subscription) {
} else if (id == R.id.nav_logout) {
}
You can open activity like this.
Intent I=new Intent(MainActivity.this,actvitytoopen.class);
StartActivity(I);
You better use fragments instead of activities and change them using FragmentManager. You can find plenty of tutorials just by searching on Google/Youtube.
You can start new activity by
Intent intent = new Intent(this,NextActivity.class);
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
for further info refer https://developer.android.com/training/basics/firstapp/starting-activity.html
I spent a lot of time trying to call a new activity by clicking on navigation drawer item . but it is virtually impossible and if it is possible in any other way I tried, then it is sure that on the called activity there will be no drawer navigation drawer then. Fragment is a part of similar activity so calling fragment is the correct way. If you are calling fragment, navigation drawer will still be there on the side pane and you would be able to select between different items of the drawer.
Im working with an android app which have 3 fragments and the activity_main, all of them are listed in a navigation drawer. The question is how can i return to the activity main by clicking in a item of the navigation drawer.
The basic idea of waht I need is to close all the fragments open to return to the activity main
This is my code.
if(id==R.id.taximetro){
//this is my activity_main that i need to return
trans = true;
} else if (id == R.id.factura) {
fragment=new frmFactura();
getSupportFragmentManager().beginTransaction().replace(R.id.content_main, fragment).addToBackStack(null).commit();
trans = true;
} else if (id == R.id.dispBlue) {
fragment=new frmDispositivos();
getSupportFragmentManager().beginTransaction().replace(R.id.content_main, fragment).addToBackStack(null).commit();
trans = true;
} else if (id == R.id.ayuda) {
fragment=new frmAyuda();
getSupportFragmentManager().beginTransaction().replace(R.id.content_main, fragment).addToBackStack(null).commit();
trans = true;
}
if (trans) {
getSupportFragmentManager().beginTransaction().replace(R.id.content_main, fragment).commit();
item.setCheckable(true);
getSupportActionBar().setTitle(item.getTitle());
}
//getSupportFragmentManager().beginTransaction().replace(R.id.content_main, fragment).addToBackStack(null).commit();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
Simple like you call fragments ..call your MainActivity
if you want check whats available on the view,
keep an ENUM value or other related way ..and change the value related the the view that you loaded ,and check a fragment is loaded or still the main view exists in your MainActivity using that ENUM value in your MainActivity call
so,
if a fragment view is loaded recall your MainActivity
else just slide the navigation because you are already in the view of MainActivity without any fragment loaded on it
if(id==R.id.taximetro){
// call your activity again if you want you can check that a fragment view is loaded or not and do changes only when you need if there is a fragment view loaded.. or simply recall it
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
}
How to prevent opening a fragment from navigation drawer if that fragment is already opened, when the fragment is opened and click in the NavigationDrawer item the fragment reCreates again, So how to check if the fragment is already opened?
public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (id == R.id.fragmentA) {
{ FragmentA fragment = new FragmentA();
transaction.add(R.id.main_screen, fragment1, "MainFrag").addToBackStack(null);
}
} else if (id == R.id.fragmentB) {
FragmentB fragment = new FragmentB();
transaction.add(R.id.main_screen, fragment).addToBackStack(null);
} else if (id == R.id.fragmentC) {
FragmentC fragment = new FragmentC();
transaction.replace(R.id.main_screen, fragment).addToBackStack(null);
}
I solved it in this way:
public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
Fragment f = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
if (id == R.id.n_1 && !(f instanceof MainFragment)) {
MainFragment fragment = new MainFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
} }
for example I am in the fragment B, And when I click in fragment B
again from the NavigationDrawer it recreates, so how to check if the
fragment is already shown in the screen or not?
If you have reference to Fragment B from the NavigationDrawer, you can call mFragmentB.isAdded() to know whether it's already shown or not.
While adding fragment use tags to replace it.
transaction.replace(R.id.main_screen, fragment, tag);
Now, when menu items are clicked use fragment manager to get the visible fragment using tag :
public boolean isFragmentCurrentlyVisible(String fragmentTag){
Fragment fragmentToTest;
fragmentToTest = fragmentManager.findFragmentByTag(fragmentTag);
if(fragmentToTest!=null && fragmentToTest.isVisible())
return true;
return false;
}
Depending on value returned by above method you can add the fragment if not already added.
I have also struggled with this for a while, I am using navigation components and Kotlin, so finally I got it sorted out. It might not be the best solution, but it's simple and works, so I wanted to share it with you:
when (menuItem.itemId) {
R.id.nav_board -> {
if(findNavController(R.id.nav_host_fragment).currentDestination?.label != "listFragment")
findNavController(R.id.nav_host_fragment)
.navigate(R.id.action_global_listFragment)
}
The label is the destination label given in the navigation.xml
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/navigation"
app:startDestination="#id/listFragment">
<fragment
android:id="#+id/listFragment"
android:name="at.example.app.ui.ListFragment"
android:label="listFragment"
tools:layout="#layout/fragment_list">
...
So this basically just checks if the current destination (where we're at) is the one that should not be re-opened and only navigates if the current destination is a different one.
I'm trying to develop an application using the Navigation drawer template of Android Studio. So, I created a new project using this template. But when I run the program and click on a menu item, the view doesn't change. I searched everywhere on internet, but I didn't see how I can handle this.
This is the code provided by Android Studio:
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_camara) {
} else if (id == R.id.nav_gallery) {
} else if (id == R.id.nav_slideshow) {
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
What I want to achieve is to replace the current view with the appropriate view for the menu item clicked.
Is Fragment the best way to do this or should I create a different activity for each menu item?
In your case adding fragment will be the best solution.
create a fragment BlankFragment.java
public class BlankFragment extends Fragment {
public BlankFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_blank, container, false);
}
}
and create fragment_black.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.above_inc.shyam.drawer.BlankFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment" />
</FrameLayout>
now replace your method
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
Fragment fragment = null;
if (id == R.id.nav_camera) {
// Handle the camera action
fragment = new BlankFragment();
} else if (id == R.id.nav_gallery) {
} else if (id == R.id.nav_slideshow) {
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment).commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
add below code in your content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.above_inc.shyam.drawer.MainActivity"
tools:showIn="#layout/app_bar_main">
<FrameLayout
android:id="#+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
you can also add more fragment to other options same as camera in above code
Fragment will be the best way if you want your navigation drawer to be shown on the next screen when you click on the menu item.
If you will use activity then navigation drawer will not be shown unless you make a BaseActivity which extends Navigation Drawer and use everywhere. In this case you have to change acitivty transition animation too as new activity will pop up after clicking on the menu which may look odd.
Right click on your project -> New -> Fragment.
Edit the switch case accordingly.
#Passiondroid's answer on using Fragments only if you want Navigation drawer across all activities is spot on.
About starting an activity on click of the menu item, in one of my apps, I follow this,
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
switch(id)
{
case R.id.nav_profile:
selection = 1;
intent = new Intent("android.intent.action.WEB");
intent.putExtra("selection",selection);
startActivity(intent);
break;
case R.id.nav_books:
intent = new Intent("android.intent.action.WEBD");
selection = 2;
intent.putExtra("selection",selection);
startActivity(intent);
break;
case R.id.fav_quotes:
intent = new Intent ("android.intent.action.SHOWFAVTES");
selection = 3;
intent.putExtra("selection",selection);
startActivity(intent);
break;
default:
break;
}
To change and configure the Menu Item, you can find the "activity_main_drawer.xml" under res->Menu.
And on click of each of the menu items, you can start an activity as per your wish. You have declare the activities in your AndroidManifest.xml file before you use it.
Beginning from android studio > 3.5 you will realize when you create navigation drawer activity it generates fragments opens when drawer items are clicked.
you can a listener if you want to open an activity.
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_accounts)
.setDrawerLayout(drawer)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
#Override
public void onDestinationChanged(#NonNull NavController controller, #NonNull NavDestination destination, #Nullable Bundle arguments) {
int menuId = destination.getId();
switch (menuId){
case R.id.nav_gallery:
Toast.makeText(MainActivity.this,"You tapped gallery",Toast.LENGTH_LONG).show();
fab.hide();
break;
default:
fab.show();
break;
}
}
});
for full tutorial. Navigation Drawer