mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 01:12:07 +00:00
Android: Show transition animation when exiting game.
This commit is contained in:
parent
0fcf0e1d21
commit
fd82f90fce
7 changed files with 124 additions and 48 deletions
|
@ -277,7 +277,7 @@ public final class NativeLibrary
|
||||||
public static void endEmulationActivity()
|
public static void endEmulationActivity()
|
||||||
{
|
{
|
||||||
Log.v("DolphinEmu", "Ending EmulationActivity.");
|
Log.v("DolphinEmu", "Ending EmulationActivity.");
|
||||||
mEmulationActivity.finish();
|
mEmulationActivity.exitWithAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setEmulationActivity(EmulationActivity emulationActivity)
|
public static void setEmulationActivity(EmulationActivity emulationActivity)
|
||||||
|
|
|
@ -29,11 +29,14 @@ public final class EmulationActivity extends AppCompatActivity
|
||||||
{
|
{
|
||||||
private View mDecorView;
|
private View mDecorView;
|
||||||
private ImageView mImageView;
|
private ImageView mImageView;
|
||||||
private FrameLayout mFrameLayout;
|
private FrameLayout mFrameEmulation;
|
||||||
|
|
||||||
private boolean mDeviceHasTouchScreen;
|
private boolean mDeviceHasTouchScreen;
|
||||||
private boolean mSystemUiVisible;
|
private boolean mSystemUiVisible;
|
||||||
|
|
||||||
|
// So that MainActivity knows which view to invalidate before the return animation.
|
||||||
|
private int mPosition;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handlers are a way to pass a message to an Activity telling it to do something
|
* Handlers are a way to pass a message to an Activity telling it to do something
|
||||||
* on the UI thread. This Handler responds to any message, even blank ones, by
|
* on the UI thread. This Handler responds to any message, even blank ones, by
|
||||||
|
@ -47,6 +50,8 @@ public final class EmulationActivity extends AppCompatActivity
|
||||||
hideSystemUI();
|
hideSystemUI();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
private String mScreenPath;
|
||||||
|
private FrameLayout mFrameContent;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState)
|
protected void onCreate(Bundle savedInstanceState)
|
||||||
|
@ -92,15 +97,17 @@ public final class EmulationActivity extends AppCompatActivity
|
||||||
setContentView(R.layout.activity_emulation);
|
setContentView(R.layout.activity_emulation);
|
||||||
|
|
||||||
mImageView = (ImageView) findViewById(R.id.image_screenshot);
|
mImageView = (ImageView) findViewById(R.id.image_screenshot);
|
||||||
mFrameLayout = (FrameLayout) findViewById(R.id.frame_content);
|
mFrameContent = (FrameLayout) findViewById(R.id.frame_content);
|
||||||
|
mFrameEmulation = (FrameLayout) findViewById(R.id.frame_emulation_fragment);
|
||||||
|
|
||||||
Intent gameToEmulate = getIntent();
|
Intent gameToEmulate = getIntent();
|
||||||
String path = gameToEmulate.getStringExtra("SelectedGame");
|
String path = gameToEmulate.getStringExtra("SelectedGame");
|
||||||
String title = gameToEmulate.getStringExtra("SelectedTitle");
|
String title = gameToEmulate.getStringExtra("SelectedTitle");
|
||||||
String screenPath = gameToEmulate.getStringExtra("ScreenPath");
|
mScreenPath = gameToEmulate.getStringExtra("ScreenPath");
|
||||||
|
mPosition = gameToEmulate.getIntExtra("GridPosition", -1);
|
||||||
|
|
||||||
Picasso.with(this)
|
Picasso.with(this)
|
||||||
.load(screenPath)
|
.load(mScreenPath)
|
||||||
.noFade()
|
.noFade()
|
||||||
.noPlaceholder()
|
.noPlaceholder()
|
||||||
.into(mImageView, new Callback()
|
.into(mImageView, new Callback()
|
||||||
|
@ -120,6 +127,7 @@ public final class EmulationActivity extends AppCompatActivity
|
||||||
});
|
});
|
||||||
|
|
||||||
mImageView.animate()
|
mImageView.animate()
|
||||||
|
.withLayer()
|
||||||
.setStartDelay(2000)
|
.setStartDelay(2000)
|
||||||
.setDuration(500)
|
.setDuration(500)
|
||||||
.alpha(0.0f)
|
.alpha(0.0f)
|
||||||
|
@ -128,7 +136,7 @@ public final class EmulationActivity extends AppCompatActivity
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
mFrameLayout.setVisibility(View.VISIBLE);
|
mFrameEmulation.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.withEndAction(new Runnable()
|
.withEndAction(new Runnable()
|
||||||
|
@ -147,7 +155,7 @@ public final class EmulationActivity extends AppCompatActivity
|
||||||
|
|
||||||
// Add fragment to the activity - this triggers all its lifecycle callbacks.
|
// Add fragment to the activity - this triggers all its lifecycle callbacks.
|
||||||
getFragmentManager().beginTransaction()
|
getFragmentManager().beginTransaction()
|
||||||
.add(R.id.frame_content, emulationFragment, EmulationFragment.FRAGMENT_TAG)
|
.add(R.id.frame_emulation_fragment, emulationFragment, EmulationFragment.FRAGMENT_TAG)
|
||||||
.commit();
|
.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,6 +220,59 @@ public final class EmulationActivity extends AppCompatActivity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void exitWithAnimation()
|
||||||
|
{
|
||||||
|
runOnUiThread(new Runnable()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
Picasso.with(EmulationActivity.this)
|
||||||
|
.invalidate(mScreenPath);
|
||||||
|
|
||||||
|
Picasso.with(EmulationActivity.this)
|
||||||
|
.load(mScreenPath)
|
||||||
|
.noFade()
|
||||||
|
.noPlaceholder()
|
||||||
|
.into(mImageView, new Callback()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onSuccess()
|
||||||
|
{
|
||||||
|
showScreenshot();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError()
|
||||||
|
{
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showScreenshot()
|
||||||
|
{
|
||||||
|
mImageView.setVisibility(View.VISIBLE);
|
||||||
|
mImageView.animate()
|
||||||
|
.withLayer()
|
||||||
|
.setDuration(500)
|
||||||
|
.alpha(1.0f)
|
||||||
|
.withEndAction(afterShowingScreenshot);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Runnable afterShowingScreenshot = new Runnable()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
mFrameContent.removeView(mFrameEmulation);
|
||||||
|
setResult(mPosition);
|
||||||
|
finishAfterTransition();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu)
|
public boolean onCreateOptionsMenu(Menu menu)
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,6 +36,7 @@ import org.dolphinemu.dolphinemu.services.AssetCopyService;
|
||||||
public final class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>
|
public final class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>
|
||||||
{
|
{
|
||||||
private static final int REQUEST_ADD_DIRECTORY = 1;
|
private static final int REQUEST_ADD_DIRECTORY = 1;
|
||||||
|
public static final int REQUEST_EMULATE_GAME = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It is important to keep track of loader ID separately from platform ID (see Game.java)
|
* It is important to keep track of loader ID separately from platform ID (see Game.java)
|
||||||
|
@ -115,6 +116,9 @@ public final class MainActivity extends AppCompatActivity implements LoaderManag
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent result)
|
protected void onActivityResult(int requestCode, int resultCode, Intent result)
|
||||||
{
|
{
|
||||||
|
switch (requestCode)
|
||||||
|
{
|
||||||
|
case REQUEST_ADD_DIRECTORY:
|
||||||
// If the user picked a file, as opposed to just backing out.
|
// If the user picked a file, as opposed to just backing out.
|
||||||
if (resultCode == RESULT_OK)
|
if (resultCode == RESULT_OK)
|
||||||
{
|
{
|
||||||
|
@ -125,6 +129,17 @@ public final class MainActivity extends AppCompatActivity implements LoaderManag
|
||||||
refreshFragment();
|
refreshFragment();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REQUEST_EMULATE_GAME:
|
||||||
|
// Invalidate Picasso image so that the new screenshot is animated in.
|
||||||
|
PlatformGamesFragment fragment = getPlatformFragment(mViewPager.getCurrentItem());
|
||||||
|
|
||||||
|
if (fragment != null)
|
||||||
|
{
|
||||||
|
fragment.refreshScreenshotAtPosition(resultCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -5,6 +5,7 @@ import android.app.ActivityOptions;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.database.DataSetObserver;
|
import android.database.DataSetObserver;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -16,6 +17,7 @@ import com.squareup.picasso.Picasso;
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.R;
|
import org.dolphinemu.dolphinemu.R;
|
||||||
import org.dolphinemu.dolphinemu.activities.EmulationActivity;
|
import org.dolphinemu.dolphinemu.activities.EmulationActivity;
|
||||||
|
import org.dolphinemu.dolphinemu.activities.MainActivity;
|
||||||
import org.dolphinemu.dolphinemu.dialogs.GameDetailsDialog;
|
import org.dolphinemu.dolphinemu.dialogs.GameDetailsDialog;
|
||||||
import org.dolphinemu.dolphinemu.model.GameDatabase;
|
import org.dolphinemu.dolphinemu.model.GameDatabase;
|
||||||
import org.dolphinemu.dolphinemu.viewholders.GameViewHolder;
|
import org.dolphinemu.dolphinemu.viewholders.GameViewHolder;
|
||||||
|
@ -81,14 +83,15 @@ public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> impl
|
||||||
if (mCursor.moveToPosition(position))
|
if (mCursor.moveToPosition(position))
|
||||||
{
|
{
|
||||||
String screenPath = mCursor.getString(GameDatabase.GAME_COLUMN_SCREENSHOT_PATH);
|
String screenPath = mCursor.getString(GameDatabase.GAME_COLUMN_SCREENSHOT_PATH);
|
||||||
Picasso.with(holder.imageScreenshot.getContext())
|
|
||||||
.invalidate(screenPath);
|
|
||||||
|
|
||||||
// Fill in the view contents.
|
// Fill in the view contents.
|
||||||
Picasso.with(holder.imageScreenshot.getContext())
|
Picasso.with(holder.imageScreenshot.getContext())
|
||||||
.load(screenPath)
|
.load(screenPath)
|
||||||
.fit()
|
.fit()
|
||||||
.centerCrop()
|
.centerCrop()
|
||||||
|
.noFade()
|
||||||
|
.noPlaceholder()
|
||||||
|
.config(Bitmap.Config.RGB_565)
|
||||||
.error(R.drawable.no_banner)
|
.error(R.drawable.no_banner)
|
||||||
.into(holder.imageScreenshot);
|
.into(holder.imageScreenshot);
|
||||||
|
|
||||||
|
@ -113,8 +116,6 @@ public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> impl
|
||||||
{
|
{
|
||||||
Log.e("DolphinEmu", "Can't bind view; dataset is not valid.");
|
Log.e("DolphinEmu", "Can't bind view; dataset is not valid.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -222,13 +223,16 @@ public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> impl
|
||||||
intent.putExtra("SelectedGame", holder.path);
|
intent.putExtra("SelectedGame", holder.path);
|
||||||
intent.putExtra("SelectedTitle", holder.title);
|
intent.putExtra("SelectedTitle", holder.title);
|
||||||
intent.putExtra("ScreenPath", holder.screenshotPath);
|
intent.putExtra("ScreenPath", holder.screenshotPath);
|
||||||
|
intent.putExtra("GridPosition", holder.getAdapterPosition());
|
||||||
|
|
||||||
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(
|
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(
|
||||||
(Activity) view.getContext(),
|
(Activity) view.getContext(),
|
||||||
holder.imageScreenshot,
|
holder.imageScreenshot,
|
||||||
"image_game_screenshot");
|
"image_game_screenshot");
|
||||||
|
|
||||||
view.getContext().startActivity(intent, options.toBundle());
|
((Activity) view.getContext()).startActivityForResult(intent,
|
||||||
|
MainActivity.REQUEST_EMULATE_GAME,
|
||||||
|
options.toBundle());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package org.dolphinemu.dolphinemu.fragments;
|
package org.dolphinemu.dolphinemu.fragments;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
import android.app.LoaderManager;
|
import android.app.LoaderManager;
|
||||||
import android.content.Loader;
|
import android.content.Loader;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v7.widget.DefaultItemAnimator;
|
||||||
import android.support.v7.widget.GridLayoutManager;
|
import android.support.v7.widget.GridLayoutManager;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -57,6 +57,15 @@ public class PlatformGamesFragment extends Fragment
|
||||||
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(),
|
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(),
|
||||||
getResources().getInteger(R.integer.game_grid_columns));
|
getResources().getInteger(R.integer.game_grid_columns));
|
||||||
recyclerView.setLayoutManager(layoutManager);
|
recyclerView.setLayoutManager(layoutManager);
|
||||||
|
recyclerView.setItemAnimator(new DefaultItemAnimator()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder, int fromX, int fromY, int toX, int toY)
|
||||||
|
{
|
||||||
|
dispatchChangeFinished(newHolder, false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
recyclerView.addItemDecoration(new GameAdapter.SpacesItemDecoration(8));
|
recyclerView.addItemDecoration(new GameAdapter.SpacesItemDecoration(8));
|
||||||
|
|
||||||
|
@ -70,10 +79,9 @@ public class PlatformGamesFragment extends Fragment
|
||||||
return rootView;
|
return rootView;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void refreshScreenshotAtPosition(int position)
|
||||||
public void onAttach(Activity activity)
|
|
||||||
{
|
{
|
||||||
super.onAttach(activity);
|
mAdapter.notifyItemChanged(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refresh()
|
public void refresh()
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:id="@+id/frame_content"
|
||||||
>
|
>
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/frame_content"
|
android:id="@+id/frame_emulation_fragment"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:visibility="invisible"/>
|
android:visibility="invisible"/>
|
||||||
|
|
|
@ -8,17 +8,10 @@
|
||||||
<!-- darker variant for the status bar and contextual app bars -->
|
<!-- darker variant for the status bar and contextual app bars -->
|
||||||
<item name="colorPrimaryDark">@color/dolphin_blue_dark</item>
|
<item name="colorPrimaryDark">@color/dolphin_blue_dark</item>
|
||||||
|
|
||||||
<!--enable window content transitions
|
<!--enable window content transitions-->
|
||||||
<item name="android:windowContentTransitions">true</item>
|
<item name="android:windowContentTransitions">true</item>
|
||||||
|
<item name="android:windowAllowEnterTransitionOverlap">true</item>
|
||||||
<!– specify enter and exit transitions –>
|
<item name="android:windowAllowReturnTransitionOverlap">true</item>
|
||||||
<item name="android:windowEnterTransition">@android:transition/fade</item>
|
|
||||||
<item name="android:windowExitTransition">@android:transition/fade</item>
|
|
||||||
|
|
||||||
<!– specify shared element transitions –>
|
|
||||||
<item name="android:windowSharedElementEnterTransition">@transition/change_image_transform</item>
|
|
||||||
<item name="android:windowSharedElementExitTransition">@transition/change_image_transform</item>
|
|
||||||
-->
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<!-- Same as above, but use default action bar, and mandate margins. -->
|
<!-- Same as above, but use default action bar, and mandate margins. -->
|
||||||
|
@ -74,23 +67,17 @@
|
||||||
<item name="colorAccent">@color/dolphin_accent_wiiware</item>
|
<item name="colorAccent">@color/dolphin_accent_wiiware</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="DolphinEmulationBase" parent="Theme.AppCompat.Light.DarkActionBar">
|
<style name="DolphinEmulationBase" parent="Theme.AppCompat">
|
||||||
<item name="colorPrimary">@color/dolphin_blue</item>
|
<item name="colorPrimary">@color/dolphin_blue</item>
|
||||||
<item name="colorPrimaryDark">@color/dolphin_blue_dark</item>
|
<item name="colorPrimaryDark">@color/dolphin_blue_dark</item>
|
||||||
<item name="android:windowTranslucentNavigation">true</item>
|
<item name="android:windowTranslucentNavigation">true</item>
|
||||||
|
|
||||||
<!-- enable window content transitions -->
|
<item name="android:windowBackground">@android:color/black</item>
|
||||||
|
|
||||||
|
<!--enable window content transitions-->
|
||||||
<item name="android:windowContentTransitions">true</item>
|
<item name="android:windowContentTransitions">true</item>
|
||||||
|
<item name="android:windowAllowEnterTransitionOverlap">true</item>
|
||||||
<!-- specify enter and exit transitions -->
|
<item name="android:windowAllowReturnTransitionOverlap">true</item>
|
||||||
<item name="android:windowEnterTransition">@android:transition/explode</item>
|
|
||||||
<item name="android:windowExitTransition">@android:transition/explode</item>
|
|
||||||
|
|
||||||
<!-- specify shared element transitions -->
|
|
||||||
<item name="android:windowSharedElementEnterTransition">@transition/change_image_transform
|
|
||||||
</item>
|
|
||||||
<item name="android:windowSharedElementExitTransition">@transition/change_image_transform
|
|
||||||
</item>
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<!-- Inherit from the Base Dolphin Emulation Theme-->
|
<!-- Inherit from the Base Dolphin Emulation Theme-->
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue