Managing Fragments in a navigation drawer - android

I copied a navigation drawer from
http://javatechig.com/android/navigation-drawer-android-example
But I'm having trouble managing the fragments, or rather the main content on the screen.
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTitle = "Formulas";
getActionBar().setTitle(mTitle);
// Getting reference to the DrawerLayout
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.drawer_list);
// Getting reference to the ActionBarDrawerToggle
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
R.drawable.ic_drawer, R.string.drawer_open,
R.string.drawer_close) {
/** Called when drawer is closed */
public void onDrawerClosed(View view) {
getActionBar().setTitle(mTitle);
invalidateOptionsMenu();
}
/** Called when a drawer is opened */
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle("Formulas");
invalidateOptionsMenu();
}
};
// Setting DrawerToggle on DrawerLayout
mDrawerLayout.setDrawerListener(mDrawerToggle);
// Creating an ArrayAdapter to add items to the listview mDrawerList
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getBaseContext(),
R.layout.drawer_list_item, getResources().getStringArray(R.array.menus));
// Setting the adapter on mDrawerList
mDrawerList.setAdapter(adapter);
// Enabling Home button
getActionBar().setHomeButtonEnabled(true);
// Enabling Up navigation
getActionBar().setDisplayHomeAsUpEnabled(true);
// Setting item click listener for the listview mDrawerList
mDrawerList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// Getting an array of rivers
String[] menuItems = getResources().getStringArray(R.array.menus);
// Currently selected river
mTitle = menuItems[position];
// Creating a fragment object
WebViewFragment rFragment = new WebViewFragment();
// Passing selected item information to fragment
Bundle data = new Bundle();
data.putInt("position", position);
data.putString("url", getUrl(position));
rFragment.setArguments(data);
// Getting reference to the FragmentManager
FragmentManager fragmentManager = getFragmentManager();
// Creating a fragment transaction
FragmentTransaction ft = fragmentManager.beginTransaction();
// Adding a fragment to the fragment transaction
ft.replace(R.id.content_frame, rFragment);
// Committing the transaction
ft.commit();
// Closing the drawer
mDrawerLayout.closeDrawer(mDrawerList);
}
});
}
protected String getUrl(int position) {
switch (position) {
case 0:
return "http://javatechig.com";
case 1:
return "http://javatechig.com/category/android/";
case 2:
return "http://javatechig.com/category/blackberry/";
case 3:
return "http://javatechig.com/category/j2me/";
case 4:
return "http://javatechig.com/category/sencha-touch/";
case 5:
return "http://javatechig.com/category/phonegap/";
case 6:
return "http://javatechig.com/category/java/";
default:
return "http://javatechig.com";
}
}
How do I manage the fragment so that I can:
- Input either basic xml/java (so I don't have to bother about bundles) in the project
or
- replace the current fragment so that I can create my own and customize everything myself

Try Checking this answer ..
It ll help you setting-up & using the Navigation Drawer in a dynamic way...
https://stackoverflow.com/a/34244065/2457493
Hope this fulfills you query..

I assume this is the example code from the Android Project shipped with the SDK.
Your sample actually contains the code needed for swapping the fragments in the content pane of the Activity.
// Getting reference to the FragmentManager
FragmentManager fragmentManager = getFragmentManager();
// Creating a fragment transaction
FragmentTransaction ft = fragmentManager.beginTransaction();
// Adding a fragment to the fragment transaction
ft.replace(R.id.content_frame, rFragment);
// Committing the transaction
ft.commit();
Your rFragment is the fragment that is going to be loaded. You can put this whole section in a method and pass your fragment to be loaded as an argument of that method, e.g.
private void replaceFragment(Fragment newFragment) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.id.content_frame, newFragment);
ft.commit();
}
If your Fragment to be loaded needs data to be passed to it, you can use the Bundle. Your fragments might take different types of data, but the code above still applies. Call it after you have called setArguments() on your Fragment object.

Related

Go directly to fragment in Navigation Drawer Android

I have a navigation drawer activity with fragments in it. Now how can I make the app to go directly to a fragment when that activity is opened? I don't want to show the content_main.xml (which is blank):
#Override
public boolean onNavigationItemSelected(MenuItem item) {
//calling the method displayselectedscreen and passing the id of selected menu
displaySelectedScreen(item.getItemId());
return true;
}
private void displaySelectedScreen(int itemId) {
//creating fragment object
Fragment fragment = null;
//initializing the fragment object which is selected
switch (itemId) {
case R.id.nav_menu1:
fragment = new Menu1();
break;
case R.id.nav_menu2:
fragment = new Menu2();
break;
case R.id.nav_menu3:
fragment = new Menu3();
break;
}
//replacing the fragment
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);
}
in onCreate()
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);
//add this line to display menu1 when the activity is loaded
displaySelectedScreen(R.id.nav_menu1);
You have some options.
1) Open activity_main.xml
And replace a line that includes layout=content_main with the layout that you actually want instead.
2) Just load the Fragment in onCreate like you would when you do click on the Navigation Drawer.
go to Activity onCreate method and put this
FragmentManager fm =getFragmentManager();
FragmentTransaction ft= fm.beginTransaction();
// the Second paramter is Object from your Fragment that you want to add it
ft.replace(R.id.activity_main ,fragmentObject );
ft.commit();

Fragment overlap another when go back

i have menu with two fragments. when i choose second fragment, i can move to third fragment with button.
MainActivity
drawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close);
mDrawerLayout.setDrawerListener(drawerToggle);
drawerToggle.syncState();
getSupportActionBar().setTitle("demo");
mSelectedId = savedInstanceState == null ? R.id.aboutConference : savedInstanceState.getInt("SELECTED_ID");
itemSelection(mSelectedId);
}
private void setToolbar() {
toolbar = (Toolbar) findViewById(R.id.toolbar);
if (toolbar != null) {
setSupportActionBar(toolbar);
}
}
private void initView() {
mDrawer = (NavigationView) findViewById(R.id.main_drawer);
mDrawer.setNavigationItemSelectedListener(this);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
}
private void itemSelection(int mSelectedId) {
switch (mSelectedId) {
case R.id.aboutConference:
mDrawerLayout.closeDrawer(GravityCompat.START);
fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.main_container, new FirstFragment());
fragmentTransaction.commit();
break;
case R.id.aboutDeveloper:
mDrawerLayout.closeDrawer(GravityCompat.START);
fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.main_container, new SecondFragment());
fragmentTransaction.commit();
break;
}
}
Second fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view =
inflater.inflate(R.layout.second_fragment, container, false);
Button button = (Button)view.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction fragmentTransaction = getActivity().getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.main_container, new ThirdFragment());
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
});
return view;
}
When i press backbutton, it's working correctly.
second fragment
But if i move to third fragment, choose first fragment in menu and press backbutton, third fragment overlaps first fragment
problem
How i can resolve this problem?
UPDATE: i don't want that i can return from first fragment to third when i press back button.
As Shaishav and vishal told you need to put colorto your parent view of the fragment.
orelse you need to Override the onBackButton pressed method and make sure the remove the previous item from stack.
To check if item is there in the stack or not try the following code
fragmentManager1.getBackStackEntryCount()

Android title changes but fragment stays the same after replace commit

I have a simple navigation drawer. When I click on the item to change the current fragment it runs the code for the replace command runs but the fragment does not change.
Here is how I setup the navigation drawer:
private void setupNavigationMenu(final Bundle savedInstanceState) {
final DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.nav_drawer_items);
// Create the navigation drawer.
navigationDrawer = new NavigationDrawer(this, toolbar, drawerLayout, mDrawerList,
R.id.main_fragment_container);
String[] osArray = {"Discover Tunes", "My Discovered Tunes"};
mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, osArray);
mDrawerList.setAdapter(mAdapter);
if (savedInstanceState == null) {
// Add the home fragment to be displayed initially.
discoverSongs();
}
mDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (position == 0){
discoverSongs();
drawerLayout.closeDrawers();
} else {
myDiscoveredSongs();
drawerLayout.closeDrawers();
}
}
});
As you can see above I have onitemclicklistner running the functions discoverSongs() and myDiscoveredSongs(). When I click on the list I can see that the correct position is working and the correct function is running. But the fragment for discoverSongs() is always showing up.
Here is my discoverSongs() function:
public void discoverSongs() {
final Fragment fragment = new DiscoverSongFragment();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.main_fragment_container, fragment, DiscoverSongFragment.class.getSimpleName())
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.commit();
setTitle("Discover Tunes");
And my myDiscoveredSongs() function looks like this:
public void myDiscoveredSongs() {
final Fragment fragment = new DiscoverSongFragment();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.main_fragment_container, fragment, MyDiscoveredSongsFragment.class.getSimpleName())
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.commit();
setTitle("My Discovered Tunes");
}
Thanks for your help.
You are use same fragment name inmyDiscoveredSongs() method so change this line you code
final Fragment fragment = new DiscoverSongFragment();
in inmyDiscoveredSongs().

Fragment already added - a bug

I cant seem to replace the fragments without having the app crush. Tried reading about it before asking here but I couldn't find a definitive answer. It seems as if this is a bug(?)
here is my code (fails in swtich case:1 with error that fragment main already added)
// Sound Cloud fragment
mSoundCloudFrag = new SoundCloudFragment();
// Add just the main player fragment
main = new Play_Main();
fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.frameContainer, main, "main");
ft.commit();
getFragmentManager().executePendingTransactions();
// Navigation Drawer
mNavigationItems = getResources().getStringArray(R.array.nav_drawer);
mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
mDrawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_itm, mNavigationItems));
mDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
switch (position) {
case 0: // Open the SoundCloud fragment
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.frameContainer, mSoundCloudFrag, "soundCloudFrag");
ft.commit();
mDrawer.closeDrawers();
case 1: // Local PC media player
FragmentTransaction ft2 = fm.beginTransaction();
ft2.replace(R.id.frameContainer, main, "main");
ft2.commit();
mDrawer.closeDrawers();
}
}
});
Maybe you lose break; in first case of the switch?

