FragmentTransaction adding fragment instead of replace - android

I'm building an QR Code Scanner using gms Vision API. The scanner is working properly, but as soon as I try to replace the fragment, it's not getting replaced, it's getting added.
Code to replace:
val manager: FragmentManager? = (context as MainActivity).supportFragmentManager
val transaction: FragmentTransaction? = manager?.beginTransaction()
transaction?.replace(R.id.container, ScannedFragment())
transaction?.addToBackStack(null)
transaction?.commit()
There are no error messsages. The app looks like this then:
Image

I found the solution myself. I had to use a FrameLayout to replace.

Related

NestedFragment navigation With ViewPager2

I'm developing an app which is made of SingleActivity&Fragments.
The project flow is below.
Project flow
The navgraph is below.
Navigation flow
RegisterPhotoFragment has a photo button. If i click the button, it show the CameraOrGalleryBottomSheetDialog by using navigate(actionid).
In the CameraOrGalleryBottomSheetDialog, I can take a photo or get a image url from gallery.
For the process, I'm using setFragmentResultListener in RegisterPhotoFragment and setFragmentResult in CameraOrGalleryBottomSheetDialog.
But the problem is, I can't get the image uri from CameraOrGalleryBottomSheetDialog in RegisterPhotoFragment and I realized that RegisterPhotoFragment is just made by using ViewPager2 in BeginningFragment not navigate(anctionid). So, i didn't use navigate(actionid) to go to the RegisterPhotoFragment.
Therefore, I changed the navigation flow like below.
Second Navigation Flow
I restarted my app and it happened a crash.
java.lang.IllegalArgumentException: Navigation action/destination mypackage:id/action_registerPhotoFragment_to_cameraOrGalleryBottomSheetDialog cannot be found from the current destination Destination(mypackage:id/beginningFragment) label=BeginningFragment class=,mypackage.presentation.ui.beginning.BeginningFragment
because i added the RegisterPhotoFragment res/navigation/navGraph but i didn't use navigate(actionid). If i use naviagte(actionid), I can only see the screen of RegisterPhotoFragment. So, i didn't use it.
Finally, I decided to make a RegisterPhotoNavHostFragment and it has only FragmentContainerView and the Navigation Flow is changed again like below.
Sadly, I thought it works but it didn't. the same crash occured.
How can i make it? is this idea wrong?
Okay, I solved this problem. One thing that i missed was that i have to create the RegisterPhotoNavHostFragment instead of RegisterPhotoFragment when i create the FragmentStateAdapter for ViewPager2 in BeginningFragment.
before
private fun getFragmentsForViewPager2() = arrayListOf(
RegisterPhotoFragment.getNewInstance(),
RegisterNicknameFragment.getNewInstance(),
RegisterGenderFragment.getNewInstance()
)
after
private fun getFragmentsForViewPager2() = arrayListOf(
RegisterPhotoNavHostFragment.getNewInstance(),
RegisterNicknameFragment.getNewInstance(),
RegisterGenderFragment.getNewInstance()
)
the idea works well.

It is possible to show page in own activity in Xamarin.Forms on Android?

I want to navigate between pages be starting and finishing new activity for any new page and show this page in own activity. How to achieve this behavior?
The answer is Yes,you could look at Native Forms.
For ios:
in ios project AppDelegate
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
Forms.Init();
...
UIViewController mainPage = new NotesPage().CreateViewController();
mainPage.Title = "Notes";
_navigation = new AppNavigationController(mainPage);
_window.RootViewController = _navigation;
_window.MakeKeyAndVisible();
return true;
}
For Android:
in Android project your activity ,it convert your page to a fragment,and then you could fill it in your activity:
Android.Support.V4.App.Fragment mainPage = new NotesPage().CreateSupportFragment(this);
SupportFragmentManager
.BeginTransaction()
.Replace(Resource.Id.fragment_frame_layout, mainPage)
.Commit();
On Android Xamarin.Forms navigate among pages by using Fragments.
If you don't like it you may fork Xamarin.Forms and change the code to work the way you want it to work: https://github.com/xamarin/Xamarin.Forms
This will make some packages incompatible with your fork of Xamarin.Forms, which you may need to take under consideration if you intend to use them.
Also if you consider the required time and knowledge this is non-trivial. It is highly unlikely that someone will do that job instead of you and provide you with the plug-in solution.

Android fragment `setEnterTransition` doesn't work

