I am using Bottom Navigation Activity from Android Studio
After setting all the needed bottom tabs, I need to add aditional button for one fragment, but outside the tab zone. And that button is only when the second fragment is called.
Something like in image below
I've set new fragment in navigation/mobile_navigation.xml
<fragment
android:id="#+id/navigation_demografski"
android:name="com.home.Fragment1"
android:label="Podaci o osobama"
tools:layout="#layout/fragment_home" />
<fragment
android:id="#+id/navigation_biometrijski"
android:name="com.home.Fragment2"
android:label="Biometrijski podaci - Desna Ruka"
tools:layout="#layout/fragment_dashboard" />
<fragment
android:id="#+id/navigation_biometrijski2"
android:name="com.home.Fragment3"
android:label="Biometrijski podaci - Lijeva Ruka"
tools:layout="#layout/fragment_dashboard2" />
But I don't know how to call the third fragment from the second fragment.
I tried to use fragmet.replace() but it just overlaps one fragment over the other.
Tabbed activity
public class TabbedActivity extends AppCompatActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabbed);
BottomNavigationView navView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
R.id.navigation_demografski, R.id.navigation_biometrijski).build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
NavigationUI.setupWithNavController(navView, navController);
}
}
Use FrameLayout as fragment container, then switch fragments inside it. You could do that by setting OnNavigationItemSelectedListener to BottomNavigationView and using
getSupportFragmentManager().beginTransaction().replace(R.id.frameLayout, selectedFragment).commit();
to switch between the fragments. On mentioned button in second fragment add onClickListener and call previous transaction from Activity with desired fragment as selectedFragment
you can implement by following my code below:
public class MainActivity extends AppCompatActivity implements BottomNavigationView.OnNavigationItemSelectedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//loading the default fragment
loadFragment(new HomeFragment());
//getting bottom navigation view and attaching the listener
BottomNavigationView navigation = findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(this);
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment fragment = null;
switch (item.getItemId()) {
case R.id.navigation_home:
fragment = new HomeFragment();
break;
case R.id.navigation_dashboard:
fragment = new DashboardFragment();
break;
case R.id.navigation_notifications:
fragment = new NotificationsFragment();
break;
case R.id.navigation_profile:
fragment = new ProfileFragment();
break;
}
return loadFragment(fragment);
}
private boolean loadFragment(Fragment fragment) {
//switching fragment
if (fragment != null) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, fragment)
.commit();
return true;
}
return false;
}
}
Related
I add to my app Bottom Navigation Bar it's work but the problem now I want move from one button in Bottom Navigation Bar to activity that activity have to fragment to view (TabLayout,ViewPager).
When I try to make it like that selectedFragment = new MainActivityOderLIstFargmant(); the show me error like that ..
and also like that and also not work.. startActivity(new Intent(NafMain.this, MainActivityOderLIstFargmant.class));
I need to move to other activity to show two (TabLayout,ViewPager).
this activity I want to move to it ..
public class MainActivityOderLIstFargmant extends AppCompatActivity {
TabLayout tabLayout;
ViewPager viewPager;
PageAdapterOrderList pageAdapterOrderList;
TabItem tabChats;
TabItem tabCalls;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mani_order_list);
tabLayout = findViewById(R.id.tablayout);
tabChats = findViewById(R.id.tabChats);
tabCalls = findViewById(R.id.tabCalls);
viewPager = findViewById(R.id.viewPager);
pageAdapterOrderList = new PageAdapterOrderList(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(pageAdapterOrderList);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
}
}
from here
public class NafMaintest extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_naf_main);
BottomNavigationView bottomNav = findViewById(R.id.bottom_navigation);
BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
Fragment selectedFragment = null;
switch (menuItem.getItemId()) {
case R.id.nav_home:
selectedFragment = new MainActivityOderLIstFargmant();//I try like that but not work
break;
case R.id.nav_favorites:
selectedFragment = new FragmentHome();
break;
case R.id.nav_search:
selectedFragment = new FragmentProfile();
break;
case R.id.nav_s:
selectedFragment = new MainActivity();
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
selectedFragment).commit();
return true;
}
});
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new FragmentHome()).commit();
}
}
}
If anyone know how solution it help me
you are trying to instantiate MainActivityOderLIstFargmant activity in the switch case R.id.nav_home and put it into a Fragment variable which is called selectedFragment, so both types are different (Fragment & Activity). That is why the screenshot you provided says Incompatible types.
To get your code works you can change the switch case as below
case R.id.nav_home:
Intent intent = new Intent(NafMaintest.this, MainActivityOderLIstFargmant.class);
startActivity(intent);
return true; // use return to avoid triggering the fragment transaction after the `swtich` block
There's a NavigationView that opens a fragment, in that fragment there's a BottomNavigationView. The bottom navigation view, should switch between two fragments.
Note: When the app starts, it opens the first blank fragment (called Home), so when I click on the second menu item it opens another fragment (that contains the bottom navigation).
I tried to switch from one fragment to the other using FragmentTransaction in this way:
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
fragmentManager.popBackStack();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
final Fragment fragment;
if (item.getItemId() == R.id.menu_alert) {
fragment = new IPAlertFragment();
} else {
fragment = new IPStatsFragment();
}
fragmentTransaction.replace(R.id.nav_host_fragment, fragment).commit();
return false;
}
};
BottomNavigationView navigation = (BottomNavigationView) getActivity().findViewById(R.id.bottom_navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
}
It works fine when I open the fragment from the navigation menu for the first time, but when I click a second time on the navigation menu, the BottomNavigationView.onNavigationItemSelectedListener doesn't fire anymore and I can't switch from a fragment to the other.
So, I've tried to accomplish my goal using NavController, like the following:
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
final NavController navController = NavHostFragment.findNavController(NavFragment.this);
if (item.getItemId() == R.id.menu_alert) {
navController.navigate(R.id.action_openAlert);
} else {
navController.navigate(R.id.action_openStats);
}
return false;
}
};
BottomNavigationView navigation = (BottomNavigationView) getActivity().findViewById(R.id.bottom_navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
}
But when I navigate to the other fragment the left menu bar change the icon to "back arrow", it's a kind of new activity, and I have to use the back button (or the menu back icon) in order to show the previous tab.
I would like to navigate to a destination fragment overriding the current "screen", as like as the side menu does.
Here is the mobile_navigation.xml:
<fragment
android:id="#+id/nav_ip_alert"
android:name="IPAlertFragment"
android:label="#string/menu_ip"
tools:layout="#layout/fragment_i_p_alert">
<action
android:id="#+id/action_openStats"
app:destination="#id/nav_ip_stats"
app:launchSingleTop="false" />
</fragment>
<fragment
android:id="#+id/nav_ip_stats"
android:name="IPStatsFragment"
android:label="#string/menu_ip"
tools:layout="#layout/stats_tabs">
<action
android:id="#+id/action_openAlert"
app:destination="#id/nav_ip_alert"
app:launchSingleTop="false" />
</fragment>
I don't know what's wrong (espacially with the first solution) any idea?
Thanks.
Finally I solved my problem:
It works fine when I open the fragment from the navigation menu for the first time, but when I click a second time on the navigation menu, the BottomNavigationView.onNavigationItemSelectedListener doesn't fire anymore and I can't switch from a fragment to the other.
The problem was caused by the navigation menu, the listener wasn't called because I used in my activity:
NavigationUI.setupWithNavController(navigationView, navController);
That overrides my OnNavigationItemSelectedListener, so I removed that line and I've setted my listener as the following:
final NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(new
NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
FragmentManager fm = getSupportFragmentManager();
fm.popBackStackImmediate();
boolean handled = NavigationUI.onNavDestinationSelected(item, navController);
if (handled) {
ViewParent parent = navigationView.getParent();
if (parent instanceof DrawerLayout) {
((DrawerLayout) parent).closeDrawer(navigationView);
}
}
return handled;
}
});
Here's a piece of NavigationUI that override my listener:
public static void setupWithNavController(#NonNull final NavigationView navigationView,
#NonNull final NavController navController) {
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
boolean handled = onNavDestinationSelected(item, navController);
//******* CUTTED ***************
return handled;
}
});
}
So, replacing the setupWithNavController, I can navigate through the tabs correctly.
I have 3 fragments, Home, Menu and orders they can be loaded by bottomnavigtioview items and the title shown by it as well
once navigate from Home to Orders then if you want to go back to Home From Orders the title still "Orders"
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment fragment;
switch (item.getItemId()) {
case R.id.navigation_home:
toolbar.setTitle(getResources().getString(R.string.title_home));
fragment = new HomeFragment();
loadFragment(fragment);
return true;
case R.id.navigation_menu:
toolbar.setTitle(getResources().getString(R.string.fragment_title_menu));
fragment = new ProductFragment();
loadFragment(fragment);
return true;
case R.id.navigation_orders:
toolbar.setTitle(getResources().getString(R.string.title_orders));
fragment = new OrdersFragment();
loadFragment(fragment);
return true;
}
return false;
}
};
private void loadFragment(Fragment fragment) {
// load fragment
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_container, fragment);
transaction.addToBackStack(null);
transaction.commit();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
navigation = findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
// attaching bottom sheet behaviour - hide / show on scroll
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) navigation.getLayoutParams();
layoutParams.setBehavior(new BottomNavigationBehavior());
toolbar.setTitle(getResources().getString(R.string.title_home));
Fragment f = HomeFragment.newInstance();
getSupportFragmentManager().beginTransaction()
.replace(R.id.frame_container, f)
.commit();
}`
I have Also Tried this but its not working
`
fragmentmanger.addOnBackStackChangedListener -> public void onBackStackChanged() {
}`
Instead of calling toolbar.setTitle in your onNavigationItemSelected method, move it to onCreateView of each fragment. When you navigate back to a Fragment, onCreateView is executed again.
It worked for me when calling it in onResume like this in each fragment:
if(getActivity()!=null) {
((MainActivity)getActivity()).setActionBarTitle
(context.getResources().getString(R.string.YOUR_TITLE));
this is the function setActionBarTitle in MainActivity
public void setActionBarTitle(String title) {
toolbar.setTitle(title);
}
I have the following bottom navbar code to switch between 3 fragments:
public class MainActivity extends AppCompatActivity {
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment fragment = null;
switch (item.getItemId()) {
case R.id.navigation_home:
fragment = new HomeFragment();
break;
case R.id.navigation_dashboard:
fragment = new DashboardFragment();
break;
case R.id.navigation_notifications:
fragment = new NotificationsFragment();
break;
}
return loadFragment(fragment);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadFragment(new HomeFragment());
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
}
private boolean loadFragment(Fragment fragment) {
//switching fragment
if (fragment != null) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, fragment)
.commit();
return true;
}
return false;
}
}
In the fragments there are RecyclerViews with lists. Every time I switch between the tabs (between fragments), it looks like the fragment is reloaded, and the lists jump to the top. I want to prevent that reloading so that the user stays on the same place in the list he viewed before switching fragments
The problem is that you are creating a new instance every time. You can cache the instance like:
private Fragment mHomeFragment = new HomeFragment();
private Fragment mDashboardFragment = new DashboardFragment();
private Fragment mNotificationsFragment = new NotificationsFragment();
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment fragment = null;
switch (item.getItemId()) {
case R.id.navigation_home:
fragment = mHomeFragment;
break;
case R.id.navigation_dashboard:
fragment = mDashboardFragment;
break;
case R.id.navigation_notifications:
fragment = mNotificationsFragment;
break;
}
return loadFragment(fragment);
}
As we could see, you are always replace your fragment when clicks on bottom navigation, replace means previous fragment removes and state cleans. The solution is do not create your fragment each time and use attach/detach method for showing actual fragment. Here is already described about these methods.
i have an home activity with icons at bottom navigation bar. On clicking the icons it moves to respective fragments. But the problem is the home activity stacks over all the fragments. What might be the problem here.
I tried finish(); after calling the fragment. But that closes all activities and goes to main activity. I need help.
Main Activity->HomeActivity-> attendance fragment
This is the home activity
Home Activity
On clicking the Attendance fragment below
Attendance fragment
Here is the code of home activity
public class FHome extends AppCompatActivity {
public static Activity fa;
private Toolbar toolbar;
private ListView listView;
public static SharedPreferences sharedPreferences;
public static String SEL_DAY;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fhome);
setupUIViews();
initToolbar();
setupListView();
fa = this;
BottomNavigationView bottomNavigationView = (BottomNavigationView)
findViewById(R.id.navigation);
bottomNavigationView.setOnNavigationItemSelectedListener
(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment selectedFragment = null;
switch (item.getItemId()) {
case R.id.action_item1:
selectedFragment = FAttendance.newInstance();
break;
case R.id.action_item2:
selectedFragment = FPost.newInstance();
break;
case R.id.action_item3:
selectedFragment = FUpdate.newInstance();
break;
}
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, selectedFragment);
transaction.commit();
return true;
}
});
//Manually displaying the first fragment - one time only
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, FPost.newInstance());
transaction.commit();
}
Help me out :(