Android Show Dialog Fragment from SharedElement of Activities - android

I want to show a Dialogfragment that appear from a SharedElement of my Activity. I tried SharedElementTransition and that not working. Here is the code:
FragmentManager fm = this.getSupportFragmentManager();
AddHistoryFragment mAddHistoryFragment = new AddHistoryFragment();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mAddHistoryFragment.setSharedElementReturnTransition(TransitionInflater.from(
this).inflateTransition(R.transition.change_image_trans));
mAddHistoryFragment.setExitTransition(TransitionInflater.from(
this).inflateTransition(android.R.transition.fade));
mAddHistoryFragment.setSharedElementEnterTransition(TransitionInflater.from(
this).inflateTransition(R.transition.change_image_trans));
mAddHistoryFragment.setEnterTransition(TransitionInflater.from(
this).inflateTransition(android.R.transition.fade));
fm.beginTransaction().add(mAddHistoryFragment,"add History")
.addSharedElement(ivAddExpense, ivAddExpense.getTransitionName()).commit();
}else {
mAddHistoryFragment.show(fm, "History");
}
Thanks

Sadly it won't work. Shared element transitions only work with replace fragment transaction, but DialogFragment.show() uses add transaction.
Also, see this question, maybe its solution will work for you
Android - Shared Element Transition In Dialog

Related

DialogFragment shows only once -

So i'm having one dialog that i'm trying to show from an Activity
this activity has a navigation graph (JETPACK)
for now i can show this popup only once if i'm in my Activity
then if i close the activity and come back again to it, it's won't show the Dialog because the state of the activity is already saved. and i'm using commitAllowingStateLoss to commit this dialog fragment if i use commit it's crashing. i searched everywhere in stackoverflow couldn't find a single solution for this problem.
code of how im showing the fragment:
public void show(Context context) {
FragmentManager fragmentManager = ((AppCompatActivity) context).getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment prev = fragmentManager.findFragmentByTag(TAG_DIALOG);
if (prev != null) {
fragmentTransaction.remove(prev);
}
fragmentTransaction.add(this, TAG_DIALOG);
fragmentTransaction.commitAllowingStateLoss();
}
Please show how you open the fragment.
Do you save anything when the activity closes? I can only imagine problems with saving the actual fragment instance, but it's all guess work without seeing any code.

Dismissing dialog and showing new one shortly shows underlying fragment before opening new dialog

I currently have one fragment that shows dialogfragment, and when I press the button on dialogfragment, I want to show another dialogfragment. In my first dialog fragment I have following method:
fun showSecondDialog() {
dismiss()
SecondDialog().showDialog(targetFragment!!)
}
showDialog() looks like this:
fun showDialog(fragment: Fragment) {
val fragmentManager = fragment.fragmentManager
val ft = fragmentManager!!.beginTransaction()
val prev = fragmentManager.findFragmentByTag(getName())
if (prev != null) {
ft.remove(prev)
}
ft.addToBackStack(null)
setTargetFragment(fragment, 0)
show(ft, getName())
}
The problem is, that dismissing dialog works immediately, but before the new dialog is shown there is a gap, where my underlying fragment is fully visible and this causes an undesirable flicker.
How to show second dialog immediately, or how to know when it's opened, so I could close the first one?
I am also having this same problem, but you can try a workaround like this if it works according to your requirement :
fun showSecondDialog() {
SecondDialog().showDialog(targetFragment!!)
Handler().postDelayed({ dismiss() }, 1000)
}
Google recommends all the fragment inflate, replace, dismiss...should be done in the parent activity and no fragment should know anything about any other fragment. That way fragments can be reused like they were initially designed to.

How to replace fragment properly using navigation drawer

I am using navigation drawer and it is simple to use. I am not providing the complete code but providing you detail which could be easy for you to understand my problem. I am using fragments these are about 8 in numbers and I am replacing them with one an other. But here comes a problem
I am replacing them on click event of the navigation drawer. but there are two main problems
After replacement , I can see the previous fragment in the background. does replace method just call the new fragment over it ? if yes then what should I do to old fragment not be visible in the background of my new fragment.
When I click navigation drawer Item , it loads the specific fragment successfully. but keeping in that fragment when I click to that specific item again it loads this fragment again and again. For example if drawer item num 3 opens fragment MyBook , then by clicking item num three 2 or many times would open fragment that much time.
So please some one answer me how to cure my app for such kind of actions which I described above.
I tried like this. Its working fine me
FragmentManager frgmanager = getFragmentManager();
frgmanager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
FragmentTransaction frgTransaction = frgmanager.beginTransaction();
if(subitem.equalsIgnoreCase("subitem")){
Frag1 frg1 =new Frag1(mCtx);
frgTransaction.replace(R.id.inflate_layout, frg1);
}else if(subitem1.equalsIgnoreCase("subitem1")){
Frag2 frg2 =new Frag2(mCtx);
frgTransaction.replace(R.id.inflate_layout, frg2);
}else{
Frag2 frg3 =new Frag3(mCtx);
frgTransaction.replace(R.id.inflate_layout, frg3);
}
frgTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
frgTransaction.commit();
you can use addtobackstack in fragmentstranstion object.like
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.bodyfragment, new AnotherFragment());
transaction.addtoBackStack(null).commit();
Use replace-method of FragmentTransaction instead of add (http://developer.android.com/guide/components/fragments.html#Transactions)
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.bodyfragment, new AnotherFragment());
transaction.commit();
To avoid re-instantiating the fragment, keep track of the current open fragment and only do a fragment transaction, if we next-to-be-opened fragment is a different one than the current.
This may achieved like the following:
class MyActivity ... {
private String currentFragment;
private void openNewFragment(Fragment fragment) {
String newFragment = fragment.getClass().getSimpleName();
if (newFragment.equals(currentFragment)){
// new fragment already shown
return;
}
// Fragment transaction etc here:
}
}
Note that this only compares fragments based in their class name. Sometimes this might not be unique, e.g. if there is a DetailFragment class which displays information about an entity. Which entities details to show may depend on intent arguments.
The above code however will then prevent opening DetailFragment for Entity=1 if currently details for Entity=2 are shown. For these scenarios the information about the fragment kept needs to be extended (e.g. storing a Reference or WeakReference to the fragment instance itself).

