Replacing fragments in one activity - android

I am able to add a fragment to my fragmentlayout, but when I'm trying to replace the fragment with a new one the screen is blank. I can add a new fragment but then it's not scrollable. I'm also not able not remove a fragment.
Does someone know what I'm doing wrong? I red a lot about it and I feel like I have tried everything..
The framelayout is defined static:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:minWidth="25px"
android:minHeight="25px">
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>'
And this is the method for switching fragments:
void TabOnTabSelected (object sender, ActionBar.TabEventArgs tabEventArgs)
{
ActionBar.Tab tab = (ActionBar.Tab)sender;
var fragmentTransaction = FragmentManager.BeginTransaction ();
switch (tab.Text) {
case "vandaag":
if (currentFragment != null) {
fragmentTransaction.Remove (FragmentManager.FindFragmentByTag ("gister"));
}
if (fragmentToday == null) {
fragmentToday = WZWVDataOverview.NewInstance (DateTime.Now.AddDays (0).ToString ("d-M-yyyy"));
}
fragmentTransaction.Add (Resource.Id.fragment_container, fragmentToday, "vandaag");
currentFragment = fragmentToday;
break;
case "gister":
if (currentFragment != null) {
fragmentTransaction.Remove (currentFragment);
}
if (fragmentYesterday == null) {
fragmentYesterday = WZWVDataOverview.NewInstance (DateTime.Now.AddDays (-1).ToString ("d-M-yyyy"));
}
currentFragment = fragmentYesterday;
fragmentTransaction.Add (Resource.Id.fragment_container, currentFragment, "gister");
break;
case "morgen":
if (currentFragment != null) {
fragmentTransaction.Remove (currentFragment);
}
if (fragmentTomorrow == null) {
fragmentTomorrow = WZWVDataOverview.NewInstance (DateTime.Now.AddDays (+1).ToString ("d-M-yyyy"));
}
fragmentTransaction.Add (Resource.Id.fragment_container, fragmentTomorrow);
currentFragment = fragmentTomorrow;
break;
}
fragmentTransaction.Commit ();
}
XML of the framelayout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:minWidth="25px"
android:minHeight="25px">
<ListView
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/list" />
</LinearLayout>
Huge thanks in advance!

You can try using the .replace method. If you do not wish to be able to move back to the previous fragment than you can remove addToBackStack().
This may need to be altered slightly to fit your application.
FragmentManager fragmentManager = getFragmentManager();
Fragment mFragment = new DetailFragment();
mFragment.setArguments(bundle);
fragmentManager.beginTransaction().replace(R.id.fragment_container, mFragment).addToBackStack("DETAILFRAGMENT").commit();
POSSIBLE SECOND SOLUTION:
Check to see how your Fragment layout XML is. Possibly try using a FrameLayout as the parent.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.modup.fragment.DetailFragment">
<!-- TODO: Update blank fragment layout -->
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</LinearLayout>
</FrameLayout>

I have open fragments from navigation view as items are selected from it.(I have use DataBinding Concept)
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout>
<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:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.k15.projectkhyatisalesapp.activities.MainActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
app:titleTextColor="#ffffff"
android:background="#ef6c00"
android:minHeight="?attr/actionBarSize"
app:popupTheme="#style/AppTheme.PopupOverlay"
android:theme="#style/ThemeOverlay.AppCompat.Dark"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="55dp"
android:orientation="horizontal">
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
android:layout_width="wrap_content"
android:id="#+id/activity_main_frame_layout"
android:layout_height="wrap_content"/>
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="#+id/activity_main_navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="#menu/listnavigation" />
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
</RelativeLayout>
<layout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
//Declaration of Variables
private ActivityMainBinding mainBinding; //for binding values in xml
private ActionBarDrawerToggle mDrawableToogle; //This class provides a handy way to tie together the functionality of DrawerLayout and the framework ActionBar to implement the recommended design for navigation drawers.
private Fragment fragment;
private Class fragmentClass = null; //pointing to class of fragment
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
setSupportActionBar(mainBinding.toolbar); //o designate a Toolbar as the action bar for an Activity
setUpDrawer(mainBinding.activityMainNavigation); //for select items in navigationView
mDrawableToogle = setupToogle();
mainBinding.drawerLayout.addDrawerListener(mDrawableToogle);
}
//private method to set navigationView
private void setUpDrawer(NavigationView navigationView) {
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
try {
selectItem(item); //call when item is selected from navigationView
} catch (IllegalAccessException | InstantiationException e) {
e.printStackTrace();
}
return true;
}
});
}
//items are selected from navigationView
public void selectItem(MenuItem menuItem) throws IllegalAccessException, InstantiationException {
switch (menuItem.getItemId()) {
case R.id.Home:
fragmentClass = Home.class;
break;
case R.id.Product:
fragmentClass = Product.class;
break;
case R.id.Media:
fragmentClass = Media.class;
break;
}
assert fragmentClass != null;
fragment = (Fragment) fragmentClass.newInstance();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(mainBinding.activityMainFrameLayout.getId(), fragment).commit(); //change the fragment
setTitle(menuItem.getTitle());
menuItem.setCheckable(true); //for set selected item
mainBinding.drawerLayout.closeDrawers();
}
#Override
protected void onPostCreate(#Nullable Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawableToogle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawableToogle.onConfigurationChanged(newConfig);
}
private ActionBarDrawerToggle setupToogle() {
return new ActionBarDrawerToggle(this, mainBinding.drawerLayout, mainBinding.toolbar, R.string.open, R.string.close);
}
menu/listnavigation.xml is attached to navigation view I contains items of navigation view.
In my code as items are selected from navigation view accordingly fragment is replaced. Here Home, Product, Media are my fragment, you can create any fragment.

