Android TV: Add settings row, enabling access to other screens.

This commit is contained in:
sigmabeta 2015-07-20 22:46:12 -04:00 committed by sigmabeta
parent 0b1212b77d
commit 245b58124e
11 changed files with 232 additions and 48 deletions

View File

@ -50,8 +50,8 @@ public final class EmulationActivity extends AppCompatActivity
private boolean mSystemUiVisible;
private boolean mMenuVisible;
private static Interpolator sDecelerator = new DecelerateInterpolator();
private static Interpolator sAccelerator = new AccelerateInterpolator();
private static final Interpolator sDecelerator = new DecelerateInterpolator();
private static final Interpolator sAccelerator = new AccelerateInterpolator();
/**
* Handlers are a way to pass a message to an Activity telling it to do something

View File

@ -35,7 +35,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_ADD_DIRECTORY = 1;
public static final int REQUEST_EMULATE_GAME = 2;
/**
@ -139,6 +139,7 @@ public final class MainActivity extends AppCompatActivity implements LoaderManag
{
fragment.refreshScreenshotAtPosition(resultCode);
}
break;
}
}

View File

@ -17,12 +17,15 @@ import android.support.v17.leanback.widget.OnItemViewClickedListener;
import android.support.v17.leanback.widget.Presenter;
import android.support.v17.leanback.widget.Row;
import android.support.v17.leanback.widget.RowPresenter;
import android.widget.Toast;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.adapters.GamePresenter;
import org.dolphinemu.dolphinemu.adapters.GameRowPresenter;
import org.dolphinemu.dolphinemu.adapters.SettingsRowPresenter;
import org.dolphinemu.dolphinemu.model.Game;
import org.dolphinemu.dolphinemu.model.GameDatabase;
import org.dolphinemu.dolphinemu.model.GameProvider;
import org.dolphinemu.dolphinemu.model.TvSettingsItem;
import org.dolphinemu.dolphinemu.viewholders.TvGameViewHolder;
public final class TvMainActivity extends Activity
@ -55,6 +58,41 @@ public final class TvMainActivity extends Activity
{
@Override
public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row)
{
// Special case: user clicked on a settings row item.
if (item instanceof TvSettingsItem)
{
TvSettingsItem settingsItem = (TvSettingsItem) item;
switch (settingsItem.getItemId())
{
case R.id.menu_refresh:
getContentResolver().insert(GameProvider.URI_REFRESH, null);
// TODO Let the Activity know the data is refreshed in some other, better way.
recreate();
break;
case R.id.menu_settings:
// Launch the Settings Actvity.
Intent settings = new Intent(TvMainActivity.this, SettingsActivity.class);
startActivity(settings);
break;
case R.id.button_add_directory:
Intent fileChooser = new Intent(TvMainActivity.this, AddDirectoryActivity.class);
// The second argument to this method is read below in onActivityResult().
startActivityForResult(fileChooser, MainActivity.REQUEST_ADD_DIRECTORY);
break;
default:
Toast.makeText(TvMainActivity.this, "Unimplemented menu option.", Toast.LENGTH_SHORT).show();
break;
}
}
else
{
TvGameViewHolder holder = (TvGameViewHolder) itemViewHolder;
// Start the emulation activity and send the path of the clicked ISO to it.
@ -71,9 +109,38 @@ public final class TvMainActivity extends Activity
startActivity(intent, options.toBundle());
}
}
});
}
/**
* Callback from AddDirectoryActivity. Applies any changes necessary to the GameGridActivity.
*
* @param requestCode An int describing whether the Activity that is returning did so successfully.
* @param resultCode An int describing what Activity is giving us this callback.
* @param result The information the returning Activity is providing us.
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent result)
{
switch (requestCode)
{
case MainActivity.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 == MainActivity.REQUEST_ADD_DIRECTORY)
{
// TODO Let the Activity know the data is refreshed in some other, better way.
recreate();
}
}
break;
}
}
private void buildRowsAdapter()
{
mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
@ -90,13 +157,16 @@ public final class TvMainActivity extends Activity
}
}
ListRow settingsRow = buildSettingsRow();
mRowsAdapter.add(settingsRow);
mBrowseFragment.setAdapter(mRowsAdapter);
}
private ListRow buildGamesRow(int platform)
{
// Create an adapter for this row.
CursorObjectAdapter row = new CursorObjectAdapter(new GamePresenter(platform));
CursorObjectAdapter row = new CursorObjectAdapter(new GameRowPresenter());
Cursor games;
if (platform == Game.PLATFORM_ALL)
@ -175,8 +245,25 @@ public final class TvMainActivity extends Activity
return new ListRow(header, row);
}
/*private ListRow buildSettingsRow()
private ListRow buildSettingsRow()
{
ArrayObjectAdapter rowItems = new ArrayObjectAdapter(new SettingsRowPresenter());
}*/
rowItems.add(new TvSettingsItem(R.id.menu_refresh,
R.drawable.ic_refresh_tv,
R.string.grid_menu_refresh));
rowItems.add(new TvSettingsItem(R.id.menu_settings,
R.drawable.ic_settings_tv,
R.string.grid_menu_settings));
rowItems.add(new TvSettingsItem(R.id.button_add_directory,
R.drawable.ic_add_tv,
R.string.add_directory_title));
// Create a header for this row.
HeaderItem header = new HeaderItem(R.string.settings, getString(R.string.settings));
return new ListRow(header, rowItems);
}
}

