Merge pull request #3491 from sigmabeta/android-mvp-platform-fragment

[Android] Refactor PlatformGamesFragment to MVP architecture
This commit is contained in:
Ryan Houdek 2016-01-10 21:35:39 -05:00
commit 77cef0c7bf
6 changed files with 209 additions and 129 deletions

View File

@ -11,7 +11,7 @@ import android.text.SpannableString;
import android.text.style.ImageSpan; import android.text.style.ImageSpan;
import org.dolphinemu.dolphinemu.R; import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.fragments.PlatformGamesFragment; import org.dolphinemu.dolphinemu.ui.platform.PlatformGamesFragment;
public class PlatformPagerAdapter extends FragmentPagerAdapter public class PlatformPagerAdapter extends FragmentPagerAdapter
{ {

View File

@ -1,123 +0,0 @@
package org.dolphinemu.dolphinemu.fragments;
import android.app.Fragment;
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;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.dolphinemu.dolphinemu.BuildConfig;
import org.dolphinemu.dolphinemu.DolphinApplication;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.adapters.GameAdapter;
import org.dolphinemu.dolphinemu.model.GameDatabase;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
public class PlatformGamesFragment extends Fragment
{
private static final String ARG_PLATFORM = BuildConfig.APPLICATION_ID + ".PLATFORM";
private int mPlatform;
private GameAdapter mAdapter;
public static PlatformGamesFragment newInstance(int platform)
{
PlatformGamesFragment fragment = new PlatformGamesFragment();
Bundle args = new Bundle();
args.putInt(ARG_PLATFORM, platform);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mPlatform = getArguments().getInt(ARG_PLATFORM);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_grid, container, false);
RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.grid_games);
// Specifying the LayoutManager determines how the RecyclerView arranges views.
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));
loadGames();
mAdapter = new GameAdapter();
recyclerView.setAdapter(mAdapter);
return rootView;
}
public void refreshScreenshotAtPosition(int position)
{
mAdapter.notifyItemChanged(position);
}
public void refresh()
{
Log.d("DolphinEmu", "[PlatformGamesFragment] " + mPlatform + ": Refreshing...");
loadGames();
}
public void loadGames()
{
Log.d("DolphinEmu", "[PlatformGamesFragment] " + mPlatform + ": Loading games...");
GameDatabase databaseHelper = DolphinApplication.databaseHelper;
databaseHelper.getGamesForPlatform(mPlatform)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Cursor>()
{
@Override
public void call(Cursor data)
{
Log.d("DolphinEmu", "[PlatformGamesFragment] " + mPlatform + ": Load finished, swapping cursor...");
if (mAdapter != null)
{
mAdapter.swapCursor(data);
}
else
{
Log.e("DolphinEmu", "[PlatformGamesFragment] " + mPlatform + ": No adapter available.");
}
}
}
);
}
}

View File