Try using fragmentTransaction.replace() instead of fragmentTransaction.add() and comment out code for removing fragments. When you replace the fragment - it gets removed. Also - remember to call: fragmentTransaction.commit() when you are done with replacing fragments.

Related

How to move to another activity using bottom navigation bar using kotlin in android studio? [duplicate]

//Here is my java code
public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
BottomNavigationView bottomNavigationView;
NavigationView navigationView;
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull final MenuItem item) {
switch (item.getItemId()) {
case R.id.home:
HomeFragment homeFragment=new HomeFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction=getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frameLayout,homeFragment).commit();
return true;
case R.id.navigation_stylist:
StylistFragment stylistsFragment=new StylistFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction1=getSupportFragmentManager().beginTransaction();
fragmentTransaction1.replace(R.id.frameLayout,stylistsFragment).commit();
return true;
case R.id.navigation_apps:
MyapptsFragment myaaptsFragment=new MyapptsFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction2=getSupportFragmentManager().beginTransaction();
fragmentTransaction2.replace(R.id.frameLayout,myaaptsFragment).commit();
return true;
case R.id.navigation_tips:
HairtipsFragment hairtipsFragment=new HairtipsFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction3=getSupportFragmentManager().beginTransaction();
fragmentTransaction3.replace(R.id.frameLayout,hairtipsFragment).commit();
return true;
case R.id.navigation_account:
AccountFragment accountFragment=new AccountFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction4=getSupportFragmentManager().beginTransaction();
fragmentTransaction4.replace(R.id.frameLayout,accountFragment).commit();
return true;
}
return false;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//start onboarding when app is opening first time
isUserFirstTime = Boolean.valueOf(Utils.readSharedSetting(HomeActivity.this, PREF_USER_FIRST_TIME, "true"));
Intent introIntent = new Intent(HomeActivity.this, OnboardingActivity.class);
introIntent.putExtra(PREF_USER_FIRST_TIME, isUserFirstTime);
if (isUserFirstTime)
startActivity(introIntent);
setContentView(R.layout.activity_home);
bottomNavigationView = findViewById(R.id.bottom_navigation);
navigationView=findViewById(R.id.nav_drawer);
//bottom navigationview listener
bottomNavigationView.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);
//navigation drawer listener
navigationView.setNavigationItemSelectedListener(this);
//open home fragment on first launch
HomeFragment homeFragment=new HomeFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction=getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frameLayout,homeFragment).commit();
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.nav_home:
HomeFragment homeFragment=new HomeFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction=getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frameLayout,homeFragment).commit();
return true;
case R.id.nav_products:
StylistFragment stylistsFragment=new StylistFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction1=getSupportFragmentManager().beginTransaction();
fragmentTransaction1.replace(R.id.frameLayout,stylistsFragment).commit();
return true;
case R.id.nav_promotions:
MyapptsFragment myaaptsFragment=new MyapptsFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction2=getSupportFragmentManager().beginTransaction();
fragmentTransaction2.replace(R.id.frameLayout,myaaptsFragment).commit();
return true;
case R.id.nav_purchases:
HairtipsFragment hairtipsFragment=new HairtipsFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction3=getSupportFragmentManager().beginTransaction();
fragmentTransaction3.replace(R.id.frameLayout,hairtipsFragment).commit();
return true;
case R.id.nav_settings:
AccountFragment accountFragment=new AccountFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction4=getSupportFragmentManager().beginTransaction();
fragmentTransaction4.replace(R.id.frameLayout,accountFragment).commit();
return true;
}
return false;
}
}
// Here is my xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<android.support.design.widget.NavigationView
android:id="#+id/nav_drawer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:theme="#style/menu_text_style"
app:menu="#menu/navigation_drawer" />
<!--app:headerLayout="#layout/nav_header_main"-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/shadow"
android:animateLayoutChanges="true">
</FrameLayout>
<View
android:id="#+id/shadow"
android:layout_width="match_parent"
android:layout_height="#dimen/_1sdp"
android:layout_above="#id/bottom_navigation"
android:background="#color/shadow"/>
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:itemIconTint="#color/navigationitem"
app:itemTextColor="#color/navigationitem"
app:menu="#menu/navigation_item"/>
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>
I want to create both navigation drawer and bottom navigation in the same activity. I created XML design now I have to write java code for both. Bottom navigation is working perfectly but navigation item clicklistener is not working. I created fragments for navigation drawer and also for bottom navigation. When I click the items in navigation drawer it's not redirecting to respective fragment. The given clicklistener for navigation drawer is not at all working.
Solution:
Try the following steps to get it working:
Step1: Implement onNavigationItemSelected as shown below:
.... extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
Step2: Use the method generated by the interface as:
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.your_drawer_item_id:
....
....
case R.id.your_drawer_item_id:
....
....
}
}
Step3: In your class declare a Global variable:
public NavigationView navigationView;
Step4: In your onCreate() initialize the variable as:
navigationView = (NavigationView) findViewById(R.id.your_nav_view);
Finally: Setup the navigationView:
navigationView.setNavigationItemSelectedListener(this);
That's it.
Hope it works.
DrawerLayout xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_vendor_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_drawer_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#color/White"
android:fitsSystemWindows="true"
app:itemBackground="#android:color/white"
app:itemIconTint="#color/bottom_color"
app:itemTextColor="#color/bottom_color"
app:headerLayout="#layout/nav_header_vendor_drawer_layout"
app:menu="#menu/vendor_drawer_menu" >
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
app_bar_vendor_drawer_layout 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"
tools:context="logixtic.android.web.vd.driver.activities.DriverDrawerActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/MyMaterialTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/Project_Standard"
app:popupTheme="#style/MyMaterialTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
android:layout_above="#+id/bottom_navigation">
</FrameLayout>
<View
android:layout_width="match_parent"
android:layout_height="3dp"
android:background="#drawable/toolbar_dropshadow_above"
android:layout_above="#id/bottom_navigation"/>
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:itemBackground="#color/White"
app:itemIconTint="#color/bottom_color"
app:itemTextColor="#color/bottom_color"
app:menu="#menu/vendor_bottom_navigation"/>
</RelativeLayout>
Try it.
You can use on the same activity using a method that recive a MenuItem parameter like this:
private void myClickItem(MenuItem item){
switch (item.getItemId()) {
case R.id.bottom_home:
// DO SOMETHING
break;
case R.id.drawer_main:
// DO SOMETHING
break;
}
}
Then, call like this:
BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(item -> { // using lamda
myClickItem(item); //call here
return true;
});
NavigationView navigationView = findViewById(R.id.nv);
navigationView.setNavigationItemSelectedListener(item -> {
myClickItem(item); // call the same method here
drawerLayout.closeDrawers(); // bonus: hide navigation after click
return false;
});
You don't need to modify your xml res, it'll work fine.

