I'm currently working on a dark theme transition by restarting the activity, but I stumbled upon a problem: the transitions don't work and I have no idea why.
The code below is the theme resources I currently use:
<style name="Theme.TestApp" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">#color/grey_light</item>
<item name="colorPrimaryVariant">#color/primary_light</item>
<item name="colorOnPrimary">#color/on_primary_light</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">#color/teal_200</item>
<item name="colorSecondaryVariant">#color/teal_700</item>
<item name="colorOnSecondary">#color/white</item>
<!-- Customize your theme here. -->
<item name="android:statusBarColor">#color/bar</item>
<item name="background">#color/grey_light</item>
<item name="android:textColor">#color/list_text</item>
<item name="android:windowSplashScreenBackground" tools:targetApi="s">#color/primary_light</item>
<item name="android:windowAnimationStyle">#style/WindowAnimation</item>
</style>
<style name="WindowAnimation">
<item name="android:windowEnterAnimation">#android:anim/fade_in</item>
<item name="android:windowExitAnimation">#android:anim/fade_out</item>
</style>
And this is the code I use to restart the activity:
myswitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
restart();
}else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
restart();
}
}
});
}
public void restart () {
Intent i = new Intent(getApplicationContext(), Settings.class);
startActivity(i);
finish();
}
}
Apparently, creating my own animations solved my problem.
fade_in.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<alpha
android:interpolator="#android:anim/accelerate_interpolator"
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="500" />
</set>
fade_out.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<alpha
android:interpolator="#android:anim/accelerate_interpolator"
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:duration="500" />
</set>
I'm working with spinners and want to change background color of window from black to white.
Here is the codes for progress dialog:
if (countProgress > 0) {
countProgress += 1;
return;
}
final ProgressDialog progressDialog = new ProgressDialog(activity, DialogFragment.STYLE_NO_TITLE);
progressDialog.setIndeterminateDrawable(activity.getResources().getDrawable(R.drawable.progress));
progressDialog.setMessage(msg);
progressDialog.setCancelable(false);
progressDialog.setCanceledOnTouchOutside(false);
stackProgressDialog.push(progressDialog);
countProgress = 1;
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
progressDialog.show();
}
});
and here is the drawable xml :
<?xml version="1.0" encoding="utf-8"?>
rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="#drawable/logo_only_64dp"
android:pivotX="50%"
android:pivotY="50%"
android:fromDegrees="0"
android:toDegrees="360"
android:repeatCount="infinite"/>
Step 1: Define a theme that inherits from Theme.Dialog:
<style name="MyTheme" parent="#android:style/Theme.Dialog">
<item name="android:alertDialogStyle">#style/CustomAlertDialogStyle</item>
<item name="android:textColorPrimary">#000000</item>
</style>
There, you can define things like the background color for the whole window (yellow in the question), font colors etc. What's really important is the definition of android:alertDialogStyle. This style controls the appearance of the black area in the question.
Step 2: Define the CustomAlertDialogStyle:
<style name="CustomAlertDialogStyle">
<item name="android:bottomBright">#color/yellow</item>
<item name="android:bottomDark">#color/yellow</item>
<item name="android:bottomMedium">#color/yellow</item>
<item name="android:centerBright">#color/yellow</item>
<item name="android:centerDark">#color/yellow</item>
<item name="android:centerMedium">#color/yellow</item>
<item name="android:fullBright">#color/yellow</item>
<item name="android:fullDark">#color/yellow</item>
<item name="android:topBright">#color/yellow</item>
<item name="android:topDark">#color/yellow</item>
</style>
This sets the black area in the question to yellow.
Step 3: Apply MyTheme to the ProgressDialog, not CustomAlertDialogStyle:
ProgressDialog dialog = new ProgressDialog(this, R.style.MyTheme);
I have an AlertDialog that coming in and out with animations, and I want to add buttons to it, how can I do it?
Here is my AlertDialog code:
private void openPopUP() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Game Paused");
builder.setMessage("Check out the transition!");
dialog = builder.create();
dialog.getWindow().getAttributes().windowAnimations =
R.style.dialog_animation;
dialog.show();
}
Here is my style code:
<resources>
<style name="AppBaseTheme" parent="android:Theme.Light"/>
<style name="AppTheme" parent="AppBaseTheme"/>
<style name="dialog_animation">
<item name="android:windowEnterAnimation">#anim/slide_in_left</item>
<item name="android:windowExitAnimation">#anim/slide_out_right</item>
</style>
</resources>
Here is my anim folder files:
Slide in left:
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="100%p" android:toXDelta="0"
android:duration="500" />
Slide out right:
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fromXDelta="0"
android:toXDelta="100%p" />
I need to add 3 buttons inside the alertdialog, how can I do it? Thank you.
You can use the method builder.setPositiveButton(String title, DialogInterface.OnClickListener listener) and then builder.setNeutralButton(...) and finally builder.setNegativeButton(...)
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;
I read many topics, but I didn't find answer of my problem. I'm trying to use android.R.style.Theme_Translucent_NoTitleBar or xml styles with
<style name="CustomDialogTheme" parent="#android:style/Theme.Dialog">
<item name="android:windowBackground">#color/transparent_white</item>
<item name="android:windowIsFloating">false</item>
<item name="android:windowNoTitle">true</item>
</style>
Even I have added
dialog.getWindow().setBackgroundDrawableResource(R.drawable.pixel);
where pixel is transparent drawable, but with no luck. I always have white border.
My code is below:
Dialog dialog = new Dialog(this,
android.R.style.Theme_Translucent_NoTitleBar);
dialog.getWindow().setBackgroundDrawableResource(R.drawable.pixel);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
ListView modeList = new ListView(this);
String[] stringArray = new String[] { "aaa", "bbb" };
ArrayAdapter<String> modeAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1,
stringArray);
modeList.setAdapter(modeAdapter);
builder.setView(modeList);
dialog = builder.create();
Regards,
Swierzy
The white border of a dialog is a 9patch image
and your background picture has to be an 9patch picture.
http://developer.android.com/guide/developing/tools/draw9patch.html
You can draw it yourself and make any border you like there.
you create your dialog like that
public AboutDialog(Context context) {
super(context,R.style.Theme_Dialog);
.......
and your style e.g.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme" parent="android:Theme">
</style>
<style name="Theme.Dialog" parent="Theme">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowBackground">#drawable/bg</item> <------- your 9patch background picture
</style>
hope this helps abit