Navigation Drawer Back Stack doesn't work - android

I have an app developed like the following image:
So a fragment A with a menu. Clicking on the menu it will open a fragment B.
My problem is that, when I click on the back button, nothing happens, so I can not return from fragment B to fragment A, and I don't understand why.
This is my code:
Main Activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final DrawerLayout drawer = findViewById(R.id.drawer_layout);
final ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open,
R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
drawer.openDrawer(Gravity.LEFT);
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
FragmentA fragmentA = new FragmentA();
FragmentManager manager = getSupportFragmentManager();
manager.beginTransaction().replace(R.id.relativelayout_for_fragment, fragmentA, fragmentA.getTag()).commit();
getSupportActionBar().setTitle(getResources().getString(R.string.title));
getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
if(getSupportFragmentManager().getBackStackEntryCount() == 0){
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
toggle.setDrawerIndicatorEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
getSupportActionBar().setHomeButtonEnabled(false);
}else{
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
toggle.setDrawerIndicatorEnabled(false);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
}
});
}
#Override
public void onBackPressed() {
DrawerLayout drawer = findViewById(R.id.drawer_layout);
int count = getSupportFragmentManager().getBackStackEntryCount();
if (count == 0) {
drawer.openDrawer(GravityCompat.START);
} else {
getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
}
Fragment A (on click on the menu)
Fragment fragmentB = new FragmentB();
FragmentTransaction transaction = activity.getFragmentManager().beginTransaction();
transaction.replace(R.id.relativelayout_for_fragment, fragmentB);
transaction.addToBackStack(null);
transaction.commit();
Fragment B
#Override
public void onCreateOptionsMenu(#NonNull Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.share_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
getFragmentManager().popBackStack();
return true;
case R.id.menu_item_share:
String contenuto = "*" + titolo + "*" + "\n" + desc;
String textToShare = getResources().getString(R.string.Linc);
Intent intent = new Intent("android.intent.action.SEND");
intent.setType("text/plain");
intent.putExtra("android.intent.extra.TEXT", contenuto + "\n\n" + textToShare);
startActivity(Intent.createChooser(intent,
getResources().getString(R.string.sharing)));
return true;
}
return super.onOptionsItemSelected(item);
}

did you try this onBackPressed
override fun onBackPressed() {
val manager: FragmentManager = supportFragmentManager
if(manager.backStackEntryCount > 0){
manager.popBackStack()
}else{
super.onBackPressed()
}
}

In MainActivity
After
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Put
getSupportFragmentManager().popBackStack()

Related

How to go back from an activity to fragment

Hey I'm new in android development and i'm trying to develop an app with navigation drawer. So i created fragments with navigation drawer menus, and from one of those fragments I have given an intent to a new activity. But i dont know how to go back from that activity to previous fragment.
MainActivity.java
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
displaySelectedScreen(R.id.nav_bus);
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private void displaySelectedScreen(int itemId) {
Fragment fragment = null;
switch (itemId) {
case R.id.nav_bus:
fragment = new BusFragment();
break;
case R.id.nav_hotel:
fragment = new HotelFragment();
break;
}
if (fragment != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
displaySelectedScreen(item.getItemId());
return true;
}
}
From this fragment i have given intent to city.java activity
HotelFragment.java
public class HotelFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView= inflater.inflate(R.layout.fragment_hotel, container, false);
Button button = (Button) rootView.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
updateDetail();
} });
return rootView;
}
public void updateDetail() {
Intent intent = new Intent(getActivity(), City.class);
startActivity(intent);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getActivity().setTitle("Hotel");
}
}
City.java
public class City extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_city_list);
} }
In manifest file i have added this
<activity android:name=".City_List"
android:parentActivityName = "MainActivity"
>
<meta-data
android:name = "android.support.PARENT_ACTIVITY"
android:value = "MainActivity" />
</activity>
</application>
to be able to go back to the previous fragment should include the .addToBackStack()
if (fragment != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.addToBackstack(null)
ft.commit();
}
and when you click on back button in the toolbar programmatically go back to the previous fragment using following code.
if ( getFragmentManager().getBackStackEntryCount() > 0)
{
getFragmentManager().popBackStack();
return;
}
super.onBackPressed();
Add this line inside back pressed method
if(getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack();
}
else {
super.onBackPressed();
}