android lollipop - setentertransition() for fragment not working properly on exiting

While replacing fragment, I am using Slide animation available for android lollipop version. It works as expected for this particular replacement, but on pressing back button it first pops back current fragment & then reverse of enter animation (slide out) is executed.
private void replaceContentFrameByFragment(Fragment replaceBy, String replaceByFragmentTag) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Slide slide = new Slide(Gravity.BOTTOM);
slide.setDuration(1000);
replaceBy.setEnterTransition(slide);
}
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, replaceBy, replaceByFragmentTag);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commitAllowingStateLoss();
}
So, how to force fragment to pop back only after reverse animation of slide is finished? I noticed that activity has method finishAfterTransition() provided. Is there something similar for frgament?
I had the same issue, onReturn from Fragment B -> A, Fragment B seem to be doing an extra slide transition. To get around it, I put in a fade transition for setReturnTransition() of a shorter time than the slide which looks quite good (as it dissolves into previous fragment). The code for this is:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Slide slideRight = new Slide(Gravity.RIGHT);
slideRight.setDuration(200);
fragment.setEnterTransition(slideRight);
Fade fade = new Fade();
fade.setDuration(100);
fragment.setReturnTransition(fade);
}
I was having the same issue with roughly the same pattern and was able to get around it by posting my fragments transition:
new Handler().post(new Runnable() {
#Override
public void run() {
page.setEnterTransition(new Slide());
getFragmentManager()
.beginTransaction()
.replace(R.id.root_layout, page, "current")
.commit();
}
});
Not sure why this resolves the issue (or if this is the absolute correct solution), but it worked for me.

Separated Back Stacks for Tabs with Fragments in Android

Since Tab Activity is deprecated I'm trying to implement tabs with fragments. As you can see in the lots of StackOverFlow questions back stack is an issue when you work with fragments and which has its own back stack.
So the thing I'm trying to do is, there is a fragment in each tab and this fragment can call another fragment within the same tab and its also the same for the other tabs.
Since there is only one activity then there is only one back stack for whole application. So I need to create my custom back stack which is separated for each tab. It's also the same common idea in the other questions. I need to find a way to create custom back stack but I couldnt find any example to take a look.
Is there any tutorial or any example piece of code doing something similar ? Thanks in advance.
There is a backstack for the whole application, but there is also a backstack for fragments.
Perhaps have a read of this:
http://developer.android.com/guide/components/fragments.html#Transactions
When you perform a fragment transaction (add, replace or remove), you can add that transaction to the backstack.
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragmentContainer, fragment);
ft.addToBackStack(null);
ft.commit();
And now when you press back, the latest fragment will be 'popped' from the fragment backstack.
You could also override the onBackPressed(), and manage your fragment backstack there. (I'm currently having trouble trying to work out how to do this efficiently).
Anyway, there are several calls available from the FragmentManager to do with the backstack. The most useful to me being:
FragmentManager.getBackStackEntryCount()
and
FragmentManager.PopBackStack()
Sorry for late answer, but this might help somebody. I have added functionality like this in my project. I used fragment tabhost to add backstacks within it. Main logic will remain same in others.
Basically I took,
Stack<String> fragmentStack = new Stack<>();
boolean bBackPress = false;
String strPrevTab;
FragmentTabHost tabHost;
strPrevTab = "tag"; // Add tag for tab which is selected by default
tabHost.setOnTabChangedListener( new TabHost.OnTabChangeListener() {
#Override
public void onTabChanged( String tabId ) {
if ( !bBackPress ) {
if ( fragmentStack.contains( tabId ) ) {
fragmentStack.remove( tabId );
}
fragmentStack.push( strPrevTab );
strPrevTab = tabId;
}
}
} );
#Override
public void onBackPressed() {
if ( fragmentStack.size() == 0 ) {
finish();
} else {
strPrevTab = fragmentStack.pop();
bBackPress = true;
tabHost.setCurrentTabByTag( strPrevTab );
bBackPress = false;
}
}
Hope this helps!

Categories

Resources