how to make FragmentContainerView activate when prompted - android

Main issue: a fragmentcontainerview works without me wanting it to.
Explanation: I have a fragmentcontainer view in an activity.It is a DialogFragment navigation graph, I want it to only shown when I prompt it but it gets shown when activity is started.
Code in activity xml:
<androidx.fragment.app.FragmentContainerView
android:id="#+id/dialogNavigation"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
app:defaultNavHost="false"
app:navGraph="#navigation/nav_dialog"
tools:layout="#layout/tutorial_dialog_start" />
Setting its visibility gone doesnt help and I couldnt find any other solution
Edit:
Solution 1:
If there's 2 navgraphs: 1 for fragments, 1 for dialogs. Merge them and use actions to navigate to dialogs from specific fragment.
Solution 2:
Create an empty dialog and have it as the first dialog showed in FragmentContainerView, when you want to show the actual dialogs navigate from the empty dialog to the actual dialog

Related

Android: How to show a fragment over parent activity and its button/nav views

I have a main activity that launches a fragment through a fragment transaction. I want the fragment to completely fill the screen, showing no views at all from the parent. However, when I commit the fragment transaction I can still see the bottom nav view of the parent activity as well as it's buttons. I made a little demo app to show what I mean:
The main activity has a yellow background. The "Testclick" button starts a fragment transaction using the code below.
This is the result of the transaction. The red background of the fragment is now visible, but the bottomNavigationView and Buttons remain visible (Which is not desired).
Fragment Transaction
bttn.setOnClickListener {
supportFragmentManager
.beginTransaction()
.replace(R.id.contentview, Frag1())
.addToBackStack(null)
.commit()
}
Main Activity layout
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/contentview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/yellow"
tools:context=".MainActivity">
...
</androidx.constraintlayout.widget.ConstraintLayout>
Your R.id.contentview must be in the background behind the buttons
Ah actually you know what there is a good tool, called LayoutInspector in Tools -> Layout inspector, you can actually see how the layout is set up while your activity is running. In your case the layout of fragment is added inside the layout of activity.
Sorry didnt see the id at first

Unable to find NavController that's inside a DialogFragment

I have a BottomSheetDialogFragment that contains a NavHostFragment like so:
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/add_feeling_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:navGraph="#navigation/add_feeling_graph" />
</LinearLayout>
</layout>
When I try to get the NavController in it's class using either of the following:
activity?.findNavController(R.id.add_feeling_nav_host_fragment)
view.findNavController()
The first option crashes because it cannot find the ID and the second one does finds a parent Nav Controller and uses that.
I have an identical setup for another Fragment however it's not a dialog and it works perfectly. Any ideas to what the issue could be? Thanks
activity?.findNavController(R.id.add_feeling_nav_host_fragment) won't do the job - it will work only if the dialog fragment is active(showing) and it is a part of activity`s UI container - DialogFragment works in other instance of window that is not within the same hierarchy with the root nav graph.
Appropriate way to do it - with NavHostFragment.findNavController(fragment) or ktx extension fragment.findNavController() where fragment is your dialog fragment. The dialog fragment should be showing with its view inflated. The best way to do it - within the dialog.
Navigation graph adjustments may also be required - I cannot tell exactly since there is no code.
Hope it helps.
Well, first of all you should post more code for us to see the whole picture. One small detail is that you dont need neither <layout> and <LinearLayout> in navigation xml. Fragment is just ok. I will suggest you to look at this repository, there is exactly solution you need.
I Hope it helps.

How to navigate from Dialog to Fragment in Navigation Component?

I am trying to navigation from DialogFragment to Fragment in Navigation Component, but getting weird result.
When I navigate from DialogFragment to Fragment, background fragment is changing to target fragment with current dialog on top of it, instead of just moving to target fragment.
Here is the navigation graph.
<navigation
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/home"
app:startDestination="#+id/titleScreen">
<fragment
android:id="#+id/titleScreen"
android:name="com.example.android.navigationadvancedsample.homescreen.Title"
android:label="#string/title_home"
tools:layout="#layout/fragment_title">
<action
android:id="#+id/action_title_to_about"
app:destination="#id/aboutScreen"/>
</fragment>
<dialog
android:id="#+id/aboutScreen"
android:name="com.example.android.navigationadvancedsample.homescreen.About"
android:label="#string/title_about"
tools:layout="#layout/fragment_about">
<action
android:id="#+id/action_aboutScreen_to_register"
app:destination="#id/register" />
</dialog>
<fragment
android:id="#+id/register"
android:name="com.example.android.navigationadvancedsample.formscreen.Register"
android:label="fragment_leaderboard"
tools:layout="#layout/fragment_leaderboard" />
</navigation>
Why I am getting this behavior or how to fix it?
By fixing I mean normal dialog behavior. Say, I have a dialog D on top of a fragment A and move to a fragment B from a button on D, the screen should show B. And when I pop back from B, it should go to previous stage of D on top of A.
Thanks #musooff for filing this bug
This problem was fixed on Navigation 2.1.0-alpha06, along with others dialog inconsistencies like back button when Dialog is popped.
However, update to 2.1.0-beta02 or higher if you can.
You could use
view.getDialog().dismiss();
after navigate to B. But in that way, dialog won't be visible when you came back to A fragment.
If you really want it to be visible, maybe you should try to use Fragment and pretend it to be Dialog. Like in these example with activity link.

Restore activity with the right fragment and state

I have an application with a main menu that when clicked, navigate to different activities.
One of these activities its a Search, with container that i update with many fragments. Its a kind of search, with 3 steps. (Step 1, Step 2, Step 3)
When i go for other activity and back to the Search Activity, the state is lost.
Whats is the best way to restore the activity with the right fragment ?
I have tried android:launchMode="singleInstance" and also intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT or Intent.FLAG_ACTIVITY_CLEAR_TOP) to force one instance of activity, and actually works but is taking time to open the activity for the first time (the app kind of stop works and then start again)
I think i can't just use savedInstanceState() because, each fragment need some information chosen on the previous fragment
Any suggestion ?
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android">
<!--Top bar Menu-->
<include layout="#layout/partials_top_bar"/>
<FrameLayout
android:windowSoftInputMode="adjustNothing"
android:id="#+id/container"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</FrameLayout>
<!--Bottom Bar Menu-->
<include layout="#layout/partials_bottom_bar"/>
</LinearLayout>
When the user choose some action, them i update the actual fragment with
activity.supportFragmentManager
.beginTransaction()
.replace(R.id.container, fragment)
.addToBackStack(null)
.commit()
EDIT: Found a solution. The "delay" / App freeze showed when i open SingleInstance was caused by removing the transition animation of all activities. But only the single instance activity presents this delay. So i'm gonna use this. Thank you so much guys.
You can create a static variable "state" in your activity, could be String, and when you change Fragment, you change de variable value, for example, when you change to the StepOneFragment you put the value to
"step_one", StepTwoFragment -> "step_two", StepThreeFragment -> "step_three", and if you get back you change the variable value depending in what fragment are you on, then in onCreate of SearchActivity, you make a switch in that variable, and depending of the value, you load the desired Fragment.
Hope it helps

How can I use Fragments to create layout in the image displayed

Here is the image screenshot:
My query is how can I implement the Stack layout shown? I have scoured the resource files and most only show how to implement two fragments.
Would anyone please give me any example of how I can create the Stack fragment as shown?
Will appreciate it. Thanks.
If your fragments are closely tied together, just don't run them in separate activities. For the single pane case you can just switch fragments within one activity.
Otherwise, if you do want to separate them between activities, you need to use the onActivityResult() model for propagating results back, and in the dual-pane case "emulate" it by just having the second call onActivityResult() of the first fragment. Note that Fragment.setTargetFragment() includes a request code argument to facilitate this.
I have activity A loading Fragment F1 which loads fragment F2
IMHO, fragments should not load other fragments. Activities load fragments, based upon available screen space. Fragments should neither know nor care whether any other fragment exists in the current activity, or if other fragments are in other activities.
I have F2 calling back to activity A to pop it off of the stack. Should I then be looking at passing a message to F1 to do what it needs to do?
Yes.
What I'm wondering is whether I'm on the right track with regards passing messages back and forwards via the parent activity or is there a more direct way of F1 responding to F2 performing something that requires it to be closed and F1 do what it needs to do.
I would not have F1 even know that F2 exists, or vice versa. When the user does something in F1 that should result in a major context shift (e.g., display some other fragment/activity), F1 should let the hosting activity know, perhaps via a listener interface registered with F1 (to support multiple possible hosting activities). The activity would then arrange for F2 to appear, either in its own activity or in another activity. Similarly, when F2 wraps up, it would let its hosting activity know via a listener interface, and that activity can route control back to the appropriate spot.
I am somewhat skeptical of your whole "F2 performs an action which should result in it being closed" approach, unless F2 is a DialogFragment.
One possible solution is given below
Please tweak width and heights according to the use case
For Landscape use
<LinearLayout android:orientation="horizontal" ..>
<fragment android:name="com.example.FragmentA"
android:id="#+id/fa"
android:layout_width="xdp"
android:layout_height="match_parent" />
<LinearLayout android:orientation="vertical" ...>
<fragment android:name="com.example.FragmentB"
android:id="#+id/fb"
android:layout_width="ydp"
android:layout_height="wrap_content" />
<fragment android:name="com.example.FragmentC"
android:id="#+id/fc"
android:layout_width="zdp"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
For Portrait view use
<LinearLayout android:orientation="vertical" ..>
<fragment android:name="com.example.FragmentA"
android:id="#+id/fa"
android:layout_width="match_parent"
android:layout_height="Xdp" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<fragment android:name="com.example.FragmentB"
android:id="#+id/fb"
android:layout_width="ydp"
android:layout_height="wrap_content" />
<fragment android:name="com.example.FragmentC"
android:id="#+id/fc"
android:layout_width="wrap_cotent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>

Categories

Resources