How to handle drawer toggle and toolbar up when having toolbar for each fragment

I am using single activity and many fragments approach in my app
Now since in my some fragments I have custom view in toolbar I decided to have separate toolbar for each fragment.
How to implement separate toolbar for each fragment also the drawer layout is in my activity
I have the same problem, I will add custom toolbar view for each fragment.
My Utility method is:
public static View addRemoveViewFromToolbar(FragmentActivity fragmentActivity, int resourceId) {
Toolbar toolbar = removeViewFromToolbar(fragmentActivity);
if (resourceId == 0) {
return null;
} else {
View view = LayoutInflater.from(fragmentActivity).inflate(resourceId, toolbar, false);
toolbar.addView(view);
return view;
}
}
public static Toolbar removeViewFromToolbar(FragmentActivity fragmentActivity) {
Toolbar toolbar = (Toolbar) fragmentActivity.findViewById(R.id.toolbar);
if (toolbar.getChildCount() > 1) {
for (int i = 1; i <= toolbar.getChildCount(); i++) {
toolbar.removeViewAt(1);
}
}
return toolbar;
}
In my each fragment
//Create your custom view based on requirement
View view = Utility.addRemoveViewFromToolbar(getActivity(), R.layout.toolbar_search_view);
if (view != null) {
edtCategory1 = (EditText) view.findViewById(R.id.edtCategory1);
edtCategory1.setOnClickListener(this);
}
Hope this explanation help you :)
I'm not sure if I understood your description of the your app correctly, but I recently did what I think you described.
My activity layout was a DrawerLayout with an included CoordinatorLayout/AppBar layout with a single toolbar and a FrameLayout below. The menu.xml contained all the items I needed in my toolbar for all the fragments. Items clicked in the nav menu would swap out fragments in the FrameLayout. My onNavigationItemSelected() called on this method to swap out the fragments and handle the backstack:
public void switchView(int id, int optArg) {
if (currentView != id) {
currentView = id; //currentView keeps track of which fragment is loaded
FragmentTransaction transaction = getFragmentManager().beginTransaction();
//Fragment contentFragment is the current fragment in the FrameLayout
switch (id) {
case 0: //menu item 1
contentFragment = new Nav_Item1_Fragment();
transaction.replace(R.id.fragment_container, contentFragment, "");
break;
case 1: //menu item 2
contentFragment = new Nav_Item2_Fragment();
transaction.replace(R.id.fragment_container, contentFragment, "");
break;
case 2: //menu item 3
contentFragment = new Nav_Item3_Fragment();
transaction.replace(R.id.fragment_container, contentFragment, "");
break;
}
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
// transaction.replace(R.id.fragment_container, contentFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
}
and in each fragment's onPrepareOptionsMenu() I setVisible() hid/showed the menu items in the toolbar related to that fragment. Each item had an method in the activity pointed to by the menu item's onClick attribute that knew what fragment it was from and what views were passed to it.
The drawer was setup in the onCreate() of the activity with a ActionBarDrawerToggle like so:
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();
activity xml:
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
...>
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
.../>
</android.support.v4.widget.DrawerLayout>
app_bar_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
...>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:gravity="top"
.../>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/fragment_container"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
So...One Nav menu, one App/Tool Bar, multiple fragments
Why do you specifically want a separate toolbar for each fragment?
You can easily change the toolbar view for each fragment.
In your function to switch fragments -
public void selectDrawerItem(MenuItem item) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction;
switch (item.getItemId()) {
case R.id.nav_home :
getSupportActionBar().setCustomView(R.layout.home_nav_bar);
fragmentClass = HomeFragment.class;
break;
case R.id.nav_settings :
getSupportActionBar().setCustomView(R.layout.settings_nav_bar);
fragmentClass = SettingsFragment.class;
break;
}
fragment = (Fragment) fragmentClass.newInstance();
fragmentManager.popBackStack(null,
FragmentManager.POP_BACK_STACK_INCLUSIVE);
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
So you can easily use the same toolbar and customize it according to your requirements for each fragment.
It can be done in a quite straightforward way.
First create an activity with a drawerlayout.
Second create a container viewpager inside the activity to hold
the fragments
Third implement a listener on your viewpager that will set the
relevant toolbar based on the fragment on display.
Let me illustrate by relevant XMLs and code
First the Drawerlayout XML for the main activity
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_landing_page"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_landing_page"
app:menu="#menu/activity_landing_page_drawer" />
</android.support.v4.widget.DrawerLayout>
Please note the container layout app_bar_landing_page. Now the XML for this
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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"
tools:context="me.veganbuddy.veganbuddy.ui.LandingPage">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
app:logo="#drawable/vegan_buddy_menu_icon"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/container_for_fragments"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
Note the viewpager which will act as container for fragments. Now the OnPageChangeListener on the viewpager.
mViewPager = (ViewPager) findViewById(R.id.container_for_fragments);
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
switch (position+1){
case 0:setSupportActionBar(aToolbar);
break;
case 1:setSupportActionBar(bToolbar);
break;
case 2:setSupportActionBar(cToolbar);;
break;
case 3:setSupportActionBar(dToolbar);
break;
default:
break;
}
}
Let me know if any further clarification is needed
The simplest approach I would suggest is to use callbacks to activity. Whenever each fragment loads in the activity, arrange a callback to the activity and load the appropriate toolbar in the activity.
Have separate toolbar xmls in your layout folder. Use the include tag to put the toolbars in your activity. Keep only 1 toolbar visible at a time. When the fragment callbacks come to your activity make the necessary one visible.
It's very simple. Besides the onclick action for the Category fragment is taking you into a new activity, not a Fragment. Now, since drawer layout is in parent activity with navigation view and without toolbar then in the first drawer fragment is a tablayout having four tabs with viewpager and a toolbar on the top and inside one tab i.e HOME is the TOP CHARTS, CATEGORIES, EDITORS. Each toolbar must be implemented in each fragment layout and not in the activity layout since you want different toolbars for each fragment. Note that Toolbar is not a property of Fragment but it's a property of ActionBarActivity or AppCompatActivity, then in the onCreateView, of the fragment that's holding the HOME, GAMES, MOVIES, MUSIC, put down these codes.
public class Drawer1Fragment extends Fragment{
public Drawer1Fragment () {}
TabLayout tabLayout;
Toolbar toolbar;
DrawerLayout drawerLayout;
ViewPager viewPager;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View myChildRoot = inflater.inflate(R.layout.child_fragment_attachment, container, false);
tabLayout = myChildRoot.findViewById(R.id.tab_layout);
viewPager= myChildRoot.findViewById(R.id.container_viewPager);
toolbar = myChildRoot.findViewById(R.id.toolbar);
drawerLayout = getActivity().findViewById(R.id.drawer_layout);
((AppCompatActivity)requireActivity()).setSupportActionBar(toolbar);
((AppCompatActivity)requireActivity()).getSupportActionBar().setTitle(getActivity().getResources().getString(R.string.app_name));
((AppCompatActivity)requireActivity()).getSupportActionBar().setHomeButtonEnabled(true);
((AppCompatActivity)getParentFragment().requireActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(getActivity(),drawerLayout,toolbar,R.drawable.icons,R.string.app_name);
drawerLayout.addDrawerListener(toggle);
toggle.syncState();
// The back arrow of a toolbar in fragment is implemented below
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view)
{
if(!drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.openDrawer(GravityCompat.START);
} else {
getActivity().finish();
}
}
});
return myChildRoot;
}
}