View File

@ -16,15 +16,8 @@ import org.dolphinemu.dolphinemu.viewholders.TvGameViewHolder;
* The Leanback library / docs call this a Presenter, but it works very
* similarly to a RecyclerView.ViewHolder.
*/
public final class GamePresenter extends Presenter
public final class GameRowPresenter extends Presenter
{
private int mPlatform;
public GamePresenter(int platform)
{
mPlatform = platform;
}
public ViewHolder onCreateViewHolder(ViewGroup parent)
{
// Create a new view.
@ -80,6 +73,25 @@ public final class GamePresenter extends Presenter
holder.country = game.getCountry();
holder.company = game.getCompany();
holder.screenshotPath = game.getScreenshotPath();
switch (game.getPlatform())
{
case Game.PLATFORM_GC:
holder.cardParent.setTag(R.color.dolphin_accent_gamecube);
break;
case Game.PLATFORM_WII:
holder.cardParent.setTag(R.color.dolphin_accent_wii);
break;
case Game.PLATFORM_WII_WARE:
holder.cardParent.setTag(R.color.dolphin_accent_wiiware);
break;
default:
holder.cardParent.setTag(android.R.color.holo_red_dark);
break;
}
}
public void onUnbindViewHolder(ViewHolder viewHolder)
@ -93,24 +105,8 @@ public final class GamePresenter extends Presenter
if (selected)
{
switch (mPlatform)
{
case Game.PLATFORM_GC:
backgroundColor = R.color.dolphin_accent_gamecube;
break;
case Game.PLATFORM_WII:
backgroundColor = R.color.dolphin_accent_wii;
break;
case Game.PLATFORM_WII_WARE:
backgroundColor = R.color.dolphin_accent_wiiware;
break;
default:
backgroundColor = android.R.color.holo_red_dark;
break;
}
// TODO: 7/20/15 Try using view tag to set color
backgroundColor = (int) view.getTag();
}
else
{

View File

@ -0,0 +1,47 @@
package org.dolphinemu.dolphinemu.adapters;
import android.content.res.Resources;
import android.support.v17.leanback.widget.ImageCardView;
import android.support.v17.leanback.widget.Presenter;
import android.view.ViewGroup;
import org.dolphinemu.dolphinemu.model.TvSettingsItem;
import org.dolphinemu.dolphinemu.viewholders.TvSettingsViewHolder;
public final class SettingsRowPresenter extends Presenter
{
public Presenter.ViewHolder onCreateViewHolder(ViewGroup parent)
{
// Create a new view.
ImageCardView settingsCard = new ImageCardView(parent.getContext());
settingsCard.setMainImageAdjustViewBounds(true);
settingsCard.setMainImageDimensions(192, 160);
settingsCard.setFocusable(true);
settingsCard.setFocusableInTouchMode(true);
// Use that view to create a ViewHolder.
return new TvSettingsViewHolder(settingsCard);
}
public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item)
{
TvSettingsViewHolder holder = (TvSettingsViewHolder) viewHolder;
TvSettingsItem settingsItem = (TvSettingsItem) item;
Resources resources = holder.cardParent.getResources();
holder.itemId = settingsItem.getItemId();
holder.cardParent.setTitleText(resources.getString(settingsItem.getLabelId()));
holder.cardParent.setMainImage(resources.getDrawable(settingsItem.getIconId(), null));
}
public void onUnbindViewHolder(Presenter.ViewHolder viewHolder)
{
// no op
}
}

View File

@ -0,0 +1,31 @@
package org.dolphinemu.dolphinemu.model;
public final class TvSettingsItem
{
private final int mItemId;
private final int mIconId;
private final int mLabelId;
public TvSettingsItem(int itemId, int iconId, int labelId)
{
mItemId = itemId;
mIconId = iconId;
mLabelId = labelId;
}
public int getItemId()
{
return mItemId;
}
public int getIconId()
{
return mIconId;
}
public int getLabelId()
{
return mLabelId;
}
}

View File

@ -4,19 +4,16 @@ import android.support.v17.leanback.widget.ImageCardView;
import android.support.v17.leanback.widget.Presenter;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
/**
* A simple class that stores references to views so that the GameAdapter doesn't need to
* keep calling findViewById(), which is expensive.
*/
public class TvGameViewHolder extends Presenter.ViewHolder
public final class TvGameViewHolder extends Presenter.ViewHolder
{
public ImageCardView cardParent;
public ImageView imageScreenshot;
public TextView textGameTitle;
public TextView textCompany;
public String gameId;
@ -28,6 +25,8 @@ public class TvGameViewHolder extends Presenter.ViewHolder
public String company;
public String screenshotPath;
public int backgroundColor;
public TvGameViewHolder(View itemView)
{
super(itemView);

View File

@ -0,0 +1,23 @@
package org.dolphinemu.dolphinemu.viewholders;
import android.support.v17.leanback.widget.ImageCardView;
import android.support.v17.leanback.widget.Presenter;
import android.view.View;
public final class TvSettingsViewHolder extends Presenter.ViewHolder
{
public ImageCardView cardParent;
// Determines what action to take when this item is clicked.
public int itemId;
public TvSettingsViewHolder(View itemView)
{
super(itemView);
itemView.setTag(this);
cardParent = (ImageCardView) itemView;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB