I've got an activity in which there are 2 fragments which changes basing on a button click.
I'd like to show an animation when the replacement appens, so i searched for the code and here's what i concluded:
public void displayView(int page){
switch (page){
case 1:
FragmentHome fragmentHome = new FragmentHome();
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment, fragmentHome)
.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out).commit();
break;
case 2:
FragmentHomeBack fragmentHomeBack = new FragmentHomeBack();
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment, fragmentHomeBack)
.setCustomAnimations(android.R.anim.accelerate_decelerate_interpolator, android.R.anim.anticipate_interpolator).commit();
break;
}
}
I don't know why but the animations don't works, the new fragment just replace the other without animation.
Here's the activity layout code:
<RelativeLayout 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/activity_master"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="#dimen/space10"
tools:context="context">
<include
android:id="#+id/ll_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="#dimen/space5"
android:orientation="vertical"
android:layout_marginLeft="#dimen/space5"
android:layout_marginRight="#dimen/space15"
layout="#layout/menu"
android:layout_alignParentTop="true"
android:layout_above="#+id/imageView" />
<FrameLayout
android:id="#+id/fragment_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="#id/ll_left">
</FrameLayout>
<ImageView
app:srcCompat="#drawable/xlink"
android:id="#+id/imageView"
android:layout_width="150dp"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:scaleType="fitEnd"
android:layout_height="70dp" />
The frame layout "fragment_holder" is where the Fragments are.
Thanks to everybody!
That should do the trick buddy. I have the same code and it works well.
getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(android.R.anim.fade_in,android.R.anim.fade_out)
.replace(R.id.layout_container, fragment)
.commit();
But..
I see what is the difference in our code. Try setting customAnimations before replace to see what happens.
And I have a suggestion to improve your code. In your "if" or "switch" statement set the fragment like
Fragment fragment;
if(page==0){
fragment = new MyFragment();
}else{
fragment = new MySecondFragment();
}
then you only have this code once
getChildFragmentManager()
.beginTransaction()
.setCustomAnimations(android.R.anim.fade_in,android.R.anim.fade_out)
.replace(R.id.layout_container, fragment)
.commit();
Related
So I'm working in Fragments that has 2 Fragments in it. take a look at the image below:
The first fragment that shows the list of the inventory is named fragment_purchase_item_list and on the right side is the fragment_purchase_list
What I want to do is when I clicked SCAN from the toolbar on the right fragment, fragment_qrscan will replace fragment_purchase_item_list. Like this image below:
Can someone please see and check why my code is not working? Thanks!
PurchaseListFragment.java
<-- start of code snippet -->
#Override
public void onClick(View v) {
int id = v.getId();
switch (id){
case R.id.btn_paypurchasetransaction:
Fragment chargeFragment = new ChargeFragment();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.customersales_content, chargeFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
break;
case R.id.layout_transaction_qrcode:
// Toast.makeText(getActivity(), "Scan Item", Toast.LENGTH_SHORT).show();
Fragment scanQRCodeFragment = new QRScanFragment();
FragmentManager fragmentManager1 = getFragmentManager();
FragmentTransaction fragmentTransaction1 = fragmentManager1.beginTransaction();
fragmentTransaction1.replace(R.id.inventory_fragment, scanQRCodeFragment);
fragmentTransaction1.addToBackStack(null);
fragmentTransaction1.commit();
break;
case R.id.layout_transaction_new:
Toast.makeText(getActivity(), "New Transaction", Toast.LENGTH_SHORT).show();
break;
}
}
<-- end of code snippet>
fragment_sales.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragments.SalesFragment"
android:orientation="horizontal"
android:id="#+id/customersales_content">
<fragment
android:id="#+id/inventory_fragment"
android:name="com.example.devcash.Fragments.PurchaseItemListFragment"
tools:layout="#layout/fragment_purchase_item_list"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3">
</fragment>
<View
style="#style/Divider"
android:layout_width="1dp"
android:layout_height="wrap_content" />
<fragment
android:id="#+id/purchaselist_fragment"
android:name="com.example.devcash.Fragments.PurchaseListFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
tools:layout="#layout/fragment_purchase_list">
</fragment>
</LinearLayout>
Try replacing getFragmentManager() with getChildFragmentManager()
I am following the vogella tutorial about multi-pane development in Android.
Now I would like to check if the a detail fragment is existing (multi-pane layout activated) to remove it and add it again with fresh data.
I need that to update the detail view when the user selects something in the main fragment.
As suggested in the tutorial I am checking for the Fragment like that:
ReviewMaschineFragment fragment = (ReviewMaschineFragment) getFragmentManager().
findFragmentById(R.id.detailreviewcontainer);
if (fragment == null || ! fragment.isInLayout()) {
Log.i("Detail Fragment", "Start new activity");
}
else {
Log.i("Detail Fragment", "Update...");
}
My Problem is that it always gets false even if the fragment exists.
Why is it not detecting the fragment as existing if it is present in the multi-pane layout?
I add my fragments like that to the layout:
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar_main);
setSupportActionBar(toolbar);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.maschinelistcontainer, new MaschineFragment());
if(getResources().getBoolean(R.bool.dual_pane)){
ft.add(R.id.detailreviewcontainer, new ReviewMaschineFragment());
}
ft.commit();
The tablet layout file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<include
android:id="#+id/toolbar_main"
layout="#layout/toolbar"
></include>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="9"
android:orientation="horizontal" >
<FrameLayout
android:id="#+id/maschinelistcontainer"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"
/>
<FrameLayout
android:id="#+id/detailreviewcontainer"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="6"
/>
</LinearLayout>
</LinearLayout>
While creating fragment add tag value with it
eg
ft.add(R.id.maschinelistcontainer, new MaschineFragment(), "sometag");
You can use findFragmentByTag() function to get fragment if it is giving null the fragment is not exist.
Fragment fragmentA = fragmentManager.findFragmentByTag("sometag");
if (fragmentA == null) {
// not exist
} else {
//fragment exist
}
for example:- http://wiki.workassis.com/android-load-two-fragments-in-one-framelayout/
Pls change
ReviewMaschineFragment fragment = (ReviewMaschineFragment) getFragmentManager().
to
ReviewMaschineFragment fragment = (ReviewMaschineFragment) getSupportFragmentManager().
Here's my navigation:
HomeFragment -> LoginFragment -> CreateEventFragment
My HomeFragment is my first Fragment inside my MainActivity.
In my code, I'm replacing each one of them using the same view id( a FrameLayout inside my MainActivity's layout: R.id.container).
So every replace() is being called like this:
FragmentManager fragmentManager = mContext.getSupportFragmentManager();
fragmentManager.beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.replace(containerId, nextFragment).addToBackStack(null).commit();
Except for LoginFragment to CreateEventFragment, because after the user logs in, he doesn't have to go back to LoginFragment so I don't call addToBackStack().
But something strange is happening:
When I'm on CreateEventFragment, after logging in successfully, and press the back button, my CreateEventFragment onDestroy() is not being called.
Debugging it I noticed that it isn't removed from the backStack, what am I doing wrong?
EDIT
Some code:
Common replace fragment method, inside BaseFragment, parent class of all three Fragments
public void replaceFragment(int containerId, Fragment nextFragment, boolean addToBackStack){
FragmentManager fragmentManager = mContext.getSupportFragmentManager();
if (addToBackStack)
fragmentManager.beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.replace(containerId, nextFragment).addToBackStack(null).commit();
else
fragmentManager.beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.replace(containerId, nextFragment).commit();
}
On HomeFragment:
BaseFragment nextFragment =
(PreferencesHandler.isLogged()) ?
CreateEventFragment.newInstance() :
LoginFragment.newInstance("create_event") ;
replaceFragment(R.id.main_fragment_container, nextFragment, true);
On LoginFragment:
public void goToNextFragment(){
Fragment nextFragment;
switch (mIntent){
case "create_event":
nextFragment = new CreateEventFragment();
break;
case "participate":
nextFragment = new ListsFragment();
break;
default:
nextFragment = new HomeFragment();
break;
}
replaceFragment(R.id.main_fragment_container, nextFragment, false);
}
My MainActivity's layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="#+id/toolbar_actionbar"
layout="#layout/toolbar_actionbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:layout_below="#+id/toolbar_actionbar"
tools:context=".MainActivity">
<FrameLayout
android:id="#+id/main_fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/toolbar_actionbar"
/>
<fragment android:id="#+id/navigation_drawer"
android:layout_width="#dimen/navigation_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
android:name="Fragments.`NavigationDrawerFragment`"
tools:layout="#layout/fragment_navigation_drawer" />
</android.support.v4.widget.DrawerLayout>
</RelativeLayout>
EDIT 2
Noticed that pressing back button calls LoginFragment onDestroy, but not CreateFragment's. Also noticed that backStack has LoginFragment, guess it shouldn't, right?
i really need help.
This is how my application looks like. I got two(2) fragments where the left side is for the buttons and for the right side is for my details.
The bigger fragment has a default display which i called splash. An image is viewed here, a bigger image that would take the height of the device.
So my case is when i click/press button 1, it would display the fragment for that but the image is still present.
My question now is, how to i get rid of the 'splash display'?
Here is my code
/**
* on main listener
*/
#Override
public void onMainListener(String whatPress){
Fragment fr = null;
if(whatPress.equals("button1"))
fr = new FragmentOne();
if(whatPress.equals("button2"))
fr = new FragmentTwo();
if(whatPress.equals("button3"))
fr = new FragmentThree();
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.detailFragment, fr, whatPress);
fragmentTransaction.commit();
}
The code above is the one handles which button is pressed.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<fragment
android:id="#+id/menuFragment"
android:name="FragmentMenu"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
class="com.mizsh.Fragment_Menu" />
<fragment
android:id="#+id/detailFragment"
android:name="com.mizsh.Fragment_Splash"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
</LinearLayout>
The code above is my main.xml
You should replace the detailFragment with FrameLayout
<FrameLayout android:id="#+id/detailFragment" android:layout_weight="1"
android:layout_width="0px" android:layout_height="match_parent" />
and replace it with Fragment_Splash in the onCreate of the activity
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.detailFragment, fragmentSplash, null);
fragmentTransaction.commit();
then replace with chosen fragment on click
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.detailFragment, chosenFragment, null);
fragmentTransaction.commit();
I've got a question.
I have a fragment, which inflates two other fragments (Fragment A is left, Fragment B is right)
I want to hide Fragment A when the user changes the mode to portrait-mode.
I added in the layout-port/xml a DrawerLayout and added the code for the NavigationDrawer in my Fragment, but it doesn't work.
Does anyone have an idea, how to realize it?
Thanks :)
I've solved the first problem with this code:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
orientation = newConfig.orientation;
switch (orientation) {
case Configuration.ORIENTATION_LANDSCAPE:
FragmentA fragmentleft = new FragmentA();
FragmentB fragmentright = new FragmentB();
FragmentTransaction transaction1 = getSupportFragmentManager()
.beginTransaction();
FragmentTransaction transaction2 = getSupportFragmentManager()
.beginTransaction();
transaction1.replace(R.id.framelayout_left, fragmentleft);
transaction2.replace(R.id.framelayout_right, fragmentright);
transaction1.commit();
transaction2.commit();
break;
case Configuration.ORIENTATION_PORTRAIT:
createNavigationDrawer();
Log.d("TEST", "Portrait");
break;
}
}
But now I have the problem, that i have to inflate FragmentA in my ListView of the DrawerLayout:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<FrameLayout
android:id="#+id/framelayout_right"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ListView
android:id="#+id/framelayout_left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#111"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp" />
But how can I do this?
It doesn't work properly :(
I had also tried to change the ListView to a FrameLayout and inflate the FragmentA within it, but it didn't work too:(
I would be very thankful, if somebody could help me :)