I have use .replace() for replace a old Fragment with a new, but in this moment i do no how use the same of .replace() by a Fragment to a mapsFragment.
Ideas?!
I can use replace? if i can' t use it, what I can use?
This is my code in this moment. (the .replace() don' t work)
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getFragmentManager();
mapsFragment fragM = null;
Fragment frag = null;
switch (position) {
case 0: //Home
mTitle = "Maps";
fragM = new mapsFragment();
break;
case 1: //Query utente
mTitle = "Section 2";
break;
case 2: //Query Amministratore
mTitle = "Section 3";
break;
}
if (position != 3) {
if(position==0){
fragmentManager.beginTransaction()
.replace(R.id.container, fragM)
.commit();
}else {
fragmentManager.beginTransaction()
.replace(R.id.container, frag)
.commit();
}
I have find the solution:link where i have found it
This is the code in particular:
if(position==0){
FragmentTransaction mTransaction = getSupportFragmentManager()
.beginTransaction();
SupportMapFragment mFRaFragment = new mapsFragment();
mTransaction.replace(R.id.container, mFRaFragment);
mTransaction.commit();
}else {
Related
I tried many methods to save instances but I am confused how to save instances in backstack because no one described how to use it if there multiple fragments.my code in mainactivity below:
bottomNavigationView.setOnItemSelectedListener(item -> {
switch (item.getItemId()){
case R.id.home:
loadFragment(new HomeFragment(),0);
break;
case R.id.create:
loadFragment(new CreateFragment(),1);
break;
case R.id.profile:
loadFragment(new ProfileFragment(),1);
break;
}
return true;
});
public void loadFragment(Fragment fragment,int flag){
FragmentManager fragmentManager=getSupportFragmentManager();
FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
if(flag==0){
fragmentTransaction.add(R.id.frame_layout,fragment);
fragmentManager.popBackStack(ROOT_FRAGMENT_TAG,FragmentManager.POP_BACK_STACK_INCLUSIVE);
fragmentTransaction.addToBackStack(ROOT_FRAGMENT_TAG);
}
else {
fragmentTransaction.replace(R.id.frame_layout,fragment);
fragmentTransaction.addToBackStack(null);
}
fragmentTransaction.commit();
}
I suggest you to make your Fragment Classes Singleton.
private static MyFragment fragment;
public static MyFragment getInstance() {
if (fragment == null) {
fragment = new MyFragment();
}
return fragment;
}
then use getInstance() method to instantiate your fragment
I have 3 and more fragments and I want to access them with the drawer.
So that when I click on "Profile" the current fragment(i.e. Home) should hide and "Profile" fragment should show and vice versa..
Right now its working with "replace fragment" but,
Instead of replace I want to show/hide them when I click on the drawer button.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//my coding
replace(new HomeFragment());
init();
}
private void init() {
mDrawer = (FlowingDrawer) findViewById(R.id.drawerlayout);
iv_Menu = findViewById(R.id.iv_Menu);
ll_Home = findViewById(R.id.ll_Home);
ll_Profile = findViewById(R.id.ll_Profile);
ll_Setting = findViewById(R.id.ll_Setting);
ll_Share = findViewById(R.id.ll_Share);
ll_Logout = findViewById(R.id.ll_Logout);
iv_Menu.setOnClickListener(this);
ll_Home.setOnClickListener(this);
ll_Profile.setOnClickListener(this);
ll_Setting.setOnClickListener(this);
ll_Share.setOnClickListener(this);
ll_Logout.setOnClickListener(this);
}
#Override
public void onClick(View view) {
switch (view.getId()){
case R.id.iv_Menu:
mDrawer.openMenu(true);
break;
case R.id.ll_Home:
replace(new HomeFragment(),"Home");
mDrawer.closeMenu(true);
break;
case R.id.ll_Profile:
replace(new ProfileFragment(),"Profile");
mDrawer.closeMenu(true);
break;
case R.id.ll_Setting:
startActivity(new Intent(this, SimplPreach.class));
mDrawer.closeMenu(true);
break;
case R.id.ll_Share:
Toast.makeText(this, "Share.", Toast.LENGTH_SHORT).show();
mDrawer.closeMenu(true);
break;
case R.id.ll_Logout:
Toast.makeText(this, "Logout.", Toast.LENGTH_SHORT).show();
mDrawer.closeMenu(true);
break;
}
}
private void replace(Fragment fragment, String s) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fl_Main,fragment);
transaction.addToBackStack(s);
transaction.commit();
}
private void replace(Fragment fragment) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fl_Main,fragment);
transaction.commit();
}
I have been searching from hours but nothing is working,
How can I use show hide instead of replace ..
Please help me..
FragmentTransaction has the following methods you can use.
show(Fragment fragment)
hide(Fragment fragment)
add(int containerViewId, Fragment fragment, String tag)
And I think you don't need to call transaction.addToBackStack(s) in your case.
My application had a bottom navigation bar which has 5 tabs.
So according to these tabs, I have 5 fragments
When I click on the tab, the fragment changed according to that tab.
I can switch fragment by using the method beginTransaction().replace...
I dont want the fragment to be destroyed and recreated again each time I switch tabs, so my solution is sth like this
//I init 5 fragments
Fragment1 frag1 = new Fragment1();
Fragment2 frag2 = new Fragment2();
Fragment3 frag3 = new Fragment3();
Fragment4 frag4 = new Fragment4();
Fragment5 frag5 = new Fragment5();
//When I click on tab, for example tab1, I hide all fragments except tab1
//hide all fragments
getSupportFragmentManager()
.beginTransaction()
.hide(fragment1) //Fragment2, 3, 4, 5 as well
.commit();
//show fragment 1
getSupportFragmentManager()
.beginTransaction()
.show(fragment1)
.commit();
It works very well, but the problem is sometimes 2 fragments show at once time (I dont know why because I hide all fragments)
Any other way to achieve that? Switch fragment without destroying it and creating it again.
for adding fragment I make this code for my project, hope it will be help.
public static void replaceFragment(Fragment fragment, FragmentManager fragmentManager) {
String backStateName = fragment.getClass().getName();
String fragmentTag = backStateName;
Fragment currentFrag = fragmentManager.findFragmentById(R.id.frame_container);
Log.e("Current Fragment", "" + currentFrag);
// boolean fragmentPopped = fragmentManager.popBackStackImmediate(backStateName, 0);
int countFrag = fragmentManager.getBackStackEntryCount();
Log.e("Count", "" + countFrag);
if (currentFrag != null && currentFrag.getClass().getName().equalsIgnoreCase(fragment.getClass().getName())) {
return;
}
FragmentTransaction ft = fragmentManager.beginTransaction();
// if (!fragmentPopped) {
ft.replace(R.id.frame_container, fragment);
ft.addToBackStack(backStateName);
ft.commit();
// }
currentFrag = fragmentManager.findFragmentById(R.id.frame_container);
Log.e("Current Fragment", "" + currentFrag);
}
hope this will be help you, and use this method in entire project for replacing fragment.
Using ViewPager with FragmentPagerAdapter suits for you in this case.
Then use ViewPager#setOffsetPageLimit(5). This will help you show/hide your fragments without recreating it again.
Follow this tutorial
Let try it, then tell me if your problem is solved or not. ;)
you don't have to need to hide the fragment just replace the fragment like this method:
public void setFragment(Fragment fragmentWhichYouWantToShow) {
fm = getSupportFragmentManager();
ft = fm.beginTransaction();
ft.replace(R.id.container, fragmentWhichYouWantToShow);
ft.commit();
}
Try to make it in a singe transaction.
protected void showAsRootFragment(Fragment fragment, #NonNull String tag) {
FragmentManager supportFragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = supportFragmentManager.beginTransaction();
if (supportFragmentManager.getFragments() != null) {
for (Fragment attachedFragment : supportFragmentManager.getFragments()) {
if (attachedFragment != null && !tag.equals(attachedFragment.getTag())) {
transaction.hide(attachedFragment);
attachedFragment.setUserVisibleHint(false);
}
}
}
if (!fragment.isAdded()) {
transaction.add(R.id.frame_container, fragment, tag);
fragment.setUserVisibleHint(true);
} else {
transaction.show(fragment);
fragment.setUserVisibleHint(true);
}
transaction.commit();
}
So here's the code:
private void selectItem(int position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = new HomeFragment();
break;
case 1:
fragment = new DoctorFragment();
break;
case 2:
fragment = new HospitalFragment();
break;
case 3:
fragment = new SpecialClinicFragment();
break;
case 4:
fragment = new PharmacyFragment();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
//the parameter "fragment" in this line of code gives an error message.
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
getActionBar().setTitle(mNavigationDrawerItemTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
} else {
Log.e("MainActivity", "Error in creating fragment");
}
It seems like I haven't properly initialised fragment instance.
The error message was "Wrong 2nd argument type" but I'm pretty sure I put in the right parameter.
Problem is not with the argument.You have used Fragment from
android.support.v4 library but you are making transaction on android.app.fragment.
Solution:
import android.app.fragment instead of android.support.v4.fragment
Because you cannot mix up with support.v4 library and android.app.*
I have 4+ Fragments (android.support.v4.app.Fragment).
Fragment f1, f2, f3, f4;
int F1 = 1; int F2 = 2; int F3 = 3; int F4 = 4;
protected void onCreate(Bundle savedInstanceState)
{
//...
f1 = new Fragment();
f2 = new Fragment();
f3 = new Fragment();
f4 = new Fragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.fl_root, f1)
.add(R.id.fl_root, f2)
.add(R.id.fl_root, f3)
.add(R.id.fl_root, f4)
.commit();
setFragment(F1);
}
public void setFragment(int fragment)
{
switch (fragment)
{
case F1:
if (!f1.isVisible()) {
getSupportFragmentManager().beginTransaction()
.setCustomAnimations(R.anim.rtol, R.anim.ltor, 0, 0)
.show(f1)
.hide(f2)
.hide(f3)
.hide(f4)
.commit();
}
break;
case F2:
if (!f2.isVisible()) {
getSupportFragmentManager().beginTransaction()
.setCustomAnimations(R.anim.rtol, R.anim.ltor, 0, 0)
.show(f2)
.hide(f1)
.hide(f3)
.hide(f4)
.commit();
}
break;
case F3:
if (!f3.isVisible()) {
getSupportFragmentManager().beginTransaction()
.setCustomAnimations(R.anim.rtol, R.anim.ltor, 0, 0)
.show(f3)
.hide(f1)
.hide(f2)
.hide(f4)
.commit();
}
break;
case F4:
if (!f1.isVisible()) {
getSupportFragmentManager().beginTransaction()
.setCustomAnimations(R.anim.rtol, R.anim.ltor, 0, 0)
.show(f4)
.hide(f1)
.hide(f2)
.hide(f3)
.commit();
}
break;
}
After setFragment to first, second and so on (1->2->3->4) rtol (translate from right to left) animation works, and it's fine.
But after going back, using setFragment (4->3->2->1), there are still rtol animation, instead of correct ltor(translate from left to right).
What I'm doing wrong, and what is the solution?
Actually there are 20+ Fragments in Single Activity in my Project.
I solved this animation problem + OutOfMemory (because of 20+ fragments added and hided).
A little bit code:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (!back)
ft.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left);
else
ft.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right);
switch (fragment)
{
case F1:
ft.replace(R.id.fl_root, new F1(), String.valueOf(F1));
break;
//...
}
Slide Animation here
The setCustomAnimations method takes one anim for entering and one for exiting a fragment so even if you go back, you are entering one of these fragments.
So you have to take a look at the fragment you are coming from and switch the animations.
Edit:
Maybe like this untested
int lastFragment;
public void setFragment(int fragment)
{
FragmentTransaction ft = getSupportFragmentManager.beginTransaction();
if(fragment > lastFragment) {
ft.setCustomAnimations(R.anim.rtol, R.anim.ltor, 0, 0);
} else {
ft.setCustomAnimations(R.anim.ltor, R.anim.rtol, 0, 0);
}
switch (fragment)
{
case F1:
if (!f1.isVisible()) {
ft
.show(f1)
.hide(f2)
.hide(f3)
.hide(f4)
.commit();
}
break;
case F2:
if (!f2.isVisible()) {
ft
.show(f2)
.hide(f1)
.hide(f3)
.hide(f4)
.commit();
}
break;
case F3:
if (!f3.isVisible()) {
ft
.show(f3)
.hide(f1)
.hide(f2)
.hide(f4)
.commit();
}
break;
case F4:
if (!f1.isVisible()) {
ft
.show(f4)
.hide(f1)
.hide(f2)
.hide(f3)
.commit();
}
break;
lastFragment = fragment;
}