Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android: Show transition animations on game start / end. #2664

Merged
merged 3 commits into from
Jul 1, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ public void run()
public static void endEmulationActivity()
{
Log.v("DolphinEmu", "Ending EmulationActivity.");
mEmulationActivity.finish();
mEmulationActivity.exitWithAnimation();
}

public static void setEmulationActivity(EmulationActivity emulationActivity)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
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;
Expand All @@ -22,10 +28,15 @@
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
Expand All @@ -39,12 +50,18 @@ public void handleMessage(Message msg)
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.
Expand Down Expand Up @@ -79,9 +96,57 @@ public void onSystemUiVisibilityChange(int flags)

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);

Expand All @@ -90,7 +155,7 @@ public void onSystemUiVisibilityChange(int flags)

// 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();
}

Expand Down Expand Up @@ -155,6 +220,59 @@ public void onBackPressed()
}
}

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)
{
Expand Down Expand Up @@ -324,4 +442,20 @@ private void showSystemUI()

hideSystemUiAfterDelay();
}


private void scheduleStartPostponedTransition(final View sharedElement)
{
sharedElement.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener()
{
@Override
public boolean onPreDraw()
{
sharedElement.getViewTreeObserver().removeOnPreDrawListener(this);
startPostponedEnterTransition();
return true;
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
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)
Expand Down Expand Up @@ -115,15 +116,29 @@ public void onClick(View view)
@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);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -15,6 +17,7 @@

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;
Expand Down Expand Up @@ -80,14 +83,15 @@ public void onBindViewHolder(GameViewHolder holder, int position)
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);

Expand All @@ -112,8 +116,6 @@ public void onBindViewHolder(GameViewHolder holder, int position)
{
Log.e("DolphinEmu", "Can't bind view; dataset is not valid.");
}


}

/**
Expand Down Expand Up @@ -220,8 +222,17 @@ public void onClick(View view)

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());
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -57,6 +57,15 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
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));

Expand All @@ -70,10 +79,9 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
return rootView;
}

@Override
public void onAttach(Activity activity)
public void refreshScreenshotAtPosition(int position)
{
super.onAttach(activity);
mAdapter.notifyItemChanged(position);
}

public void refresh()
Expand Down
16 changes: 15 additions & 1 deletion Source/Android/app/src/main/res/layout/activity_emulation.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/frame_content">
android:id="@+id/frame_content"
>

<FrameLayout
android:id="@+id/frame_emulation_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible"/>

<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/image_screenshot"
android:transitionName="image_game_screenshot"/>

</FrameLayout>
2 changes: 1 addition & 1 deletion Source/Android/app/src/main/res/layout/card_game.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
android:id="@+id/image_game_screen"
android:layout_width="match_parent"
android:layout_height="0dp"
android:transitionName="image_game_screen"
android:transitionName="image_game_screenshot"
android:layout_weight="1"
tools:src="@drawable/placeholder_screenshot"
tools:scaleType="centerCrop"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<transitionSet>
<changeImageTransform/>
</transitionSet>