Navigation Drawer back button in fragments

I started creating of app which use one activity (Navigation Drawer) and many fragments.
But I unable to use toolbar back button to navigate back from fragments. Hardware back button works perfectly. I know that I need to override onOptionsItemSelected, catch android.R.id.home, check if there are something in back stack and than pop it. After changing fragment, "burger" button changes to "back arrow", but when I click on it onOptionsItemSelected never fired, just opens the NavigationDrawer menu.
Here the code from activity:
public class NavDrawerActivity extends AppCompatActivity implements ... {
NavigationView navigationView;
BottomNavigationView bottomNavigationView;
ActionBarDrawerToggle toggle;
FragmentManager fragmentManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nav_drawer);
fragmentManager = getSupportFragmentManager();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
// Set back button
fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
if (fragmentManager.getBackStackEntryCount() > 0) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
} else {
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
toggle.syncState();
}
}
});
// Load default fragment
changeFragment(new HomeFragment(), false);
navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
View headerLayout = navigationView.getHeaderView(0);
bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(this);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Toast.makeText(this, "Back pressed", Toast.LENGTH_SHORT)
.show();
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START))
drawer.closeDrawer(GravityCompat.START);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else if (fragmentManager.getBackStackEntryCount() > 0) {
fragmentManager.popBackStack();
} else {
super.onBackPressed();
}
}
private void changeFragment(Fragment fm, boolean addToBackStack)
{
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.id.frame_layout_content, fm);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
if (addToBackStack) ft.addToBackStack(null);
ft.commit();
}
}
And how I change (replace) fragments from HomeFragment:
IndexDetailFragment newFragment = new IndexDetailFragment();
Bundle args = new Bundle();
args.putString(IndexDetailFragment.ARG_INDEX_ID, id);
newFragment.setArguments(args);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left);
transaction.replace(R.id.frame_layout_content, newFragment);
transaction.addToBackStack(null);
transaction.commit();
setNavigationOnClick() on the toolbar after setSupportActionBar(toolbar) :
setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
Toast.makeText(getActivity(), "Back clicked!",
Toast.LENGTH_SHORT).show();
}
});
I have made a small app for reference
FirstFragment
public class FirstFragment extends Fragment {
public FirstFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_first, container, false);
}
}
SecondFragment
public class SecondFragment extends Fragment {
public SecondFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_second, container, false);
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
private Toolbar mToolbar;
private ActionBarDrawerToggle drawerToggle;
private DrawerLayout mDrawerLayout;
private String TAG = "MainActivity";
private FragmentManager mFragmentManager;
private NavigationView mNavigationView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
if (mToolbar != null) {
setSupportActionBar(mToolbar);
}
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);
drawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.drawer_open, R.string.drawer_close) {
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
}
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
}
};
mDrawerLayout.addDrawerListener(drawerToggle);
mNavigationView = findViewById(R.id.navigation);
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.first:
changeFragment(new FirstFragment(), true);
return true;
case R.id.second:
changeFragment(new SecondFragment(), true);
return true;
}
return false;
}
});
mFragmentManager = getSupportFragmentManager();
changeFragment(new FirstFragment(), true);
}
#Override
protected void onPostCreate(#Nullable Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
if (drawerToggle != null) {
drawerToggle.syncState();
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
Log.i(TAG, "onOptionsItemSelected: Home Button Clicked");
if (mDrawerLayout.isDrawerOpen(Gravity.START)) {
mDrawerLayout.closeDrawer(Gravity.START);
} else {
mDrawerLayout.openDrawer(Gravity.START);
}
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
if (mDrawerLayout.isDrawerOpen(Gravity.START)) {
mDrawerLayout.closeDrawer(Gravity.START);
}
if (mDrawerLayout.isDrawerOpen(Gravity.START)) {
mDrawerLayout.closeDrawer(Gravity.START);
} else if (mFragmentManager.getBackStackEntryCount() > 0) {
mFragmentManager.popBackStack();
} else {
super.onBackPressed();
}
}
private void changeFragment(Fragment fragment, boolean needToAddBackstack) {
FragmentTransaction mFragmentTransaction = mFragmentManager.beginTransaction();
mFragmentTransaction.replace(R.id.FRAME_CONTENT, fragment);
mFragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
if (needToAddBackstack)
mFragmentTransaction.addToBackStack(null);
mFragmentTransaction.commit();
}
}
activity_main
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
        
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="#dimen/abc_action_bar_default_height_material"
android:background="#color/colorPrimaryDark"
/>
<FrameLayout
android:id="#+id/FRAME_CONTENT"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="#dimen/abc_action_bar_default_height_material" />
</FrameLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:layout_marginTop="#dimen/abc_action_bar_default_height_material"
app:menu="#menu/drawermenu" />
</android.support.v4.widget.DrawerLayout>
I had the same issue.
I finally solved by adding this in the onCreate method.
getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
if(getSupportFragmentManager().getBackStackEntryCount() == 0){
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
menuToggle.setDrawerIndicatorEnabled(true);
}else{
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
menuToggle.setDrawerIndicatorEnabled(false);
}
}
});
Hope it helps
Simplest solution for Kotlin Developers
Just add this in your root activity where fragments resist
if (supportFragmentManager.backStackEntryCount > 0) {
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
toolbar.setNavigationOnClickListener {
if (supportFragmentManager.backStackEntryCount > 0) {
super.onBackPressed()
} else {
supportActionBar!!.setDisplayHomeAsUpEnabled(false)
drawerLayout.addDrawerListener(toggle)
toggle.syncState()
drawerLayout.openDrawer(GravityCompat.START)
}
}
} else {
supportActionBar!!.setDisplayHomeAsUpEnabled(false)
drawerLayout.addDrawerListener(toggle)
toggle.syncState()
}
Here, whenever setDisplayHomeAsUpEnabled is set true , I am showing back button. and on cliking it, I am calling super.onBackPressed() which is similar to what your back button does!
Add below code in onCreate() method
that's work for me
getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, " Back Pressed ", Toast.LENGTH_SHORT).show();
}
});
} else {
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
drawerToggle = new ActionBarDrawerToggle(MainActivity.this, drawerLayout, toolbar,
R.string.app_name, R.string.app_name);
drawerLayout.addDrawerListener(drawerToggle);
drawerToggle.syncState();
}
}
});
The thing that solved me the issue was this:
I used the code that came automatically with the NavigationDrawerActivity template, and it was something like this:
NavigationView navigationView = _binding.navView;
// Passing each menu ID as a set of Ids because each menu should be considered as top level destinations:
_AppBarConfiguration = new AppBarConfiguration.Builder(R.id.nav_x, R.id.nav_y, R.id.nav_z)
.setOpenableLayout(_binding.drawerLayout)
.build();
_navController = Navigation.findNavController(this, R.id.nav_host_content_main);
NavigationUI.setupActionBarWithNavController(this, _navController, _AppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, _navController);
And I struggled a lot with many tricks and hacks, and nothing was working for me.
At some point, I have noticed that the fragments that I want to enable the back button are "being considered as top level destinations", exactly what the comment says in the code above. Then I removed those sub-fragments and BOOM that was it, with not a single hack or line of code needed, this is provided out of the box, I just needed to pay attention to it.
So in my case, I changed to the below code:
NavigationView navigationView = _binding.navView;
// Passing each menu ID as a set of Ids because each menu should be considered as top level destinations:
_AppBarConfiguration = new AppBarConfiguration.Builder(R.id.nav_x)
.setOpenableLayout(_binding.drawerLayout)
.build();
_navController = Navigation.findNavController(this, R.id.nav_host_content_main);
NavigationUI.setupActionBarWithNavController(this, _navController, _AppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, _navController);
: Just removed R.id.nav_y, R.id.nav_z in the AppBarConfiguration
I struggled with this for a while. I got it to work by:
setting my the drawer layout in MainActivity.kt:
val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
findViewById<NavigationView>(R.id.nav_view).setupWithNavController(navController)
appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)
Include the toolbar layout in each of the fragments that I need the Toolbar:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
/>
</com.google.android.material.appbar.AppBarLayout>
</LinearLayout>
Add the following code to the home fragment of the drawer, the one from which other fragments are called using the drawer. This gets the hamburguer icon to work, onside the onViewCreated method:
var myToolbar = requireActivity()
.findViewById<androidx.appcompat.widget.Toolbar>(R.id.toolbar)
myToolbar.inflateMenu(R.menu.menu)
val drawerLayout = requireActivity().findViewById<DrawerLayout>(R.id.drawer_layout)
val toggle = ActionBarDrawerToggle(
activity, drawerLayout, myToolbar,
R.string.navigation_drawer_open, R.string.navigation_drawer_close
)
toggle.setDrawerIndicatorEnabled(true)
drawerLayout.addDrawerListener(toggle)
toggle.syncState()
Add the following code in the kotlin code for the fragments that are after the home fragment, this will get the back arrow:
val navController = findNavController()
val appBarConfiguration = AppBarConfiguration(navController.graph)
view.findViewById<Toolbar>(R.id.toolbar)
.setupWithNavController(navController, appBarConfiguration)
In the destination fragment add the following code in onCreateView Method:
activity?.onBackPressedDispatcher?.addCallback(
viewLifecycleOwner, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
findNavController().navigate(
[back fragment directions] )
}
})
Hope this helps everyone struggling with this :)

Navigation Drawer open close pane not working with smoothness

This is my gif of problem. I am using navigation drawer, and I have done some code as per below but the pane close and open is not working with require smoothness.
This is my code:
public class SettingFlyout extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
SharedPreferences pref;
SharedPreferences.Editor editor;
public DrawerLayout drawer;
public ActionBarDrawerToggle toggle;
public NavigationView navigationView;
LinearLayout viewPager;
int roleId;
FragmentStack fragmentStack = FragmentStack.getInstance();
#Override
public void onPanelClosed(int featureId, Menu menu) {
super.onPanelClosed(featureId, menu);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setting_flyout);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
TextView credits, num_credits, ttlscore, num_ttlscore, tutorNow;
final Typeface typeface = Typeface.createFromAsset(getAssets(), "fonts/GothamBookRegular.ttf");
View v = getLayoutInflater().inflate(R.layout.student_actionbar_view, null);
credits = (TextView) v.findViewById(R.id.credits);
credits.setTypeface(typeface);
viewPager = (LinearLayout) findViewById(R.id.viewpager);
Intent i = getIntent();
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
int status = i.getIntExtra("status", 1);
String username = i.getStringExtra("username");
navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
navigationView.setItemIconTintList(null);
View view = navigationView.getHeaderView(0);
TextView TVuserName = (TextView) view.findViewById(R.id.personTextsettingflyout);
TVuserName.setText(username);
if (status == 0) {
roleId = Integer.parseInt(i.getStringExtra("roleId"));
}
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
Tablayout_with_viewpager withViewpager = new Tablayout_with_viewpager(status, roleId);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.addToBackStack(null);
fragmentTransaction.replace(R.id.viewpager, withViewpager);
fragmentTransaction.commit();
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
FragmentManager fragmentManager = getSupportFragmentManager();
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else
if (fragmentStack.size()==0) {
super.onBackPressed();
finish();
moveTaskToBack(true);
} else if (fragmentStack.size()>0) {
if (fragmentStack.size()<2 || fragmentStack.size()==2 || fragmentStack.isEmpty()){
super.onBackPressed();
finish();
moveTaskToBack(true);
SplashScreen splashScreen=new SplashScreen();
splashScreen.onBackPressed();
} else {
Fragment fragment = fragmentStack.pop();
if (fragment.getClass().equals(""))
Toast.makeText(getApplicationContext(), fragment.getClass().toString(), Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), String.valueOf(fragmentStack.size()), Toast.LENGTH_SHORT).show();
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.id.viewpager, fragment).commit();
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment fragment;
if (id == R.id.profile) {
Tablayout_with_viewpager tablayout_with_viewpager = new Tablayout_with_viewpager();
fragmentTransaction.replace(R.id.viewpager, tablayout_with_viewpager).commit();
// Handle the camera action
} else if (id == R.id.desired_tutor) {
DesiredTutor desiredTutor = new DesiredTutor();
fragmentTransaction.replace(R.id.viewpager, desiredTutor).commit();
} else if (id == R.id.payment_options) {
BuyCredits buyCredits=new BuyCredits();
fragmentTransaction.replace(R.id.viewpager, buyCredits).commit();
} else if (id == R.id.lesson_tracking) {
lessonTracking lessonTracking=new lessonTracking();
fragmentTransaction.replace(R.id.viewpager, lessonTracking).commit();
} else if (id == R.id.TTL_Score) {
TTL_Score ttl_score = new TTL_Score();
fragmentTransaction.replace(R.id.viewpager, ttl_score).commit();
} else if (id == R.id.History) {
History history = new History();
fragmentTransaction.replace(R.id.viewpager, history).commit();
} else if (id == R.id.notification) {
Notification notification = new Notification();
fragmentTransaction.replace(R.id.viewpager, notification).commit();
} else if (id == R.id.support) {
Support support = new Support();
fragmentTransaction.replace(R.id.viewpager, support).commit();
} else if (id == R.id.sign_out) {
pref=getSharedPreferences("loginStatus", Context.MODE_PRIVATE);
editor=pref.edit();
editor.clear();
editor.apply();
Intent i = new Intent(getApplicationContext(), Login.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
finish();
}
else if (id== R.id.daily_game){
TutorGuides dailyGame= new TutorGuides();
fragmentTransaction.replace(R.id.viewpager, dailyGame).commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
what should I do to make it smoother?
Every time used this code it not need to use this code every time define in once a time:-
fragmentTransaction.replace(R.id.viewpager, desiredTutor).commit();
Create a method:-
public static void showFragment(Fragment fragment, String Tag) {
FragmentManager manager = activity.getSupportFragmentManager();
FragmentTransaction transcation = manager.beginTransaction();
transcation.replace(R.id.viewpager, fragment, Tag);
transcation.addToBackStack(Tag);
transcation.commit();
}
and use this :-
switch (item.getItemId())
{
case R.id.desired_tutor:
showFragment(new DesiredTutor(), "");
break;
case R.id.payment_options:
showFragment(new BuyCredits(), "");
break;
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
You are initiating it everytime. Its wrong. Just initialize it once and use that object to open and close the drawer. remove that code from item selected listener and put it in to Oncreate to initialize it once.
Use below code to make it perfect :
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
toggle.syncState();
}
ActionBarDrawerToggle toggle;
toggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) {
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
invalidateOptionsMenu();
}
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
invalidateOptionsMenu();
}
};
mDrawerLayout.setDrawerListener(toggle);

How to implement onBackPress from fragment in navigation drawer to MainActivity

I want to implement onBackPress to my fragment but i don't know how. When i go to another fragment (in this case, my fragment is the one from my ActivityHome and i'm using standard NavigationDrawer from android stuudio).
Here is my code for ActivityHome
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
FragmentHome fragment = new FragmentHome();
fragmentTransaction.add(R.id.containerID, fragment);
fragmentTransaction.commit();
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_home, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_logout) {
Toast.makeText(getApplicationContext(),
"Akun anda telah dikeluarkan!", Toast.LENGTH_LONG).show();
Intent logout = new Intent(ActivityHome.this, ActivityMain.class);
startActivity(logout);
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
if(id == R.id.nav_home){
ActivityHome.this.getSupportFragmentManager().beginTransaction().replace(R.id.containerID, FragmentHome.newInstance()).commit();
}else if (id == R.id.nav_profile){
ActivityHome.this.getSupportFragmentManager().beginTransaction().replace(R.id.containerID, Profile.newInstance()).commit();
}
else if (id == R.id.nav_history){
ActivityHome.this.getSupportFragmentManager().beginTransaction().replace(R.id.containerID, History.newInstance()).commit();
}
else if (id == R.id.nav_about_us){
ActivityHome.this.getSupportFragmentManager().beginTransaction().replace(R.id.containerID, AboutUs.newInstance()).commit();
}
else if (id == R.id.nav_ganti_kata_sandi){
ActivityHome.this.getSupportFragmentManager().beginTransaction().replace(R.id.containerID, GantiKataSandi.newInstance()).commit();
}
else if (id == R.id.nav_share){
ActivityHome.this.getSupportFragmentManager().beginTransaction().replace(R.id.containerID, Share.newInstance()).commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
I hope u guys can help me with my problem.
I have webview in fragment, I used this code to detect backpress code in mainactivity OnbackPressed():
Fragment webview = getSupportFragmentManager().findFragmentByTag("BLOG");
if (webview instanceof BlogFragment) {
boolean goback = ((BlogFragment) webview).canGoBack();
if (!goback) {
} else {
((BlogFragment) webview).goBack();
}
}
Make sure you start fragment like:
getSupportFragmentManager()
.beginTransaction()
.addToBackStack(null)
.replace(R.id.frame_content, new BlogFragment(), "BLOG")
.commit();
To open fragment from activity.
Fragment fragment = Fragment.newInstance();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.fragment_slide_left_enter,
R.anim.fragment_slide_left_exit, R.anim.fragment_slide_right_enter,
R.anim.fragment_slide_right_exit);
addFragmentToActivity(fragmentTransaction, Fragment, R.id
.content_frame);
public void addFragmentToActivity(#NonNull FragmentTransaction transaction,
#NonNull Fragment fragment, int frameId) {
transaction.addToBackStack(fragment.getClass().getName());
transaction.add(frameId, fragment, fragment.getClass().getName());
transaction.commit();
}
That's how I add fragment from HomeActivity and For back Call override method OnBackPressed in HomeActivity.
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
getSupportFragmentManager().popBackStackImmediate();
}
You can get event when back button pressed from any fragment in Activity's onBackPressed() method.
Suppose you've pressed back from HomeFragment then you can get onBackPressed in Activity like following :
#Override
public void onBackPressed() {
HomeFragment fragment = (Fragment)findFragmentById(// fragment id);
if(fragment!=null && fragment.isVisible()){
// Here you can code for Home Fragment's onBackPress()
}
super.onBackPressed();
}

Android DrawerLayout does not close untill fragment is replaced

I got a problem that DrawerLayout does not close smoothly and it stops in the middle for a while, it totally closes after finish replacing fragment. In coding I close DrawerLayout before replacing fragment (productList class). In productList class, it calls asynctask to get all the product list from server meanwhile running progress bar. Ideally when user clicks menu, DrawerLayout will close at once and productList fragment will be loading all the product list. It seems to me DrawerLayout close event waits for productList's asynctask. Any suggestion greatly appreciated.
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, View.OnClickListener {
public String tag = "MainActivity";
Context mContext;
//User Object
User user;
//Control
TextView txtName, txtPosition, txtLogout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
user = Constants.getUser();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
//NavigationView Header
View headerView = navigationView.getHeaderView(0);
txtName = (TextView) headerView.findViewById(R.id.nav_header_main_name) ;
txtName.setText(user.getName().toString());
txtLogout = (TextView) headerView.findViewById(R.id.nav_header_main_logout);
txtLogout.setOnClickListener(this);
navigationView.setNavigationItemSelectedListener(this);
//Add Menu in navigationView
Menu myMenu = navigationView.getMenu();
myMenu.clear();
myMenu.add(0,Integer.parseInt("01"),0,"Product List");
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#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) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
//close drawer
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
// replace fragment
int id = item.getItemId();
FragmentManager fragmentManager = getSupportFragmentManager();
if(Constants.DEBUG) {
Toast.makeText(mContext, " Menu Id " + String.valueOf(id), Toast.LENGTH_LONG).show();
}
fragmentManager.beginTransaction()
.replace(R.id.container,new productList())
.commit();
return true;
}
#Override
public void onClick(View v) {
//Log out onclick
if(v.getId() == R.id.nav_header_main_logout){
this.finish();
}
}
}
This probably happens beacuse the Navigation Drawer's animation and the creation of the Fragment happens at the same time.
You can solve it by starting your Fragment with a small delay-
handler.postDelayed(new Runnable() {
#Override
public void run() {
// replace fragment
int id = item.getItemId();
FragmentManager fragmentManager = getSupportFragmentManager();
if(Constants.DEBUG) {
Toast.makeText(mContext, " Menu Id " + String.valueOf(id), Toast.LENGTH_LONG).show();
}
fragmentManager.beginTransaction()
.replace(R.id.container,new productList())
.commit();
}
}, 300);

Categories

Resources