I have FrameLayout element in my MainActivity's layout, what is used as "connection point" for multiple type of Fragments.
View:
<FrameLayout
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Fragment replace:
Fragment fragment = new CoursesFragment();
getFragmentManager().beginTransaction().replace(R.id.main_content, fragment).commit();
Now I'm at the situation I need change main_content directly from CoursesFragment (fragment replaces own view). What is best approach to do this? Is it safe? I can reach MainActivity's context and change it, but I don't know if it's correct way.
I don't know what your View is, but the simplest approach is to provide both Views inside their own ViewGroup, while setting 'the other view' on setVisibility(View.GONE). If you need to switch, just set the first shown View to View.GONE, and the second to View.VISIBLE.
This way you don't have to hack around with the Activity's context, or Fragment Managers hide and show methods.
Related
I have a fragment with constraints that I want to preserve
<fragment
android:id="#+id/fr_test"
android:name="com.test.FragmentTest"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
I use transactions to hide/show it and all . works fine
fm.beginTransaction().hide(mainActivity.fr_test).commit()
fm.beginTransaction().show(mainActivity.fr_test).commit()
I use transactions to recreate fragment keeping the same container to use the same constraints
fm.beginTransaction().replace(R.id.mainActivity.fr_test, FragmentTest).commit()
But if now I try to hide/show the fragment with the same references as before it does nothing. I suppose that references are lost but I don't know how to find them. I tried to save the reference like this:
fragRef = FragmentTest()
viewsManager.fm.beginTransaction().replace(R.id.fr_test, fragRef).commit()
and then use:
fm.beginTransaction().hide(mainActivity.fragRef).commit()
fm.beginTransaction().show(mainActivity.fragRef).commit()
but still does the same.
What I'm doing wrong?
When you call replace, he calling remove(fragment) and after call add(int, fragment, string). I think that you should use add method instead replace and control your UI using hide and show
In my App, an Activity having a layout xml (first page) inflates onCreate method. On some event(like button click), i want to use Fragment class, and inflate layout xml via Fragments, on the above said layout xml as a container. like below , is my layout xml(first page).
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button ... . >
</FrameLayout>
On Button click, i want to use Fragments within the same Layout container. So i use below code in Activity (on button click).
FragmentManager fManager= getFragmentManager();
FragmentTransaction fTransaction = fManager.beginTransaction();
MyFragment frag = new MyFragment();
fTransaction.replace(R.id.container,frag);
fTransaction.commit();
Now, new layout via Fragment is visible but the old layout is also in the background and visible.
I don't want to use Fragments from the very first layout, as i am doing.
I want to inflate a layout xml first, then on some event, use Fragments layout, and again , from Fragments , i want to switch to Layout xml, means vice-a-versa.
like,
Layout xml inflate via setContentView() -> layout via Fragments -> Layout xml inflate via setContentView()
How to hide or make invisible layout xml (first page) when Fragment layout gets inflates and vice-a-versa ?
If the fragment covers the whole screen, you can set the background of the fragment a solid color.
I have a view pager that has a page for each subject in an array (English, Maths, Science, etc). The fragments in the view pager are all created from the same XML file. These fragments then have fragments added inside of them.
As all the parents inflate from the same XML file, I can not specify which fragment I want to add the child fragment to. I was wondering if their was a way to do this - Narrow the scope of the id maybe??
I think you want to implement multiple fragments with the capability to manipulate them depending on user selections. There is Google link Fragments
Review these code on that web page:
The many samples of Fragment and FragmentTransaction
Look at method showDetails in class TitlesFragment, for example.
If you want a working sample, look at Working with Android Fragments. Snippet from the webpage:
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent">
<fragment
android:id="#+id/headFrag"
android:name="com.intertech.HeaderFrag"
android:layout_width="wrap_content"
android:layout_height="match_parent"/>
<fragment
android:id="#+id/bodyFrag"
android:name="com.intertech.BodyFrag"
android:layout_width="wrap_content"
android:layout_height="match_parent"/>
</LinearLayout>
And the code
...
FragmentManager fragmentManager = getFragmentManager ();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction ();
// work here to change Activity fragments (add, remove, etc.).
fragmentTransaction.add (R.id.myFrame, myFrag);
fragmentTransaction.commit ();
From above, notice there are 2 fragments in the layout. And fragmentTransaction.add method should specify parent container in R.id form.
Someday I may want/need to implement this. So far I implemented show/hide Layouts instead (not regretting it), and they can have IDs for me to manipulate.
Have fun and keep us posted, Tommy Kwee.
First. I suggest you to try to avoid child fragment, if you really doesn't have very good reason to use them.
But I don't understand where is problem. I don't see any problem if more fragment use the same XML for the inflate. You can call setArguments() on all parent fragment and put here some Bundle which can be used to recognize which fragment it is inside of it by getArguments().
I have a navigation bar in my app, the thing is that I want the navbar to be available in all activities. I suppose that I have to set contentView two times, but that doesn't work, of course.
I've been looking at and but I dont get it to work. I have a super class, can I set this second layout from my super class?
You should include the nav bar via <include> tag from the other layouts. Setting the content layout twice will not work, as Android is in the callbacks basically always using what the user has told last. So
setContentLayout(R.layout.nav);
setContentLayout(R.layout.main);
will result in only the main layout being used.
Have a look at this article which gives an example of using the include tag.
You can extend standard activities (Activity, ListActivity, etc.. if you use any others) and use them as a base for including a nav_bar.
For example:
Define a layout with nabar like this
<LinearLayout
...
android:orientation="vertical"
>
<YourNavBarComponent
...
/>
<FrameLayout
android:id="#+id/nav_content"
...
>
// Leave this empty for activity content
</FrameLayout>
</LinearLayout>
This will be your base layout to contain all other layouts in the nav_content frame.
Next, in create a base activity class, and do the following:
public abstract class NavActivity extends Activity {
protected LinearLayout fullLayout;
protected FrameLayout navContent;
#Override
public void setContentView(final int layoutResID) {
fullLayout= (LinearLayout) getLayoutInflater().inflate(R.layout.nav_layout, null); // Your base layout here
navContent= (FrameLayout) fullLayout.findViewById(R.id.nav_content);
getLayoutInflater().inflate(layoutResID, navContent, true); // Setting the content of layout your provided in the nav_content frame
setContentView(fullLayout);
// here you can get your navigation buttons and define how they should behave and what must they do, so you won't be needing to repeat it in every activity class
}
}
And now, when you create a new activity, where you need a nav bar, just extend NavActivity instead. And your nav bar will be placed where you need it, without repeating it in every layout over and over again, and polluting the layouts (not to mention repeating a code to control navigation in every activity class).
Try merging layouts, as described on Android Developers Blog.
Suppose I have 2 XML files and my activity will setContentView the appropriate one based on some button press from the user. Is it possible to change the transition animation for the changing of content view?
So far I see super.overridePendingTransition() which is suitable for starting new activities, however my example does not start a new activity, it just changes the layout in the current one.
Mathias Lin has explained it very well.
You can always use default stock animations supplied by Android framework.
Heres an example code:
boolean isFirstXml=evaluatingConditionFunction();
LayoutInflater inflator=getLayoutInflater();
View view=inflator.inflate(isFirstXml?R.layout.myfirstxml:R.layout.myseconxml, null, false);
view.startAnimation(AnimationUtils.loadAnimation(this, android.R.anim.slide_out_right));
setContentView(view);
Call this from any of your activity which holds your Parent View.
For custom animations you can visit developer docs. Heres the documentation link.
Yes, you can apply an animation on almost any view you like. Just via view.startAnimation(animation);
Take the outer viewgroup of your respective layout (content view) and apply the animation to it. Depending what kind of animation you want to do, it might make sense to inflate/load both layouts but hide one of them and then swap. Please specify what kind of transition you have in mind.
For example: if you do an alpha transition, you would run the alphaAnimation on the current layout, when when the animation ends (AnimationListener), you set the content view to the new layout, and fade the content back in, via another alphaAnimation.
A better solution is using ViewFlipper: it is a FrameLayout, that can do animations when changing the views.
<ViewFlipper
android:id="#+id/[your_id_here]"
android:inAnimation="..."
android:outAnimation="..."
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RelativeLayout
<!--Your first layout -->
</RelativeLayout>
<RelativeLayout
<!--Your second layout -->
</RelativeLayout>
</ViewFlipper>
Then, switch the views with setDisplayedChild(int) or showNext() or showPrevious. If you want to have different animation for left and right movement, you have to set inAnimation and outAnimation in the code before transition.
More complete example is here.