How to navigate to previous fragment using back-button within NavigationDrawer?

I know that similar questions have been asked before, but I can't seem to find exactly what I’m looking for. My problem is that my back button is currently exiting the app. What I’m trying to do is to make it navigate to the previous fragment. Like if you open fragment1 - > fragment2 and then press the back button it would take you back to fragment1.
My current code looks like this.
public class MainActivity extends FragmentActivity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
private String[] mPageTitles;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTitle = mDrawerTitle = getTitle();
mPageTitles = getResources().getStringArray(R.array.menu_array);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
// set a custom shadow that overlays the main content when the drawer
// opens
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow,
GravityCompat.START);
// set up the drawer's list view with items and click listener
mDrawerList.setAdapter(new ArrayAdapter<String>(this,
R.layout.drawer_list_item, mPageTitles));
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
// enable ActionBar app icon to behave as action to toggle nav drawer
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
// ActionBarDrawerToggle ties together the the proper interactions
// between the sliding drawer and the action bar app icon
mDrawerToggle = new ActionBarDrawerToggle(this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description for accessibility */
R.string.drawer_close /* "close drawer" description for accessibility */
)
{
public void onDrawerClosed(View view) {
getActionBar().setTitle(mTitle);
invalidateOptionsMenu(); // creates call to
// onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(mDrawerTitle);
invalidateOptionsMenu(); // creates call to
// onPrepareOptionsMenu()
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
// Sets the firstpage if no state is found
if (savedInstanceState == null) {
selectItem(0);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
/* Called whenever we call invalidateOptionsMenu() */
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// If the nav drawer is open, hide action items related to the content
// view
return super.onPrepareOptionsMenu(menu);
}
// Toogles the drawer menu
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return mDrawerToggle.onOptionsItemSelected(item);
}
/* The click listner for ListView in the navigation drawer */
private class DrawerItemClickListener implements
ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
selectItem(position);
}
}
private void selectItem(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
switch (position) {
case 0:
KontaktInfoFragment kontakt = new KontaktInfoFragment();
fragmentTransaction.replace(R.id.content_frame, kontakt);
fragmentTransaction.addToBackStack("Replace");
fragmentTransaction.commit();
break;
case 1:
OmOssFragment omoss = new OmOssFragment();
fragmentTransaction.replace(R.id.content_frame, omoss);
fragmentTransaction.addToBackStack("Replace");
fragmentTransaction.commit();
break;
case 2:
MainScreenActivity mainscreen = new MainScreenActivity();
fragmentTransaction.replace(R.id.content_frame, mainscreen);
fragmentTransaction.addToBackStack("Replace");
fragmentTransaction.commit();
break;
case 3:
LoginFragment login = new LoginFragment();
fragmentTransaction.replace(R.id.content_frame, login);
fragmentTransaction.addToBackStack("Replace");
fragmentTransaction.commit();
break;
case 4:
ContactFormFragment form = new ContactFormFragment();
fragmentTransaction.replace(R.id.content_frame, form);
fragmentTransaction.addToBackStack("Replace");
fragmentTransaction.commit();
break;
}
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
setTitle(mPageTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
#Override
public void setTitle(CharSequence title) {
mTitle = title;
getActionBar().setTitle(mTitle);
}
}
When you press back button inside your fragment onBackPressed() method of your activity will be called if you have declared that..So handling back button for fragments within navigation drawer can be one in this way..
MainActvity
public static boolean isMainActivityShown ;
public static boolean isFragment1Shown=false ;
public static boolean isFragment2Shown=false ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
isMainActivityShown=true //inside onCreate method put isMainActivityShown true
.
.
.
}
Fragment currentFragment = new Fragment1();
isMainActivityShown=false; //when moving to fragment1
isFragment1Shown=true;
frgManager = getFragmentManager();
frgManager.beginTransaction().replace(R.id.content_frame, currentFragment)
.commit();
#Override
public void onBackPressed() {
if(isMainActivityShown)
{
finish();
}
else if(isFragment1Shown)
{
//write the code to handle back button when you are in Fragment1
}
else if(isFragment2Shown)
{ //When you are in Fragment 2 pressing back button will move to fragment1
Fragment currentFragment = new Fragment1();
isFragment2Shown=false;
isFragment1Shown=true;
FragmentManager frgManager;
frgManager = getFragmentManager();
frgManager.beginTransaction().replace(R.id.content_frame, currentFragment)
.commit();
}
}
Fragment1
Fragment currentFragment = new Fragment2();
MainActivity.isFragment1Shown=false;
MainActivity.isFragment2Shown=true;
frgManager = getFragmentManager();
frgManager.beginTransaction().replace(R.id.content_frame, currentFragment)
.commit();

Categories

Resources