I want to show Bottom Navigation View inside a fragment just like Instagram. First of all is it possible to add bottom navigation view inside fragment? And if yes, then how?
This is inside onCreateView:
private BottomNavigationView.OnNavigationItemSelectedListener
mOnNavigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
Fragment fragment;
switch (menuItem.getItemId()){
case R.id.navigation_home:
toolbar.setTitle("Home");
return true;
case R.id.navigation_attend:
toolbar.setTitle("Attendance");
return true;
case R.id.navigation_inquire:
toolbar.setTitle("Inquiry");
return true;
case R.id.navigation_help:
toolbar.setTitle("Help Desk");
return true;
case R.id.navigation_setting:
toolbar.setTitle("Profile");
return true;
}
return false;
}
};
And according to https://www.androidhive.info/2017/12/android-working-with-bottom-navigation/ we've to use:
ActionBar toolbar = getSupportActionBar();
toolbar.setTitle("Home");
But I know this isn't working...
Thanks in advance
Related
I am very new to android development and hence, I am not able to solve my problems via help from other internet resources. Using Youtube videos, I am designing an app that uses both NavigationDrawer and TabLayout, and all the TabLayout items and navigation drawer items use fragments. My problem is that when I clicked on items in navigation drawers, the app still displays TabLayout's fragments instead of displaying the fragment corresponding to the clicked item from `NavigationDrawer. Please help me with this. I have included code and even an image below. Thanks a lot.
The abovementioned image.
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
private DrawerLayout drawer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//following gives toolbar and navigation bar can be viewed by sliding L-R
Toolbar toolbar = findViewById(R.id.toolbar_main);
setSupportActionBar(toolbar);
//attach sectionpageadapter to viewpager
SectionPagerAdapter pagerAdapter = new SectionPagerAdapter(getSupportFragmentManager());
ViewPager pager = findViewById(R.id.pager);
pager.setAdapter(pagerAdapter);
//attach viewpager to tablayout
TabLayout tabLayout = findViewById(R.id.tabs);
tabLayout.setupWithViewPager(pager);
//following to give hamburger sign to navigation drawer
drawer = findViewById(R.id.drawer_layout);
//references to listen to click events on navigation views
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
//following for hamburger sign to rotate when slide from L-R
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer,toolbar,
R.string.navigation_drawer_open,R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
//below is our default fragment which will be shown on create, without any clicks
//if statement so that it wont reload on rotation or resume of the device
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new HomeFragment()).commit();
navigationView.setCheckedItem(R.id.nav_home);
}
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
switch (menuItem.getItemId()){
case R.id.nav_home:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new HomeFragment()).commit();
break;
case R.id.nav_myaccount:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new AccountFragment()).commit();
break;
case R.id.nav_mymessages:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new MessageFragment()).commit();
break;
case R.id.nav_mysongs:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new MySongFragment()).commit();
break;
case R.id.nav_mystores:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new StoreFragment()).commit();
break;
}
drawer.closeDrawer(GravityCompat.START);
return true;
}
#Override
//following for closing navagation bar instead of leaving activity immediately when you press back button
public void onBackPressed() {
if(drawer.isDrawerOpen(GravityCompat.START)){
drawer.closeDrawer(GravityCompat.START);
}else {
super.onBackPressed();
}
}
private class SectionPagerAdapter extends FragmentPagerAdapter{
public SectionPagerAdapter(FragmentManager fm){
super(fm,BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
#Override
public int getCount() {
return 4;
}
#NonNull
#Override
public Fragment getItem(int position) {
switch (position){
case 0:
return new HomeFragment();
case 1:
return new FragmentArtists();
case 2:
return new FragmentAlbum();
case 3:
return new FragmentPlaylists();
}
return null;
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
switch (position){
case 0:
return getResources().getText(R.string.home_tab);
case 1:
return getResources().getText(R.string.artist_tab);
case 2:
return getResources().getText(R.string.album_tab);
case 3:
return getResources().getText(R.string.playlist_tab);
}
return null;
}
}
}
Replace this code!
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
switch (menuItem.getItemId()){
case R.id.nav_home:
pager.setVisibility(View.VISIBLE);
tabs.setVisibility(View.VISIBLE);
fragmentConterner.setVisibility(View.GONE);
break;
case R.id.nav_myaccount:
pager.setVisibility(View.GONE);
tabs.setVisibility(View.GONE);
fragmentConterner.setVisibility(View.VISIBLE);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new AccountFragment()).commit();
break;
case R.id.nav_mymessages:
pager.setVisibility(View.GONE);
tabs.setVisibility(View.GONE);
fragmentConterner.setVisibility(View.VISIBLE);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new MessageFragment()).commit();
break;
case R.id.nav_mysongs:
pager.setVisibility(View.GONE);
tabs.setVisibility(View.GONE);
fragmentConterner.setVisibility(View.VISIBLE);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new MySongFragment()).commit();
break;
case R.id.nav_mystores:
pager.setVisibility(View.GONE);
tabs.setVisibility(View.GONE);
fragmentConterner.setVisibility(View.VISIBLE);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new StoreFragment()).commit();
break;
}
drawer.closeDrawer(GravityCompat.START);
return true;
}
I hope it's helpful for you!
you have the provision to set the visibility of the layout elements to visible,invisible and gone. Programatically you can do this by
ViewPager.setVisibility(View.GONE);
TabLayout.setVisibility(View.GONE);
and also you can show the FrameLayout that you are using to inflate the FrameLayout container.
FrameLayout.setVisibility(View.VISIBLE);
And start with having the FrameLayout set to gone in the XML attribute.
android:visibility="gone"
I hope it helps.
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'm coupling BottomNavigationView with ViewPager, it works ok, the main reason for that is the swiping and animation.
There are 3 possibilities on my listener:
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
viewPager.setCurrentItem(0);
return true;
case R.id.navigation_solicitation:
viewPager.setCurrentItem(1);
return true;
case R.id.navigation_my_profile:
viewPager.setCurrentItem(2);
return true;
}
return false;
}
};
However, there are other, unlisted fragments. How can I inflate fragments on the view pager and make it go away once swiped or something else was selected?
Solution
Added this below the viewpager in the main layout file:
<FrameLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</FrameLayout>
Below is the method used to open the new fragment and make viewpager gone:
viewPager.setVisibility(viewPager.GONE);
fragment = new PostSolicitationFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_up, R.anim.slide_out_down);
ft.replace(R.id.content, fragment);
ft.commit();
And this is the new onNavigationSelectedItems to make it show up again in case the user clicks a menu item.
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
viewPager.setVisibility(VISIBLE);
viewPager.setCurrentItem(0);
return true;
case R.id.navigation_solicitation:
viewPager.setVisibility(VISIBLE);
viewPager.setCurrentItem(1);
return true;
case R.id.navigation_my_profile:
viewPager.setVisibility(VISIBLE);
viewPager.setCurrentItem(2);
return true;
}
return false;
}
I used BottomNavigationView to switch fragments. How to get currently selected menu item, to prevent reopening fragment ?
BottomNavigationView bottomNavigationView = (BottomNavigationView)
findViewById(R.id.bottom_navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(
new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.action_1:
// open fragment 1
break;
case R.id.action_2:
// open fragment 2
break;
case R.id.action_3:
// open fragment 3
break;
}
return false;
}
});
}
Get selected item at first and then getMenu().findItem(int itemId)
bottomNavigationView.getMenu().findItem(bottomNavigationView.getSelectedItemId())
Solution:
private int getSelectedItem(BottomNavigationView bottomNavigationView) {
Menu menu = bottomNavigationView.getMenu();
for (int i = 0; i < bottomNavigationView.getMenu().size(); i++) {
MenuItem menuItem = menu.getItem(i);
if (menuItem.isChecked()) {
return menuItem.getItemId();
}
}
return 0;
}
Get the currently selected menu item ID using getSelectedItemId:
int selectedItemId = bottomNavigationView.getSelectedItemId();
MenuItem selectedItem = bottomNavigationView.getMenu().findItem(selectedItemId);
This method started being available from Android Support Library 25.3.0.
I think the simplest solution for checking if the previous item is the next item is this:
BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(
new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
final int previousItem = bottomNavigationView.getSelectedItemId();
final int nextItem = item.getItemId();
if (previousItem != nextItem) {
switch (nextItem) {
case R.id.action_1:
// open fragment 1
break;
case R.id.action_2:
// open fragment 2
break;
case R.id.action_3:
// open fragment 3
break;
}
}
return true;
}
}
);
Note that there is no need for iterating, and that onNavigationItemSelected returns true, because the function consumes the event.
I hope it helps someone.
I have android.support.v7.widget.Toolbar in my fragment.
Also I declared in my Fragment onViewCreated this:
((MainActivity) mCtx).setSupportActionBar(toolbar);
((MainActivity) mCtx).getSupportActionBar().setTitle(null);
((MainActivity) mCtx).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
But I cant make that Toolbar button back to work no way.
How to do that?
Tried to:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackAction();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Instead of onBackAction(); use:
onBackPressed();
break;