I'm trying to animate the showing of a fragment in a very basic way but it doesn't work:
MyFragment myFragment = (MyFragment) getFragmentManager().findFragmentById(R.id.myFragment);
getFragmentManager().beginTransaction()
.hide(myFragment)
.commit();
Slide slideRight = new Slide(Gravity.RIGHT);
slideRight.setDuration(3000);
Slide slideLeft = new Slide(Gravity.LEFT);
slideLeft.setDuration(3000);
myFragment.setEnterTransition(slideRight);
myFragment.setExitTransition(slideLeft);
then later
getFragmentManager().beginTransaction()
.show(myFragment)
.commit();
But fragment just appears without any transition. I can't figure out why it doesn't animate.
Edit:
I ended up using the fragment support library with setCustomAnimations cause the native library doesn't support animation with relative values.
Also using the new API with setEnterTransition doesn't seem to work properly with show/hide and for some unknown reason worked only with replace which doesn't fit my needs.
setCustomAnimation will do the trick.
FragmentManager.beginTransaction()
.replace(R.id.fragment, new Fragment)
.setCustomAnimations(R.anim.slide_out_left, R.anim.slide_in_right).commit();

How can I use chenupt/SpringIndicator in Fragment

I want to use it in a v4.Fragment to load childFragment, and the SpringIndicator sample code based on MultipleModel.
I tryed to deliver a ChildFragmentManager to ModelPagerAdapter in Fragment follow this:
ModelPagerAdapter adapter = new ModelPagerAdapter(getChildFragmentManager(), new PagerModelManager());
But that not works, nothing displayed on phone's screen.
Actually,The SpringIndicator will works in a Activity.(use getSupportFragmentManager as the arg)
How can I do?Thank you very much.
Sorry,everyBody.That code in question taked effect but not display beacause of background color.So, You can use SpringIndicator in Fragment to load childFragment with:
ModelPagerAdapter adapter = new ModelPagerAdapter(getChildFragmentManager(), new PagerModelManager());
The first arg is getChildFragmentManager() worked for me.

How to use default animations in Android?

I'm trying to use the default animations for the Activity with fragments.. here I found something about it:
Android: using Activity's default animation for Fragments
the problem is: ok, I need (for example) "activityOpenEnterAnimation".. how can I use it?
Using the following code won't work:
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setCustomAnimations(android.R.anim.activityOpenEnterAnimation, android.R.anim.activityOpenExitAnimation);
transaction.replace(R.id.container, fragment)
.addToBackStack(((Object) fragment).getClass().getName())
.commit();
Hints? Thanks! :)
Nowadays, Android documentation clearly recommends not to use resources directly from android.R.*, since every release of the platform has changes on them. Even some resources dissapear from one version to another, so you shouldn't rely on them. On the other hand, lots of resources are private and not available from a developer's code.
The safest (and recommended) way is to simply copy & paste the resources you need (in this case, the animations) from the source code of the Android version you want into your own code, and use them through the regular R.*.
You can browse the Android source code in many ways, as explained in [1].
[1] Where can I find Android source code online?
example of using default android animation when back pressed happen
#Override
public void onBackPressed() {
super.onBackPressed();
overridePendingTransition(android.R.anim.fade_in,android.R.anim.fade_out);
}
for using default animations you should use android.R.anim.ANIMATIONNAME
I managed to get it to work this way:
static public int getResourceIdFromCurrentThemeAttribute(FragmentActivity activity, int attribute){
TypedValue a = new TypedValue();
activity.getTheme().resolveAttribute(attribute, a, false);
return a.resourceId;
}
//This type of fragment will be opened like an activity
static public void openActivityLikeFragment(FragmentActivity activity, BaseFragment fragment, int containerId, String stackRef) {
FragmentManager fm = activity.getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
//The fragment open/close transition should have the same animations as its activity
ft.setCustomAnimations(
getResourceIdFromCurrentThemeAttribute(activity, android.R.attr.activityOpenEnterAnimation),
getResourceIdFromCurrentThemeAttribute(activity, android.R.attr.activityOpenExitAnimation),
getResourceIdFromCurrentThemeAttribute(activity, android.R.attr.activityCloseEnterAnimation),
getResourceIdFromCurrentThemeAttribute(activity, android.R.attr.activityCloseExitAnimation)
);
ft.replace(containerId, fragment);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(stackRef);
ft.commit();
}
This solution is safer than directly referencing a resource, since its referencing an attribute which won't change without some deprecation warnings first.

Categories

Resources