fragment of fragments toolbar title setting

I have one Activity and lots of fragments switch between this Activity, i set the toolbar title just in this Activity , like this :
this Activity:
#Override
public void onClick(View view) {
int id = view.getId();
if (id == R.id.logIn){
switchFragment(LogInFragment.newInstance());
//when i switch fragment , i change the tile by this code
toolbar.setTitle(R.string.pageLogIn);
drawerLayout.closeDrawer(GravityCompat.START);
}
if (id == R.id.singUp){
switchFragment(SignUp.newInstance());
toolbar.setTitle(R.string.singUp);
drawerLayout.closeDrawer(GravityCompat.START);
}
}
private void switchFragment(Fragment fragment) {
FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.mainFrame, fragment, null);
//transaction.addToBackStack(null);
transaction.commit();
}
and this my Activity layout:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.user.taiwandigestionsociety_v11.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFFFF">
<android.support.v7.widget.Toolbar
android:id="#+id/toolBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:theme="#style/ToolBarStyle"
android:background="#drawable/actionbar">
</android.support.v7.widget.Toolbar>
<FrameLayout
android:id="#+id/mainFrame"
android:layout_gravity="end"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</android.support.design.widget.AppBarLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#android:color/transparent"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header">
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
My question is one of fragments has a button that it will switch to new fragment, i can't switch the toolbar title by the Activity java .
I try another way to set the function to call the Activity switch function, the app will crash .
I try like this:
public class Welcome extends Fragment implements View.OnClickListener {
#Override
public void onClick(View view) {
int id = view.getId();
if (id == R.id.welcomeLogin){
MainActivity mainActivity=new MainActivity();
mainActivity.switchFragment(ActivityHomePage.newInstance());
}
}
}
How can i set the fragment toolbar title like those fragments ?
Create One Method in Activity :
public void setToolBar(String title) {
getSupportActionBar().setTitle(title);
}
And call this method in onCreateView of Fragment :
((MainActivity) getActivity()).setToolBar(title);
Do not create instance of Activity like this! Rather pass your context of MainActivity to the Fragment then use that to change.
- MainActivity mainActivity=new MainActivity();
- mainActivity.switchFragment(ActivityHomePage.newInstance());
First of defined main activity
private HomeActivity activity;
after set values "onCreate" method
activity = (HomeActivity) getActivity();
set toolbar values:
HeaderBar headerBar;
headerBar = (HeaderBar) view.findViewById(R.id.headerBar);
Example i hv set right side image in tital bar:
headerBar.ivRight.setImageResource(R.mipmap.save);

