Fragment already added - a bug - android

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?

Related

Android Studio Navigation Drawer fragments overlapping

I've added a Navigation drawer activity to my project and I'm trying to add items as fragments. This is what I have done in the main activity.
fragmentManager = getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.nav_host_fragment, new HomeFragment());
fragmentTransaction.commit();
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item)
{
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
int id = item.getItemId();
if (id == R.id.nav_home)
{
fragmentManager = getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.nav_host_fragment, new HomeFragment());
fragmentTransaction.commit();
}
else if(id == R.id.Shopping_list)
{
fragmentManager = getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.nav_host_fragment, new ShoppingListFragment());
fragmentTransaction.commit();
}
else if(id == R.id.nav_Language)
{
fragmentManager = getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.nav_host_fragment, new FragmentLang());
fragmentTransaction.commit();
}
The default fragment is Home which is working fine and as expected BUT the other fragments are overlapping with the Home Fragment. (The HomeFragment is the only one that's working fine).
I've done something like this inside every Fragment class:
public class ShoppingListFragment extends Fragment{
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View view = inflater.inflate(R.layout.fragment_shopping_list, container,false);
return view;
}
}
I can't see where the mistake is. everything looks good but all other fragments are showing over the HomeFragment.
fragment manager maintains the stack of all the previous fragments that are replaced sometimes the back stack fragments overlap with the fragment we replaced, add this line
fragmentManager.popBackStack();
like this,
fragmentManager = getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.nav_host_fragment, new HomeFragment());
fragmentManager.popBackStack();
fragmentTransaction.commit();
Hope will help. Happy coding :)

Set item on navigation view as selected from fragment

When moving to a different fragment I want the corresponding item in the navigation menu to be highlighted. This should be done from the fragment itself.
Below is the code present in the fragment:
saveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dispName = dispNameET.getText().toString();
myRef.setText(dispName);
//going to another fragment
Fragment fragment = new ListFragment();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_layout, fragment);
fragmentTransaction.commit();
}
});
After this the navigation view shows wrong item as highlighted.
Please help
Your code should look like this
saveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dispName = dispNameET.getText().toString();
myRef.setText(dispName);
//going to another fragment
Fragment fragment = new ListFragment();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_layout, fragment);
fragmentTransaction.commit();
NavigationView navigationView = (NavigationView) getActivity().findViewById(R.id./*id of nav bar*/);
navigationView.setCheckedItem(R.id./*id of menu item to be highlighted*/);
}
});
NavigationView navigationView = (NavigationView) getActivity().findViewById(R.id./*id of nav bar*/);
navigationView.setCheckedItem(R.id./*id of menu item to be highlighted*/);
Put this code in the onClick method or in the beginning of required fragment

Android - Show fragment on resume

I currently have a navigation drawer, which has a few fragments (Home, Help, About) in my activity. On startup it opens up Home. The issue i'm having is that when i go to another fragment such as Help and then proceed to put the phone to sleep and subsequently turn on the phone back on it'll always return to Home instead of help.
I'm quite new to lifecycles but was hoping to get some feedback on how to resume from a different fragment.
EDIT: Provided relevant code
Update: Realised that this happens because i reinit the views on resume.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initializeUI();
}
private void initializeUI() {
fragAbout = new About();
fragHelp = new Help();
fragHome = new MyViewPager();
// Adding fragments to activity
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.main_activity_fraglayout, fragHome);
transaction.commit();
...
}
private void addDrawerItems() {
...
DrawerItemAdapter drawerAdapter = new DrawerItemAdapter(this, R.layout.nav_list_row, drawerItems);
mDrawerList.setAdapter(drawerAdapter);
mDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
switch (position) {
case 0:
...
newFragOnClick(fragHome, "Home");
break;
case 1:
...
newFragOnClick(fragSettings, "Help");
break;
case 2:
...
newFragOnClick(fragAbout, "About");
break;
default:
break;
}
}
});
}
private void newFragOnClick(Fragment frag, String actionBarTitle){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.main_activity_fraglayout, frag);
transaction.commit();
}
Use sharedpreferences to save the current tab position and in onResume() use it to move to the saved position.

Actionbarsherlock navigation_mode_list list not appearing

As My title of the question suggest, I have a SherlockFragmentActivity where I'm using the NavigationMode: NAVIGATION_MODE_LIST
However, I can't see the list to change between the items until I rotate the screen to landscape, and then it appears. And then you can rotate back to portrait to make it show.
How do I get it to show without having to rotate the screen first.
Here is my activity oncreate:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SystemBarTintManager tintManager = new SystemBarTintManager(this);
tintManager.setStatusBarTintEnabled(true);
tintManager.setTintColor(Color.parseColor("#424254"));
tintManager.setNavigationBarTintEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
title = new String[] {"List 1"};
subtitle = new String[]{"List 1 sub"};
icon = new int[]{R.drawable.list_one};
adapter = new NavListAdapter(this, title, subtitle, icon);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
ActionBar.OnNavigationListener navlistener = new OnNavigationListener() {
#Override
public boolean onNavigationItemSelected(int position, long itemId) {
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction();
switch (position) {
case 0:
ft.replace(android.R.id.content, frag1);
break;
case 1:
ft.replace(android.R.id.content, frag2);
break;
case 2:
ft.replace(android.R.id.content, frag3);
break;
}
ft.commit();
return true;
}
};
getSupportActionBar().setListNavigationCallbacks(adapter, navlistener);
}
The solution was to Add the following lines of code just before the navlistener:
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction();
ft.replace(android.R.id.content, frag1);
ft.commit();

Managing Fragments in a navigation drawer

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.

Categories

Resources