Android Slide Animation within layout - java

How can I do this animation in my activity?
when you click a button in the layout, it will slide like this(can't post too many links and picture yet
I already tried doing tabbed but its not the one i'm looking for.
its my first time doing, I only know how to have slide animation between activity
Thanks in Advance
EDIT*
I want to know how to get this effect
http://i.stack.imgur.com/nJtFw.jpg

You can use a fragment for the central layout and then use Fragment animations like this
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);
DetailsFragment newFragment = DetailsFragment.newInstance();
ft.replace(R.id.details_fragment_container, newFragment, "detailFragment");
ft.commit();
Where the xml file for animation could look like.
<?xml version="1.0" encoding="utf-8"?>
<set>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="x"
android:valueType="floatType"
android:valueFrom="-1280"
android:valueTo="0"
android:duration="500"/>
</set>
There are many other animations you can apply, you can find more resources here

Related

Animate fragment from bottom up, over top previous fragment

I'd like to animate in a new fragment from the bottom up, over top of the previous fragment.
Unfortunately, my current implementation pushes the previous fragment up, as the new fragment is animating in, like this:
https://i.imgur.com/IgMUamp.png
What I would like it to do is have the new fragment animate over top the previous fragment, like so:
https://i.imgur.com/DTrEfcm.png
Here is what my code looks like now:
private void pushFragment(String fragmentTag, Fragment fragment) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.anim_in_test, R.anim.anim_out_test);
fragmentTransaction.replace(
R.id.fragment_container,
fragment,
fragmentTag);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commitAllowingStateLoss();
}
Here is anim_in_test.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_decelerate_interpolator">
<translate
android:duration="#android:integer/config_longAnimTime"
android:fromYDelta="100%p"
android:toYDelta="0" />
</set>
And here is anim_out_test.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="#android:integer/config_longAnimTime"
android:fromYDelta="0%p"
android:toYDelta="-100%p"
/>
</set>
What do I need to change to get this working right?
setCustomAnimations(int enter, int exit)
Exit animation should be empty (because you need old fragment stay on screen while new one appears), but if you pass 0 to second param view dissapear without animation. Thats why I add empty alpha animation which changes alpha from 1 to 1.
fragmentTransaction.setCustomAnimations(R.anim.anim_in_test, R.anim.anim_out_test);
anim_out_test.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:duration="#android:integer/config_longAnimTime"
android:fromAlpha="1"
android:toAlpha="1" />
</set>
But at that point it doesnt' work because android draw and animate new fragment BELOW old fragment. You can see it if you make fragment backgrounds transparent.
To resolve this issue I use setZ(z), setElevation(z) or setTranslationZ(z) methods on root view of fragment. It looks like all of them are working. Z value of new fragment should be more than old fragment Z.
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.view, container, false);
view.setZ(value);
Here is result:
It works but I dont know side effects of this solution. On android 4 I think it can be done via custom ViewGroup as fragment container, which draws children in reverse order.

Android Navigation Component with Transition from Drawerlayout

Is it possible to change the transition effect from opening a fragment from a drawerlayout with the android navigation component. There is nothing in the android docs.
Sarah! Yes, it is possible. You can add your custom listener to handle navigation item selection and add animation there. I had to add one myself, for other purposes, but it definitely fits as a solution for your task.
How to:
Add layout with drawer. Example:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<!-- Other views can be added here, or below -->
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="#menu/menu_for_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>
Find NavigationView by ID and assign it to a variable private NavigationView navigationView in your activity, that you may extract by using findViewById(R.id.nav_view). This step is optional. You may find the view and assing naviation item selection listener without holding a reference to NavigationView;
Set navigation item selection listener:
navigationView.setNavigationItemSelectedListener(menuItem -> {
#IdRes
int id = menuItem.getItemId();
NavOptions.Builder optionsBuilder = new NavOptions.Builder();
switch (id) {
case R.id.first_menu_item_id: {
// Lets assume for the first menu item navigation is default
optionsBuilder
.setEnterAnim(R.anim.nav_default_enter_anim)
.setExitAnim(R.anim.nav_default_exit_anim)
.setPopEnterAnim(R.anim.nav_default_pop_enter_anim)
.setPopExitAnim(R.anim.nav_default_pop_exit_anim);
}
break;
case R.id.second_menu_item_id: {
// Lets assume for the second menu item navigation is missing
// empty here
}
break;
case R.id.thrid_menu_item_id: {
// Lets assume for the third menu item navigation is custom
optionsBuilder
.setEnterAnim(R.anim.slide_in_right)
.setExitAnim(R.anim.slide_out_left)
.setPopEnterAnim(R.anim.slide_in_left)
.setPopExitAnim(R.anim.slide_out_right);
}
break;
}
navController.navigate(id, null, optionsBuilder.build());
// Do not forget to close the drawer
// drawer.closeDrawers();
return true;
});
This should help! Any thoughts and questions are welcome!
In case you are interested in animations mentioned in example:
slide_in_left.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="-100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="300"/>
</set>
slide_in_right.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="300"/>
</set>
slide_out_left.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0%" android:toXDelta="-100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="300"/>
</set>
slide_out_right.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0%" android:toXDelta="100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="300"/>
</set>
Update (28 March 2020)
In case this solution doesn't work with the Drawer Menu try to use it with the following code.
Note that I placed setNavigationItemSelectedListener call at the end of the method due to NavigationUI functions sometimes settings it's own listener. That could also be the cause of problem.
There is a lot going on behind NavigationUI functions and if something doesn't work right check out implementation of the functions you use.
private void setupNavigation() {
// Set custom toolbar as action bar
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
// Setup navigation with toolbar and drawer
NavController navController = Navigation.findNavController(this, R.id.main_nav_host_fragment);
/* The set of destinations by id considered at the top level
of your information hierarchy. The Up button will not be displayed
when on these destinations. */
Set<Integer> set = new HashSet<>(Arrays.asList(R.id.first_fragmentId_from_nav_graph, R.id.second_fragmentId_from_nav_graph, R.id.third_fragmentId_from_nav_graph));
/* Configuration options for {#link NavigationUI} methods that interact with implementations of the
app bar pattern */
AppBarConfiguration configuration = new AppBarConfiguration.Builder(set).setDrawerLayout(drawer).build();
NavigationUI.setupWithNavController(toolbar, navController, configuration);
NavigationUI.setupWithNavController(navigationView, navController);
NavigationUI.setupActionBarWithNavController(this, navController, configuration);
// And here you set the listener.
navigationView.setNavigationItemSelectedListener(...);
}
There are multiple calls to NavigationUI functions like setupWithNavController and setupActionBarWithNavController. The reason is that behind each one of them is added one more destination changed listener to navigation controller. See addOnDestinationChangedListener for more information about the listener.
First call adds new ToolbarOnDestinationChangedListener(toolbar, configuration);
Second call adds custom implementation of NavController.OnDestinationChangedListener that updates your navigation view in drawer correctly;
Third call adds new ActionBarOnDestinationChangedListener(activity, configuration).
This configuration allows me to use a single application on a tablet with a Master-Detail pattern and on the phone as a usual application with Drawer Menu.
Referenced string resources are just:
<string name="navigation_drawer_open">Open navigation drawer</string>
<string name="navigation_drawer_close">Close navigation drawer</string>
But they are required for accessibility. It's very good to translate them if you support multiple languages. Basically anything used for accessibility is generally good to translate.
There is a simpler way. Internally NavigationUI builds the NavOptions like this:
if (navController.getCurrentDestination().getParent().findNode(item.getItemId())
instanceof ActivityNavigator.Destination) {
builder.setEnterAnim(R.anim.nav_default_enter_anim)
.setExitAnim(R.anim.nav_default_exit_anim)
.setPopEnterAnim(R.anim.nav_default_pop_enter_anim)
.setPopExitAnim(R.anim.nav_default_pop_exit_anim);
} else {
builder.setEnterAnim(R.animator.nav_default_enter_anim)
.setExitAnim(R.animator.nav_default_exit_anim)
.setPopEnterAnim(R.animator.nav_default_pop_enter_anim)
.setPopExitAnim(R.animator.nav_default_pop_exit_anim);
}
You can just create these directories yourself and override the defaults. In my case I had to create the animator folder (not anim!) in /res/ and put 4 new animation files with these names in it. But maybe try both folders to be sure.
At the moment it works perfectly in a MaterialComponents Theme: the selected drawer item still get's highlighted and the appbar animation is still working too (unlike with some other methods).

How to set a temporary fragment to my "home screen" Android studio

I have started coding and I really like it, I have been on/off on diffrent project (to learn diffrent things) But now i got a problem, I "app"reciate all the help i can get.
I am using the navigation drawer and got three fragments installed. I can navigate through the navigation drawer and select a fragment and it loads on my screen. But when i start my app the screen is just white and the navigation drawer is on the left and i can pick a fragment. Is it possible to have a fragment on my "home screen" so when I start the app there is a fragment already placed on the screen BUT! when i chosse another fragment in the navigation drawer i would like to have my fragment who loaded at the beginning to disappear. Otherwise both fragments will show on eachother (Text on text). Maybe to have the temporary fragment to "finish" itself somehow. Please look at my imgur image to get my idea.Imgur image press here to view
Here is a generic solution on how to use the FragmentManager. It should give a good idea on how to display a Fragment. Besides that you could include a static Fragment in your layout. It's up to you how to approach it.
So the FragmentManager solution looks like this:
YourActivity.java
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentManager fragmentManager = getFragmentManager();
Fragment fragment = AnyFragment.instantiate(this, AnyFragment.class.getName());
fragmentManager.beginTransaction().add(R.id.fragment_placeholder, fragment).addToBackStack(null).commit();
}
The target id is defined in your activity layout.xml
<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"
android:orientation="vertical">
<FrameLayout
android:id="#+id/fragment_placeholder"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"></FrameLayout>
</LinearLayout>
Later if you want to replace the current Fragment you can use the remove and add method of the FragmentManager (the replace method is kinda buggy).
Fragment currentFragment = fragmentManager.findFragmentById(R.id.fragment_placeholder))
fragmentManager.beginTransaction().remove(currentFragment).add(R.id.fragment_placeholder, yourNewFragment).addToBackStack(null).commit();

Navigating between ListFragment and Fragment

My school assignment has an activity that contains a ListFragment and a Fragment. The MainActivity creates the ListFragment, and then each item on the list should open the regular Fragment that just contains a picture, and then when I click on the picture it should go back to the ListFragment.
In all cases, I call the fragments using this code (edited for the specific case of course):
Fragment fragTwo = new FragmentTwo();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragment_place, fragTwo);
ft.addToBackStack(null);
ft.commit();
It calls the fragments OK, except that the second fragment will appear OVER the ListFragment, and I can still select things from the list while the second fragment is open. Do I need to create a new fragment object every time I navigate? And how do I disable/enable a fragment from it's own onclick listener?
main_activity.xml:
<?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" >
<fragment
android:name="com.example.w0068332.fragmentstest.FragmentOne"
android:id="#+id/fragment_place"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
1- Yes you need to create a fragment for each item.
Bundle arguments = new Bundle();
arguments.putInt(FragmentTwo.ARG_ITEM_ID,R.drawable_pic);
FragmentTwo fragment = new FragmentTwo();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.item_detail_container, fragment)
.commit();
I suppose that you display pictures from resources
2- To disable selection from ListFragment while displaying the second one.
In the parent layout of the second fragment you have to add background and make it clickable as below:
android:background="#color/white"
android:clickable="true"
3- To navigate back for the ListFragment add a click listener for the ImageView and onClick call onBackPressed of the Activity:
getActivity().onBackPressed();
you can also have a look on a template from Android studio for Master and details activity

Slide in another XML layout when button is clicked

I have a main.xml layout file and in my Java code, I am doing some calculation taken from the main layout and wanting to display in result.xml layout file. I know I can use the anim folder to hold the animation to slidei n the result layout like the following:
left to right:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate android:fromXDelta="-100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="700"/>
</set>
right to left:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="0%" android:toXDelta="100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="700" />
</set>
I was wondering how to implement the above so when the button is clicked on the main layout file, the result layout file slides in from the right. And also if I wanted to go back to the main layout I can press a button (added on result layout) to slide right the main layout file
You can also use this function : overridePendingTransition which can define an animation for the upcoming activity and an other animation for the activity which exit.
Use it like this, in your second Activity :
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
overridePendingTransition(android.R.anim.slide_out_right, 0);
setContentView(R.layout.myLayout);
first argument is for the animation enter, and 0 is for no animation.
And for an animation when you leave your second activity :
#Override
public void finish() {
super.finish();
overridePendingTransition(R.anim.enterAnim, R.anim.leaveAnim);
}
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.

Categories