summaryrefslogtreecommitdiff
path: root/Source/Android/app/src/main/java
diff options
context:
space:
mode:
authorRyan Houdek <Sonicadvance1@gmail.com>2015-06-30 22:19:25 -0500
committerRyan Houdek <Sonicadvance1@gmail.com>2015-06-30 22:19:25 -0500
commit605ce3788d68a37691b653268dc6c9b901f28d2d (patch)
tree99f82a779ce10120cc35195e5a82b9d3a3277b1b /Source/Android/app/src/main/java
parenta0f5bd51f15d2aff46ab3331b1201448db517409 (diff)
parentfd82f90fcea42c11435ce88a61cfe5dfd0d03f1a (diff)
Merge pull request #2664 from sigmabeta/android-load-animation
Android: Show transition animations on game start / end.
Diffstat (limited to 'Source/Android/app/src/main/java')
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java2
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java136
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java31
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java21
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/PlatformGamesFragment.java16
5 files changed, 187 insertions, 19 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java
index c9efb0c790..9fcdbe8cd1 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java
@@ -277,7 +277,7 @@ public final class NativeLibrary
public static void endEmulationActivity()
{
Log.v("DolphinEmu", "Ending EmulationActivity.");
- mEmulationActivity.finish();
+ mEmulationActivity.exitWithAnimation();
}
public static void setEmulationActivity(EmulationActivity emulationActivity)
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java
index d1e6f47273..6b27c08c4a 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java
@@ -12,6 +12,12 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewTreeObserver;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+import com.squareup.picasso.Callback;
+import com.squareup.picasso.Picasso;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
@@ -22,10 +28,15 @@ import java.util.List;
public final class EmulationActivity extends AppCompatActivity
{
private View mDecorView;
+ private ImageView mImageView;
+ private FrameLayout mFrameEmulation;
private boolean mDeviceHasTouchScreen;
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
* on the UI thread. This Handler responds to any message, even blank ones, by
@@ -39,12 +50,18 @@ public final class EmulationActivity extends AppCompatActivity
hideSystemUI();
}
};
+ private String mScreenPath;
+ private FrameLayout mFrameContent;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
+ // Picasso will take a while to load these big-ass screenshots. So don't run
+ // the animation until we say so.
+ postponeEnterTransition();
+
mDeviceHasTouchScreen = getPackageManager().hasSystemFeature("android.hardware.touchscreen");
// Get a handle to the Window containing the UI.
@@ -79,9 +96,57 @@ public final class EmulationActivity extends AppCompatActivity
setContentView(R.layout.activity_emulation);
+ mImageView = (ImageView) findViewById(R.id.image_screenshot);
+ mFrameContent = (FrameLayout) findViewById(R.id.frame_content);
+ mFrameEmulation = (FrameLayout) findViewById(R.id.frame_emulation_fragment);
+
Intent gameToEmulate = getIntent();
String path = gameToEmulate.getStringExtra("SelectedGame");
String title = gameToEmulate.getStringExtra("SelectedTitle");
+ mScreenPath = gameToEmulate.getStringExtra("ScreenPath");
+ mPosition = gameToEmulate.getIntExtra("GridPosition", -1);
+
+ Picasso.with(this)
+ .load(mScreenPath)
+ .noFade()
+ .noPlaceholder()
+ .into(mImageView, new Callback()
+ {
+ @Override
+ public void onSuccess()
+ {
+ scheduleStartPostponedTransition(mImageView);
+ }
+
+ @Override
+ public void onError()
+ {
+ // Still have to do this, or else the app will crash.
+ scheduleStartPostponedTransition(mImageView);
+ }
+ });
+
+ mImageView.animate()
+ .withLayer()
+ .setStartDelay(2000)
+ .setDuration(500)
+ .alpha(0.0f)
+ .withStartAction(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ mFrameEmulation.setVisibility(View.VISIBLE);
+ }
+ })
+ .withEndAction(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ mImageView.setVisibility(View.GONE);
+ }
+ });
setTitle(title);
@@ -90,7 +155,7 @@ public final class EmulationActivity extends AppCompatActivity
// Add fragment to the activity - this triggers all its lifecycle callbacks.
getFragmentManager().beginTransaction()
- .add(R.id.frame_content, emulationFragment, EmulationFragment.FRAGMENT_TAG)
+ .add(R.id.frame_emulation_fragment, emulationFragment, EmulationFragment.FRAGMENT_TAG)
.commit();
}
@@ -155,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
public boolean onCreateOptionsMenu(Menu menu)
{
@@ -324,4 +442,20 @@ public final class EmulationActivity extends AppCompatActivity
hideSystemUiAfterDelay();
}
+
+
+ private void scheduleStartPostponedTransition(final View sharedElement)
+ {
+ sharedElement.getViewTreeObserver().addOnPreDrawListener(
+ new ViewTreeObserver.OnPreDrawListener()
+ {
+ @Override
+ public boolean onPreDraw()
+ {
+ sharedElement.getViewTreeObserver().removeOnPreDrawListener(this);
+ startPostponedEnterTransition();
+ return true;
+ }
+ });
+ }
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java
index 7812e6ead5..33cd0b0c15 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java
@@ -36,6 +36,7 @@ import org.dolphinemu.dolphinemu.services.AssetCopyService;
public final class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>
{
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)
@@ -115,15 +116,29 @@ public final class MainActivity extends AppCompatActivity implements LoaderManag
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent result)
{
- // If the user picked a file, as opposed to just backing out.
- if (resultCode == RESULT_OK)
+ switch (requestCode)
{
- // Sanity check to make sure the Activity that just returned was the AddDirectoryActivity;
- // other activities might use this callback in the future (don't forget to change Javadoc!)
- if (requestCode == REQUEST_ADD_DIRECTORY)
- {
- refreshFragment();
- }
+ case REQUEST_ADD_DIRECTORY:
+ // If the user picked a file, as opposed to just backing out.
+ if (resultCode == RESULT_OK)
+ {
+ // Sanity check to make sure the Activity that just returned was the AddDirectoryActivity;
+ // other activities might use this callback in the future (don't forget to change Javadoc!)
+ if (requestCode == REQUEST_ADD_DIRECTORY)
+ {
+ 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);
+ }
}
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java
index a9a7be930e..e74bd6f96d 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java
@@ -1,9 +1,11 @@
package org.dolphinemu.dolphinemu.adapters;
import android.app.Activity;
+import android.app.ActivityOptions;
import android.content.Intent;
import android.database.Cursor;
import android.database.DataSetObserver;
+import android.graphics.Bitmap;
import android.graphics.Rect;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
@@ -15,6 +17,7 @@ import com.squareup.picasso.Picasso;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.activities.EmulationActivity;
+import org.dolphinemu.dolphinemu.activities.MainActivity;
import org.dolphinemu.dolphinemu.dialogs.GameDetailsDialog;
import org.dolphinemu.dolphinemu.model.GameDatabase;
import org.dolphinemu.dolphinemu.viewholders.GameViewHolder;
@@ -80,14 +83,15 @@ public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> impl
if (mCursor.moveToPosition(position))
{
String screenPath = mCursor.getString(GameDatabase.GAME_COLUMN_SCREENSHOT_PATH);
- Picasso.with(holder.imageScreenshot.getContext())
- .invalidate(screenPath);
// Fill in the view contents.
Picasso.with(holder.imageScreenshot.getContext())
.load(screenPath)
.fit()
.centerCrop()
+ .noFade()
+ .noPlaceholder()
+ .config(Bitmap.Config.RGB_565)
.error(R.drawable.no_banner)
.into(holder.imageScreenshot);
@@ -112,8 +116,6 @@ public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> impl
{
Log.e("DolphinEmu", "Can't bind view; dataset is not valid.");
}
-
-
}
/**
@@ -220,8 +222,17 @@ public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> impl
intent.putExtra("SelectedGame", holder.path);
intent.putExtra("SelectedTitle", holder.title);
+ intent.putExtra("ScreenPath", holder.screenshotPath);
+ intent.putExtra("GridPosition", holder.getAdapterPosition());
+
+ ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(
+ (Activity) view.getContext(),
+ holder.imageScreenshot,
+ "image_game_screenshot");
- view.getContext().startActivity(intent);
+ ((Activity) view.getContext()).startActivityForResult(intent,
+ MainActivity.REQUEST_EMULATE_GAME,
+ options.toBundle());
}
/**
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/PlatformGamesFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/PlatformGamesFragment.java
index 4957090ed3..c1d1b1c8e7 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/PlatformGamesFragment.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/PlatformGamesFragment.java
@@ -1,12 +1,12 @@
package org.dolphinemu.dolphinemu.fragments;
-import android.app.Activity;
import android.app.Fragment;
import android.app.LoaderManager;
import android.content.Loader;
import android.database.Cursor;
import android.os.Bundle;
import android.support.annotation.Nullable;
+import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
@@ -57,6 +57,15 @@ public class PlatformGamesFragment extends Fragment
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(),
getResources().getInteger(R.integer.game_grid_columns));
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));
@@ -70,10 +79,9 @@ public class PlatformGamesFragment extends Fragment
return rootView;
}
- @Override
- public void onAttach(Activity activity)
+ public void refreshScreenshotAtPosition(int position)
{
- super.onAttach(activity);
+ mAdapter.notifyItemChanged(position);
}
public void refresh()