View pager Fragment is blank on back pressed

I'm using ViewPager inside fragment. The viewpager contains two fragments.
My problem when I go back to this fragment i got a blank fragment (it works only in the first time).
ViewPager Code :
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager());
adapter.addFragment(new ListeMagasinsFragment(), getActivity().getString(R.string.liste));
adapter.addFragment(new MapMagasinsFragment(), getActivity().getString(R.string.carte));
viewPager.setAdapter(adapter);
}
I also overrided onBackPressed() :
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
super.onBackPressed();
} else {
getSupportFragmentManager().popBackStack();
}
//super.onBackPressed();
}
}
This code below shows the fragment transaction :
Fragment fragment = new MagasinDetailsFragment();
if (fragment != null) {
Bundle bundles = new Bundle();
if (magasin != null) {
bundles.putSerializable("magasin", (Serializable) magasin);
Log.e("magasin", "is valid");
} else {
Log.e("magasin", "is null");
}
fragment.setArguments(bundles);
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container_body, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
More code:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_magasins, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false);
viewPager = (ViewPager)view.findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) view.findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
}
Fragment xml :
<android.support.design.widget.CoordinatorLayout 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.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMaxWidth="0dp"
app:tabMode="fixed"
app:tabGravity="fill"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
main_activity.xml :
<android.support.v4.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer"
/>
And content_main.xml :
<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:id="#+id/content_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.carrefour.creova.carrefourmobile.activities.MainActivity"
tools:showIn="#layout/app_bar_main">
<FrameLayout
android:id="#+id/container_body"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
Any ideas ?
In your Activity override the onBackPressed() method.
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack();
} else{
finish();
}
}
You must have added the fragments to the BackStack for this to work, something similar to:
Fragment fragment = new YourFragment();
Bundle bundle = new Bundle();
bundle.putString("variable_if_needed", "Some Value");
getFragmentManager().beginTransaction()
.replace(R.id.relativecontent, fragment)
.addToBackStack(null)
.commit();
return true;
"R.id.relativecontent" should be your Fragment container.
Is it actually necessary to go back to the previous page in the viewPager when you press the back button? That is not something I have seen often. For one, the previous page(Fragment) should be a left or right swipe away from the current one, and you may implement an AlertDialog to prompt the user to see if he wants to exit the app instead.

Android: How to use a ViewPager + action bar tab correctly in a Fragment?

This is my activity_main.xml:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Framelayout to display Fragments -->
<FrameLayout
android:id="#+id/frameContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- Listview to display slider menu -->
<ListView
android:id="#+id/listMainMenu"
android:layout_width="280dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#color/color_list_mainmenu_divider"
android:dividerHeight="1dp"
android:listSelector="#drawable/list_item_mainmenu_selector_background"
android:background="#color/color_list_mainmenu_background"/>
</android.support.v4.widget.DrawerLayout>
So in my MainActivity class I can show my main menu and I can show a new Fragment:
private void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
String title = null;
switch (position) {
case 1:
fragment = new WorkoutStoreFragment();
title = getString(R.string.mainmenu_item_workout);
break;
....
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frameContainer, fragment).commit();
// update selected item and title, then close the drawer
this.listMainMenu.setItemChecked(position, true);
this.listMainMenu.setSelection(position);
setTitle(title);
this.drawerLayout.closeDrawer(this.listMainMenu);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
But in my WorkoutStoreFragment class (extend v4.support.Fragment) I want to use a viewPager with a TabPageIndicator class to show some different other Fragments. But it doesn't work.
In general, my view architecture is it correct ?
Thanks by advance guys!

Categories

Resources