I set my own animations for dialog window enter but it not fires when I call .show() first time after activity created.
At the gif below you can see that first time animation is drop down and only second time it is slide up that I set.
DialogFragment:
public class DateChooseDialog extends DialogFragment {
public DateChooseDialog() {
// Required empty public constructor
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(STYLE_NORMAL, R.style.DialogFullScreen);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.dialog_date_choose, container);
}
#Override
public void onResume() {
WindowManager.LayoutParams params = getDialog().getWindow().getAttributes();
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.gravity = Gravity.BOTTOM;
params.windowAnimations = R.style.DialogSlideAnimation;
getDialog().getWindow().setAttributes(params);
super.onResume();
}
}
Animations:
<style name="DialogSlideAnimation" parent="Theme.AppCompat.Dialog">
<item name="android:windowEnterAnimation">#anim/slide_up</item>
<item name="android:windowExitAnimation">#anim/slide_down</item>
</style>
<!-- slide_up -->
<translate
android:duration="#android:integer/config_shortAnimTime"
android:fromYDelta="0"
android:interpolator="#android:anim/accelerate_interpolator"
android:toYDelta="100%"
/>
<!-- slide_down -->
<translate
android:duration="#android:integer/config_shortAnimTime"
android:fromYDelta="0"
android:interpolator="#android:anim/accelerate_interpolator"
android:toYDelta="100%"
/>
This is how I show dialog:
DateChooseDialog dateChooseDialog = new DateChooseDialog();
dateChooseDialog.show(getFragmentManager(), "date_choose");
Problem is all about keyboard. It resizes your whole window and while keyboard disappears with slide down animation, your whole window resizes it self through sliding down.
Please add this lines to your manifest.
<activity (Your current activity)
...
android:windowSoftInputMode="adjustPan">
</activity>
With these lines, your keyboard will overlay window and it wont resize.
Next challange is detect keyboard is opened to delay animation if neccessary.
Good luck there
Related
I have checked all the Stack Overflow Q/A on this, still can't find a solution.
Here are the files:
DialogFragment.java
package app.com.thetechnocafe.mealsquickie.Dialogs;
import android.app.Dialog;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TextInputEditText;
import android.support.design.widget.TextInputLayout;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;
import app.com.thetechnocafe.mealsquickie.R;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* Created by gurleensethi on 26/01/17.
*/
public class NewCategoryDialog extends DialogFragment {
#BindView(R.id.category_name_text_input_layout)
TextInputLayout mCategoryNameTextInputLayout;
#BindView(R.id.category_name_text_input_edit_text)
TextInputEditText mCategoryNameTextInputEditText;
#BindView(R.id.cancel_button)
Button mCancelButton;
#BindView(R.id.add_button)
Button mAddButton;
private OnAddCategoryListener mListener;
//Interface for callbacks
public interface OnAddCategoryListener {
void onCategoryAdded(String category);
}
//Instance method
public static NewCategoryDialog getInstance() {
return new NewCategoryDialog();
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
//Inflate the custom dialog
View root = LayoutInflater.from(getContext()).inflate(R.layout.dialog_new_category, container, false);
ButterKnife.bind(this, root);
setEventListeners();
//Set properties
getDialog().requestWindowFeature(STYLE_NO_TITLE);
setCancelable(false);
return root;
}
#Override
public void onStart() {
super.onStart();
getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
private void setEventListeners() {
mCancelButton.setOnClickListener(view -> getDialog().dismiss());
mAddButton.setOnClickListener(view -> validateAndSubmitFields());
}
private void validateAndSubmitFields() {
if (mListener != null) {
//Remove all the already existing errors
mCategoryNameTextInputLayout.setErrorEnabled(false);
String category = mCategoryNameTextInputEditText.getText().toString();
if (category.equals("")) {
mCategoryNameTextInputLayout.setError(getString(R.string.category_name_cannot_be_empty));
return;
}
mListener.onCategoryAdded(category);
} else {
Toast.makeText(getContext(), "No Listener attached for adding new category. Please contact the developer.", Toast.LENGTH_SHORT).show();
}
}
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.getWindow().getAttributes().windowAnimations = R.style.DialogSlideFromBottomAnimation;
return dialog;
}
}
slide_down.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="1000"
android:fromYDelta="0%"
android:interpolator="#android:anim/accelerate_interpolator"
android:toYDelta="100%" />
</set>
slide_up.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="1000"
android:fromYDelta="100%"
android:interpolator="#android:anim/accelerate_interpolator"
android:toYDelta="0%" />
</set>
Showing the dialog:
DialogFragment dialog = NewCategoryDialog.getInstance();
dialog.show(getFragmentManager(), DIALOG_NEW_CATEGORY_TAG);
I have tried both getAttributes().windowAnimations and setWindowAnimations(), and have also tried it putting it in onActivityCreated, onCreateDialog, onCreateView, but it doesn't seem to work.
No matter which the solutions you pick you might have had the same problem as me.
I need to UNINSTALL the game from my development device before installing the new version for the changes to take effect.
I am not sure why but I guess it has to do with the optimized deployment on Android studio not recognizing the changes.
Try it as this.
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (getDialog().getWindow() != null) {
dialog.getWindow().getAttributes().windowAnimations = R.style.DialogSlideFromBottomAnimation;
}
}
In your onStart of the fragment,
do the following:
// safety check
if (getDialog() == null) {
return;
}
// set the animations to use on showing and hiding the dialog
getDialog().getWindow().setWindowAnimations(
R.style.dialog_animation_slide);
The style set above should be defined like:
<style
name="dialog_animation_slide" >
<item name="android:windowEnterAnimation">#anim/slide_up</item>
<item name="android:windowExitAnimation">#anim/slid_down</item>
</style>
Be sure to put your slide_up.xml and slide_down.xml in res/anim directory
Do remove dialog.getWindow().getAttributes().windowAnimations = R.style.DialogSlideFromBottomAnimation; from onCreateDialog()
Let me know if this works for you!!!
If nothing work, maybe the device has animations deactivated from the developer options. restore default options and check.
Animations are a bit tricky when it comes to DialogFragment.
When you need to change the visibility or position of views in your layout, you should include subtle animations to help the user understand how the UI is changing.
So in order to achieve that lets take in mind that DialogFragment is a wrapper for the Dialog class, you should set a theme to your base Dialog to get the animation you want:
public class CustomDialogFragment extends DialogFragment
{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
return super.onCreateView(inflater, container, savedInstanceState);
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
// Set a theme on the dialog builder constructor!
AlertDialog.Builder builder =
new AlertDialog.Builder( getActivity(), R.style.MyCustomTheme );
builder
.setTitle( "Your title" )
.setMessage( "Your message" )
.setPositiveButton( "OK" , new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which) {
dismiss();
}
});
return builder.create();
}
}
Then you just need to define the theme that will include your desired animation. In styles.xml add your custom theme:
slide_down.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="1000"
android:fromYDelta="0%"
android:interpolator="#android:anim/accelerate_interpolator"
android:toYDelta="100%" />
</set>
slide_up.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="1000"
android:fromYDelta="100%"
android:interpolator="#android:anim/accelerate_interpolator"
android:toYDelta="0%" />
</set>
styles.xml
<style name="MyCustomTheme" parent="#android:style/Theme.Panel">
<item name="android:windowAnimationStyle">#style/MyAnimation.Window</item>
</style>
<style name="MyAnimation.Window" parent="#android:style/Animation.Activity">
<item name="android:windowEnterAnimation">#anim/slide_down</item>
<item name="android:windowExitAnimation">#anim/slide_up</item>
</style>
And that's all... Hope it helps. That is thanks to this answer: Show DialogFragment with animation growing from a point
Good day. I faced problem, when dialog animation stops working when dialog called from fragment.
First I tried DialogFragment with custom style:
public static class QRDialog extends DialogFragment {
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity());
dialog.setCancelable(true);
ImageView im = new ImageView(getActivity());
im.setImageResource(R.drawable.qr_code_placeholder);
im.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
im.setClickable(true);
im.setScaleType(ImageView.ScaleType.FIT_XY);
im.setAdjustViewBounds(true);
im.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dismiss();
}
});
dialog.setView(im);
return dialog.create();
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getDialog().getWindow().getAttributes().windowAnimations = R.style.XSlideAnimation;
}
}
Those XSlideAnimation is simple animation style:
<style name="XSlideAnimation" >
<item name="android:windowEnterAnimation">#android:anim/slide_in_left</item>
<item name="android:windowExitAnimation">#android:anim/slide_out_right</item>
</style>
It didn't work.
Then I tried set custom animation for fragment transaction:
FragmentTransaction tr = getFragmentManager().beginTransaction();
tr.setCustomAnimations(R.anim.in, R.anim.out);
new QRDialog().show(tr, "dialog");
in.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromYDelta="50%"
android:toYDelta="0"
android:duration="500"
/>
</set>
out.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromYDelta="0"
android:toYDelta="50%"
android:duration="500"
/>
</set>
No success either.
Then I tried just to get new Dialog instance and set animation for it:
final Dialog dialog = new Dialog(getActivity());
ImageView im = new ImageView(getActivity());
im.setImageResource(R.drawable.qr_code_placeholder);
im.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
im.setClickable(true);
im.setScaleType(ImageView.ScaleType.FIT_XY);
im.setAdjustViewBounds(true);
dialog.setContentView(im);
im.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.getWindow().getAttributes().windowAnimations = R.style.XSlideAnimation;
dialog.setCancelable(true);
dialog.show();
And animation works perfect BUT only if I call dialog from activity. When I put exact same code in fragment, animation stop working. First approach works from activity too, but not in fragment.
How can I get working animation when creating dialog in fragment?
UPD 16-102017:
I see no answer or comments here so far, but somebody upvoted this issue once. So, just for update - in my case it's just started to work. I did literally nothing with code. Animation just appeared and staid couple days later during tests.
To achieve a animated pop up, I have used a custom DialogFragment extending the DialogFragment class. Then, I designed the overlay layout in xml and added that during loading of the pop up. As, I needed to do the animation, I designed 2 animation xml files and added that in styles.xml and added the animation during the loading of the overlay.
I am showing the overlay animation in 3 places. It shows perfectly i.e. grows from the Bee icon and disappears in the bee icon when I use it as a component in a list item and when I use it along with a image view. But when I use it along with a VideoView or Exoplayer View the starting point of the animation shifts to the left for the x axis and goes up for the Y axis.
Also, the the pop up along with the animation works perfectly using the below code for Samsung Note Edge but causes the above problem for Samsung Galaxy S5 and Nexus 4.
It also works fine i.e. the overlay is at the exact position where the bee is for all 3 screens when I do not use the animation. So, I guess the error is in the animation.
I am giving sample code, I wrote.
Custom Dialog Fragment:
public class ConfirmBox extends DialogFragment {
private View source;
private RelativeLayout relLayout;
public ConfirmBox() {
}
public ConfirmBox(View source) {
this.source = source;
}
public ConfirmBox(View source,RelativeLayout relLayout) {
this.source = source;
this.relLayout =relLayout;
}
public static ConfirmBox newInstance(View source) {
return new ConfirmBox(source);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(STYLE_NO_TITLE, 0);
}
#Override
public void onStart() {
super.onStart();
// Less dimmed background; see http://stackoverflow.com/q/13822842/56285
Window window = getDialog().getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.dimAmount = 0.2f; // dim only a little bit
window.setAttributes(params);
// Transparent background; see http://stackoverflow.com/q/15007272/56285
// (Needed to make dialog's alpha shadow look good)
window.setBackgroundDrawableResource(android.R.color.transparent);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Put your dialog layout in R.layout.view_confirm_box
final View view = inflater.inflate(R.layout.overlay_view, container, false);
RelativeLayout layout = (RelativeLayout) view.findViewById(R.id.overlayLayout);
layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
getDialog().dismiss();
}
});
setDialogPosition();
return view;
}
/**
* Try to position this dialog next to "source" view
*/
private void setDialogPosition() {
if (source == null) {
return; // Leave the dialog in default position
}
// Find out location of source component on screen
// see http://stackoverflow.com/a/6798093/56285
int[] location = new int[2];
source.getLocationOnScreen(location);
int sourceX = location[0];
int sourceY = location[1];
Log.d("CONFIRM BOX:", "X: " + sourceX + "Y: " + sourceY);
Window window = getDialog().getWindow();
window.getAttributes().windowAnimations = R.style.PauseDialogAnimation;
// set "origin" to top left corner
window.setGravity(Gravity.TOP| Gravity.LEFT);
WindowManager.LayoutParams params = window.getAttributes();
params.x = sourceX;
params.y = sourceY - dpToPx(25);
Log.d("CONFIRM BOX:","X: "+ sourceX + "Y: "+ sourceY);
Log.d("CONFIRM BOX:","-----------------------------------------------------------");
window.setAttributes(params);
// Show the animation of the DialogueFragment
window.getAttributes().windowAnimations = R.style.PauseDialogAnimation;
}
public int dpToPx(float valueInDp) {
DisplayMetrics metrics = getActivity().getResources().getDisplayMetrics();
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valueInDp, metrics);
}
}
anim_in.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:interpolator="#android:anim/linear_interpolator"
android:fromXScale="0.0"
android:toXScale="1.0"
android:fromYScale="0.0"
android:toYScale="1.0"
android:fillAfter="false"
android:startOffset="100"
android:duration="200"
android:pivotX = "5%"
android:pivotY = "-40%"
/>
<translate
android:fromYDelta="50%"
android:toYDelta="0"
android:startOffset="100"
android:duration="200"
/>
</set>
anim_out.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:interpolator="#android:anim/linear_interpolator"
android:fromXScale="1.0"
android:toXScale="0.0"
android:fromYScale="1.0"
android:toYScale="0.0"
android:fillAfter="false"
android:duration="200"
android:pivotX = "5%"
android:pivotY = "-40%"
/>
<translate
android:fromYDelta="0"
android:toYDelta="50%"
android:duration="200"
/>
</set>
styles.xml:
<style name="PauseDialogAnimation">
<item name="android:windowEnterAnimation">#anim/anim_in</item>
<item name="android:windowExitAnimation">#anim/anim_out</item>
</style>
Can someone kindly help me on zeroing in on the problem here?
Thanks.
I am writing an Android app where I want the activity to appear by animating in from the bottom of the screen to the top. I am able to do this with code from here:
How to translate the activity from top to bottom and viceversa?
However, I am not able to do the vice-versa animation wherein the Activity would disappear by sliding from the top to the bottom of the screen.
I used the code in the above link; the activity appears by sliding up, but when disappearing, it fades out, instead of sliding to the bottom.
I even tried putting the code in onCreate() :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
overridePendingTransition(R.anim.appear_from_bottom, R.anim.disappear_to_bottom);
setContentView(R.layout.activity_all_metadata_display);
initializePage();
}
You need to define your "slide up" animations from the linked question, and some new "slide down" animations that reverse the process.
The important parts of the animations to look at are the fromYDelta and toYDelta values. These define the Y-positions (of the top of your view) at the start & end of the animations.
slide_in_up.xml
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="#android:integer/config_longAnimTime"
android:fromYDelta="100%p"
android:toYDelta="0%p" />
slide_out_up.xml
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="#android:integer/config_longAnimTime"
android:fromYDelta="0%p"
android:toYDelta="-100%p" />
slide_in_down.xml
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="#android:integer/config_longAnimTime"
android:fromYDelta="-100%p"
android:toYDelta="0%p" />
slide_out_down.xml
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="#android:integer/config_longAnimTime"
android:fromYDelta="0%p"
android:toYDelta="100%p" />
For the "slide up" animations, you should have overridden the pending transition in your onResume() method like this:
protected void onResume()
{
super.onResume();
overridePendingTransition(R.anim.slide_in_up, R.anim.slide_out_up);
}
For the "slide down" animations, do something similar in your onPause() method:
protected void onPause()
{
super.onPause();
overridePendingTransition(R.anim.slide_in_down, R.anim.slide_out_down);
}
Some tutorials suggest using the wrong life-cycle methods:
onCreate() is not called every time the activity is shown
onDestroy() is not called every time the activity is taken away
Rather use methods that are called every time there is a screen transition:
onResume() is called when the activity is shown to the user
onPause() is called when the activity is going to be taken away
For more info on these methods specifically, check the Android developer site:
Pausing and Resuming an Activity
When your screen is displayed, it will slide in from the bottom.
When a new screen is displayed, your screen will slide back down.
Two ways of doing this:
1. Using styles
Assuming you wish to implement this for all activities, in your base theme define the following entry:
<item name="android:windowAnimationStyle">#style/ActivityAnimations</item>
Then define the following style:
<style name="ActivityAnimations" parent="android:style/Animation.Activity">
<item name="android:activityOpenEnterAnimation">#anim/appear_from_bottom</item>
<item name="android:activityOpenExitAnimation">#anim/hold</item>
<item name="android:activityCloseEnterAnimation">#anim/hold</item>
<item name="android:activityCloseExitAnimation">#anim/disappear_to_bottom</item>
</style>
Where #anim/hold can be something like this:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false" >
<translate
android:duration="1000"
android:zAdjustment="bottom" />
</set>
2. Using overridePendingTransition()
Override finish():
#Override
public void finish() {
super.finish();
overridePendingTransition(R.anim.hold, R.anim.disappear_to_bottom);
}
Override onBackPressed():
#Override
public void onBackPressed() {
finish();
}
Override onOptionsItemSelected():
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
In your main xml file. Add id of the root tag and pass this to function. like
/** The Constant ANIM_NO. */
public static final int ANIM_NO = 0;
public static void topToDown(Context context, View target, int type,
int duration) {
if (type == UtilityAnimations.ANIM_NO) {
UtilityAnimations.topToDown(context, target, duration);
} else {
final Animation animation = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, -1.0f,
Animation.RELATIVE_TO_SELF, 0.0f);
animation.setDuration(duration != 0 ? duration
: UtilityAnimations.DURATION_MEDIAM);
animation.setInterpolator(UtilityAnimations.getInterpolator(
context, type));
target.startAnimation(animation);
}
}
you can vice-versa your transition by overriding the Transition in your onPause() :
#Override
protected void onPause()
{
super.onPause();
overridePendingTransition(R.anim.appear_from_bottom, R.anim.disappear_to_bottom);
}
I'm showing a DialogFragment when the user taps on a row in a ListView. I'd like to animate the showing of the dialog so that it grows from the center of the row. A similar effect can be seen when opening a folder from the launcher.
One idea that I've had is a combination of TranslateAnimation and ScaleAnimation. Is there another way?
Being DialogFragment a wrapper for the Dialog class, you should set a theme to your base Dialog to get the animation you want:
public class CustomDialogFragment extends DialogFragment implements OnEditorActionListener
{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
return super.onCreateView(inflater, container, savedInstanceState);
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
// Set a theme on the dialog builder constructor!
AlertDialog.Builder builder =
new AlertDialog.Builder( getActivity(), R.style.MyCustomTheme );
builder
.setTitle( "Your title" )
.setMessage( "Your message" )
.setPositiveButton( "OK" , new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which) {
dismiss();
}
});
return builder.create();
}
}
Then you just need to define the theme that will include your desired animation. In styles.xml add your custom theme:
<style name="MyCustomTheme" parent="#android:style/Theme.Panel">
<item name="android:windowAnimationStyle">#style/MyAnimation.Window</item>
</style>
<style name="MyAnimation.Window" parent="#android:style/Animation.Activity">
<item name="android:windowEnterAnimation">#anim/anim_in</item>
<item name="android:windowExitAnimation">#anim/anim_out</item>
</style>
Now add the animation files in the res/anim folder:
( the android:pivotY is the key )
anim_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:interpolator="#android:anim/linear_interpolator"
android:fromXScale="0.0"
android:toXScale="1.0"
android:fromYScale="0.0"
android:toYScale="1.0"
android:fillAfter="false"
android:startOffset="200"
android:duration="200"
android:pivotX = "50%"
android:pivotY = "-90%"
/>
<translate
android:fromYDelta="50%"
android:toYDelta="0"
android:startOffset="200"
android:duration="200"
/>
</set>
anim_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:interpolator="#android:anim/linear_interpolator"
android:fromXScale="1.0"
android:toXScale="0.0"
android:fromYScale="1.0"
android:toYScale="0.0"
android:fillAfter="false"
android:duration="200"
android:pivotX = "50%"
android:pivotY = "-90%"
/>
<translate
android:fromYDelta="0"
android:toYDelta="50%"
android:duration="200"
/>
</set>
Finally, the tricky thing here is to get your animation grow from the center of each row. I suppose the row is filling the screen horizontally so, on one hand the android:pivotX value will be static. On the other hand, you can't modify the android:pivotY value programmatically.
What I suggest is, you define several animations each of which having a different percentage value on the android:pivotY attribute (and several themes referencing those animations). Then, when the user taps the row, calculate the Y position in percentage of the row on the screen. Knowing the position in percentage, assign a theme to your dialog that has the appropriate android:pivotY value.
It is not a perfect solution but could do the trick for you. If you don't like the result, then I would suggest forgetting the DialogFragment and animating a simple View growing from the exact center of the row.
Check it out this code, it works for me
// Slide up animation
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="#android:integer/config_mediumAnimTime"
android:fromYDelta="100%"
android:interpolator="#android:anim/accelerate_interpolator"
android:toXDelta="0" />
</set>
// Slide dowm animation
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="#android:integer/config_mediumAnimTime"
android:fromYDelta="0%p"
android:interpolator="#android:anim/accelerate_interpolator"
android:toYDelta="100%p" />
</set>
// Style
<style name="DialogAnimation">
<item name="android:windowEnterAnimation">#anim/slide_up</item>
<item name="android:windowExitAnimation">#anim/slide_down</item>
</style>
// Inside Dialog Fragment
#Override
public void onActivityCreated(Bundle arg0) {
super.onActivityCreated(arg0);
getDialog().getWindow()
.getAttributes().windowAnimations = R.style.DialogAnimation;
}
DialogFragment has a public getTheme() method that you can over ride for this exact reason. This solution uses less lines of code:
public class MyCustomDialogFragment extends DialogFragment{
...
#Override
public int getTheme() {
return R.style.MyThemeWithCustomAnimation;
}
}
To get a full-screen dialog with animation, write the following ...
Styles:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="actionModeBackground">?attr/colorPrimary</item>
<item name="windowActionModeOverlay">true</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.NoActionBar.FullScreenDialog">
<item name="android:windowAnimationStyle">#style/Animation.WindowSlideUpDown</item>
</style>
<style name="Animation.WindowSlideUpDown" parent="#android:style/Animation.Activity">
<item name="android:windowEnterAnimation">#anim/slide_up</item>
<item name="android:windowExitAnimation">#anim/slide_down</item>
</style>
res/anim/slide_up.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="#android:interpolator/accelerate_quad">
<translate
android:duration="#android:integer/config_shortAnimTime"
android:fromYDelta="100%"
android:toYDelta="0%"/>
</set>
res/anim/slide_down.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="#android:interpolator/accelerate_quad">
<translate
android:duration="#android:integer/config_shortAnimTime"
android:fromYDelta="0%"
android:toYDelta="100%"/>
</set>
Java code:
public class MyDialog extends DialogFragment {
#Override
public int getTheme() {
return R.style.AppTheme_NoActionBar_FullScreenDialog;
}
}
private void showDialog() {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
Fragment previous = getSupportFragmentManager().findFragmentByTag(MyDialog.class.getName());
if (previous != null) {
fragmentTransaction.remove(previous);
}
fragmentTransaction.addToBackStack(null);
MyDialog dialog = new MyDialog();
dialog.show(fragmentTransaction, MyDialog.class.getName());
}
In DialogFragment, custom animation is called onCreateDialog. 'DialogAnimation' is custom animation style in previous answer.
public Dialog onCreateDialog(Bundle savedInstanceState)
{
final Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation;
return dialog;
}
Use decor view inside onStart in your dialog fragment
#Override
public void onStart() {
super.onStart();
final View decorView = getDialog()
.getWindow()
.getDecorView();
decorView.animate().translationY(-100)
.setStartDelay(300)
.setDuration(300)
.start();
}
If you want to work over APIs you have to do inside your DialogFragemnt->onStart and not inside onCreateDialog
#Override
public void onStart()
{
if (getDialog() == null)
{
return;
}
getDialog().getWindow().setWindowAnimations(
R.style.DlgAnimation);
super.onStart();
}
Note: This is just a complement to other answers.
No matter which the solutions you pick you might have the same problem as me.
I need to UNINSTALL the game from my development device before installing the new version for the animation changes to take effect.
I am not sure why but I guess it has to do with the optimized deployment on Android studio not recognizing the changes.
Have you looked at Android Developers Training on Zooming a View? Might be a good starting point.
You probably want to create a custom class extending DialogFragment to get this working.
Also, take a look at Jake Whartons NineOldAndroids for Honeycomb Animation API compatibility all the way back to API Level 1.
Add this code on values anim
<scale
android:duration="#android:integer/config_longAnimTime"
android:fromXScale="0.2"
android:fromYScale="0.2"
android:toXScale="1.0"
android:toYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"/>
<alpha
android:fromAlpha="0.1"
android:toAlpha="1.0"
android:duration="#android:integer/config_longAnimTime"
android:interpolator="#android:anim/accelerate_decelerate_interpolator"/>
call on styles.xml
<style name="DialogScale">
<item name="android:windowEnterAnimation">#anim/scale_in</item>
<item name="android:windowExitAnimation">#anim/scale_out</item>
</style>
On java code: set Onclick
public void onClick(View v) {
fab_onclick(R.style.DialogScale, "Scale" ,(Activity) context,getWindow().getDecorView().getRootView());
// Dialogs.fab_onclick(R.style.DialogScale, "Scale");
}
setup on method:
alertDialog.getWindow().getAttributes().windowAnimations = type;