@ -18,8 +18,8 @@ import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.activities.AddDirectoryActivity; import org.dolphinemu.dolphinemu.activities.AddDirectoryActivity;
import org.dolphinemu.dolphinemu.activities.SettingsActivity; import org.dolphinemu.dolphinemu.activities.SettingsActivity;
import org.dolphinemu.dolphinemu.adapters.PlatformPagerAdapter; import org.dolphinemu.dolphinemu.adapters.PlatformPagerAdapter;
import org.dolphinemu.dolphinemu.fragments.PlatformGamesFragment;
import org.dolphinemu.dolphinemu.model.GameProvider; import org.dolphinemu.dolphinemu.model.GameProvider;
import org.dolphinemu.dolphinemu.ui.platform.PlatformGamesView;
import org.dolphinemu.dolphinemu.utils.StartupHandler; import org.dolphinemu.dolphinemu.utils.StartupHandler;
/** /**
@ -106,7 +106,7 @@ public final class MainActivity extends AppCompatActivity implements MainView
public void refreshFragmentScreenshot(int fragmentPosition) public void refreshFragmentScreenshot(int fragmentPosition)
{ {
// Invalidate Picasso image so that the new screenshot is animated in. // Invalidate Picasso image so that the new screenshot is animated in.
PlatformGamesFragment fragment = getPlatformFragment(mViewPager.getCurrentItem()); PlatformGamesView fragment = getPlatformGamesView(mViewPager.getCurrentItem());
if (fragment != null) if (fragment != null)
{ {
@ -159,7 +159,7 @@ public final class MainActivity extends AppCompatActivity implements MainView
private void refreshFragment() private void refreshFragment()
{ {
PlatformGamesFragment fragment = getPlatformFragment(mViewPager.getCurrentItem()); PlatformGamesView fragment = getPlatformGamesView(mViewPager.getCurrentItem());
if (fragment != null) if (fragment != null)
{ {
fragment.refresh(); fragment.refresh();
@ -167,10 +167,10 @@ public final class MainActivity extends AppCompatActivity implements MainView
} }
@Nullable @Nullable
private PlatformGamesFragment getPlatformFragment(int platform) private PlatformGamesView getPlatformGamesView(int platform)
{ {
String fragmentTag = "android:switcher:" + mViewPager.getId() + ":" + platform; String fragmentTag = "android:switcher:" + mViewPager.getId() + ":" + platform;
return (PlatformGamesFragment) getFragmentManager().findFragmentByTag(fragmentTag); return (PlatformGamesView) getFragmentManager().findFragmentByTag(fragmentTag);
} }
} }

View File

@ -0,0 +1,102 @@
package org.dolphinemu.dolphinemu.ui.platform;
import android.app.Fragment;
import android.database.Cursor;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.dolphinemu.dolphinemu.BuildConfig;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.adapters.GameAdapter;
public final class PlatformGamesFragment extends Fragment implements PlatformGamesView
{
private static final String ARG_PLATFORM = BuildConfig.APPLICATION_ID + ".PLATFORM";
private PlatformGamesPresenter mPresenter = new PlatformGamesPresenter(this);
private GameAdapter mAdapter;
private RecyclerView mRecyclerView;
public static PlatformGamesFragment newInstance(int platform)
{
PlatformGamesFragment fragment = new PlatformGamesFragment();
Bundle args = new Bundle();
args.putInt(ARG_PLATFORM, platform);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mPresenter.onCreate(getArguments().getInt(ARG_PLATFORM));
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_grid, container, false);
findViews(rootView);
mPresenter.onCreateView();
return rootView;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
int columns = getResources().getInteger(R.integer.game_grid_columns);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(), columns);
mAdapter = new GameAdapter();
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.addItemDecoration(new GameAdapter.SpacesItemDecoration(8));
}
@Override
public void refreshScreenshotAtPosition(int position)
{
mAdapter.notifyItemChanged(position);
}
@Override
public void refresh()
{
mPresenter.refresh();
}
@Override
public void onItemClick(String gameId)
{
// No-op for now
}
@Override
public void showGames(Cursor games)
{
if (mAdapter != null)
{
mAdapter.swapCursor(games);
}
}
private void findViews(View root)
{
mRecyclerView = (RecyclerView) root.findViewById(R.id.grid_games);
}
}

View File

@ -0,0 +1,62 @@
package org.dolphinemu.dolphinemu.ui.platform;
import android.database.Cursor;
import android.util.Log;
import org.dolphinemu.dolphinemu.DolphinApplication;
import org.dolphinemu.dolphinemu.model.GameDatabase;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
public final class PlatformGamesPresenter
{
private final PlatformGamesView mView;
private int mPlatform;
public PlatformGamesPresenter(PlatformGamesView view)
{
mView = view;
}
public void onCreate(int platform)
{
mPlatform = platform;
}
public void onCreateView()
{
loadGames();
}
public void refresh()
{
Log.d("DolphinEmu", "[PlatformGamesPresenter] " + mPlatform + ": Refreshing...");
loadGames();
}
private void loadGames()
{
Log.d("DolphinEmu", "[PlatformGamesPresenter] " + mPlatform + ": Loading games...");
GameDatabase databaseHelper = DolphinApplication.databaseHelper;
databaseHelper.getGamesForPlatform(mPlatform)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Cursor>()
{
@Override
public void call(Cursor games)
{
Log.d("DolphinEmu", "[PlatformGamesPresenter] " + mPlatform + ": Load finished, swapping cursor...");
mView.showGames(games);
}
}
);
}
}

View File

@ -0,0 +1,39 @@
package org.dolphinemu.dolphinemu.ui.platform;
import android.database.Cursor;
/**
* Abstraction for a screen representing a single platform's games.
*/
public interface PlatformGamesView
{
/**
* Tell the view to refresh its contents.
*/
void refresh();
/**
* Tell the view that a certain game's screenshot has been updated,
* and should be redrawn on-screen.
*
* @param position The index of the game that should be redrawn.
*/
void refreshScreenshotAtPosition(int position);
/**
* Pass a click event to the view's Presenter. Typically called from the
* view's list adapter.
*
* @param gameId The ID of the game that was clicked.
*/
void onItemClick(String gameId);
/**
* To be called when an asynchronous database read completes. Passes the
* result, in this case a {@link Cursor}, to the view.
*
* @param games A Cursor containing the games read from the database.
*/
void showGames(Cursor games);
}