From bfdc1e0e601a85db973adc49215e5c77719e2d7e Mon Sep 17 00:00:00 2001 From: Lioncash Date: Thu, 31 Oct 2013 04:00:33 -0400 Subject: [PATCH] [Android] Move the main activity to use Fragments. Cleaned up the main activity as well. --- android/phoenix/AndroidManifest.xml | 2 +- .../phoenix/res/layout/main_menu_layout.xml | 12 ++ android/phoenix/res/values/strings.xml | 1 + .../com/retroarch/browser/CoreSelection.java | 1 + .../retroarch/browser/HistorySelection.java | 1 + .../{ => mainmenu}/MainMenuActivity.java | 83 ++++------ .../browser/mainmenu/MainMenuFragment.java | 21 +++ .../util/PreferenceListFragment.java | 147 +++++++++++++----- 8 files changed, 182 insertions(+), 86 deletions(-) create mode 100644 android/phoenix/res/layout/main_menu_layout.xml rename android/phoenix/src/com/retroarch/browser/{ => mainmenu}/MainMenuActivity.java (83%) create mode 100644 android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuFragment.java diff --git a/android/phoenix/AndroidManifest.xml b/android/phoenix/AndroidManifest.xml index b9d2f1061e..3fffa73921 100644 --- a/android/phoenix/AndroidManifest.xml +++ b/android/phoenix/AndroidManifest.xml @@ -18,7 +18,7 @@ - + diff --git a/android/phoenix/res/layout/main_menu_layout.xml b/android/phoenix/res/layout/main_menu_layout.xml new file mode 100644 index 0000000000..2136cb2d95 --- /dev/null +++ b/android/phoenix/res/layout/main_menu_layout.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/android/phoenix/res/values/strings.xml b/android/phoenix/res/values/strings.xml index b909b60509..4fcf64202b 100644 --- a/android/phoenix/res/values/strings.xml +++ b/android/phoenix/res/values/strings.xml @@ -12,6 +12,7 @@ RetroArch - Main Menu + Asset Extraction TV Mode Load Core Load Game diff --git a/android/phoenix/src/com/retroarch/browser/CoreSelection.java b/android/phoenix/src/com/retroarch/browser/CoreSelection.java index ac4f230875..ad5337bf15 100644 --- a/android/phoenix/src/com/retroarch/browser/CoreSelection.java +++ b/android/phoenix/src/com/retroarch/browser/CoreSelection.java @@ -1,6 +1,7 @@ package com.retroarch.browser; import com.retroarch.R; +import com.retroarch.browser.mainmenu.MainMenuActivity; import com.retroarch.browser.preferences.util.ConfigFile; import com.retroarch.browser.preferences.util.UserPreferences; diff --git a/android/phoenix/src/com/retroarch/browser/HistorySelection.java b/android/phoenix/src/com/retroarch/browser/HistorySelection.java index 8fe525614e..97f7f98199 100644 --- a/android/phoenix/src/com/retroarch/browser/HistorySelection.java +++ b/android/phoenix/src/com/retroarch/browser/HistorySelection.java @@ -7,6 +7,7 @@ import java.io.IOException; import java.io.InputStreamReader; import com.retroarch.R; +import com.retroarch.browser.mainmenu.MainMenuActivity; import com.retroarch.browser.preferences.util.UserPreferences; import android.app.ListActivity; diff --git a/android/phoenix/src/com/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuActivity.java similarity index 83% rename from android/phoenix/src/com/retroarch/browser/MainMenuActivity.java rename to android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuActivity.java index a61fa3ff76..2496193249 100644 --- a/android/phoenix/src/com/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuActivity.java @@ -1,10 +1,13 @@ -package com.retroarch.browser; +package com.retroarch.browser.mainmenu; import java.io.*; import com.retroarch.R; +import com.retroarch.browser.NativeInterface; +import com.retroarch.browser.RetroActivity; import com.retroarch.browser.preferences.util.UserPreferences; +import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; @@ -16,34 +19,38 @@ import android.media.AudioManager; import android.os.Build; import android.os.Bundle; import android.os.Handler; -import android.preference.PreferenceActivity; +import android.preference.PreferenceManager; import android.provider.Settings; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentActivity; +import android.support.v4.app.FragmentManager; import android.util.Log; import android.widget.Toast; -public final class MainMenuActivity extends PreferenceActivity { +/** + * Class representing the {@link FragmentActivity} for the main menu. + */ +public final class MainMenuActivity extends FragmentActivity { private static MainMenuActivity instance = null; - private static final int ACTIVITY_LOAD_ROM = 0; - private static final int ACTIVITY_RETROARCH = 1; private static final String TAG = "MainMenu"; - private static String libretro_path; - private static String libretro_name; @Override - @SuppressWarnings("deprecation") public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - // Load the main menu XML. - addPreferencesFromResource(R.xml.main_menu); + // Set the content view. This will give us the FrameLayout to switch fragments in and out of. + setContentView(R.layout.main_menu_layout); + + // Show the main UI for this FragmentActivity. + final Fragment mainMenuFragment = new MainMenuFragment(); + final FragmentManager fm = getSupportFragmentManager(); + fm.beginTransaction().replace(R.id.content_frame, mainMenuFragment).commit(); // Cache an instance of this class (TODO: Bad practice, kill this somehow). instance = this; // Get libretro path and name. SharedPreferences prefs = UserPreferences.getPreferences(this); - libretro_path = prefs.getString("libretro_path", getApplicationInfo().dataDir + "/cores"); - libretro_name = prefs.getString("libretro_name", getString(R.string.no_core)); // Bind audio stream to hardware controls. setVolumeControlStream(AudioManager.STREAM_MUSIC); @@ -66,8 +73,7 @@ public final class MainMenuActivity extends PreferenceActivity { Intent startedByIntent = getIntent(); if (startedByIntent.getStringExtra("ROM") != null && startedByIntent.getStringExtra("LIBRETRO") != null) { if (savedInstanceState == null || !savedInstanceState.getBoolean("romexec")) - loadRomExternal(startedByIntent.getStringExtra("ROM"), - startedByIntent.getStringExtra("LIBRETRO")); + loadRomExternal(startedByIntent.getStringExtra("ROM"), startedByIntent.getStringExtra("LIBRETRO")); else finish(); } @@ -105,7 +111,7 @@ public final class MainMenuActivity extends PreferenceActivity { cacheStream.close(); if (currentCacheVersion == version) { - Log.i("ASSETS", "Assets already extracted, skipping..."); + Log.i(TAG, "Assets already extracted, skipping..."); return true; } } @@ -148,7 +154,7 @@ public final class MainMenuActivity extends PreferenceActivity { final Handler handler = new Handler(); dialog.setContentView(R.layout.assets); dialog.setCancelable(false); - dialog.setTitle("Asset extraction"); + dialog.setTitle(R.string.asset_extraction); // Java is fun :) Thread assetsThread = new Thread(new Runnable() { @@ -169,8 +175,8 @@ public final class MainMenuActivity extends PreferenceActivity { public void setModule(String core_path, String core_name) { UserPreferences.updateConfigFile(this); - libretro_path = core_path; - libretro_name = core_name; + String libretro_path = core_path; + String libretro_name = core_name; SharedPreferences prefs = UserPreferences.getPreferences(this); SharedPreferences.Editor edit = prefs.edit(); @@ -180,7 +186,6 @@ public final class MainMenuActivity extends PreferenceActivity { // Set the title section to contain the name of the selected core. setCoreTitle(libretro_name); - } public void setCoreTitle(String core_name) { @@ -308,10 +313,15 @@ public final class MainMenuActivity extends PreferenceActivity { @Override public void startActivity(Intent intent) { - if (intent.getComponent().getClassName() - .equals("com.retroarch.browser.diractivities.ROMActivity")) { - if (!new File(libretro_path).isDirectory()) { - super.startActivityForResult(intent, ACTIVITY_LOAD_ROM); + final SharedPreferences sPrefs = PreferenceManager.getDefaultSharedPreferences(this); + final String corePath = sPrefs.getString("libretro_path", ""); + + // If ROMActivity is attempting to be accessed. + if (intent.getComponent().getClassName().equals("com.retroarch.browser.diractivities.ROMActivity")) { + // If the path for a core hasn't been set yet, prompt the user to do so. + // otherwise, launch the activity to browse for a ROM to load. + if (!new File(corePath).isDirectory()) { + startActivity(intent); } else { Toast.makeText(this, R.string.load_a_core_first, Toast.LENGTH_SHORT).show(); } @@ -320,33 +330,6 @@ public final class MainMenuActivity extends PreferenceActivity { } } - @Override - protected void onActivityResult(int reqCode, int resCode, Intent data) { - switch (reqCode) { - case ACTIVITY_LOAD_ROM: { - if (data.getStringExtra("PATH") != null) { - UserPreferences.updateConfigFile(this); - String current_ime = Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); - Toast.makeText(this,String.format(getString(R.string.loading_data), data.getStringExtra("PATH")), Toast.LENGTH_SHORT).show(); - Intent myIntent = new Intent(this, RetroActivity.class); - myIntent.putExtra("ROM", data.getStringExtra("PATH")); - myIntent.putExtra("LIBRETRO", libretro_path); - myIntent.putExtra("CONFIGFILE", UserPreferences.getDefaultConfigPath(this)); - myIntent.putExtra("IME", current_ime); - startActivityForResult(myIntent, ACTIVITY_RETROARCH); - } - break; - } - - case ACTIVITY_RETROARCH: { - Log.i(TAG, "RetroArch finished running."); - UserPreferences.readbackConfigFile(this); - break; - } - - } - } - @Override protected void onSaveInstanceState(Bundle data) { super.onSaveInstanceState(data); diff --git a/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuFragment.java b/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuFragment.java new file mode 100644 index 0000000000..abd423abdf --- /dev/null +++ b/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuFragment.java @@ -0,0 +1,21 @@ +package com.retroarch.browser.mainmenu; + +import android.os.Bundle; + +import com.retroarch.R; +import com.retroarch.browser.preferences.fragments.util.PreferenceListFragment; + +/** + * Fragment that represents the main menu. + */ +public class MainMenuFragment extends PreferenceListFragment +{ + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + + // Load the XML for the main menu. + this.addPreferencesFromResource(R.xml.main_menu); + } +} diff --git a/android/phoenix/src/com/retroarch/browser/preferences/fragments/util/PreferenceListFragment.java b/android/phoenix/src/com/retroarch/browser/preferences/fragments/util/PreferenceListFragment.java index 05e0e23d5f..e6a80c0165 100644 --- a/android/phoenix/src/com/retroarch/browser/preferences/fragments/util/PreferenceListFragment.java +++ b/android/phoenix/src/com/retroarch/browser/preferences/fragments/util/PreferenceListFragment.java @@ -18,22 +18,23 @@ import android.support.v4.app.ListFragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.view.ViewParent; import android.widget.ListView; public class PreferenceListFragment extends ListFragment { + private static final String PREFERENCES_TAG = "android:preferences"; private PreferenceManager mPreferenceManager; - private ListView lv; - private int xmlId; + private ListView mList; + private boolean mHavePrefs; + private boolean mInitDone; /** * The starting request code given out to preference framework. */ private static final int FIRST_REQUEST_CODE = 100; - private static final int MSG_BIND_PREFERENCES = 0; - private Handler mHandler = new Handler() + private static final int MSG_BIND_PREFERENCES = 1; + private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) @@ -47,21 +48,22 @@ public class PreferenceListFragment extends ListFragment } }; - //must be provided - public PreferenceListFragment() + private final Runnable mRequestFocus = new Runnable() { - } - - public PreferenceListFragment(int xmlId) - { - this.xmlId = xmlId; - } + @Override + public void run() + { + mList.focusableViewAvailable(mList); + } + }; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle b) { - postBindPreferences(); - return lv; + View view = inflater.inflate(R.layout.preference_list_content, container, false); + view.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); + + return view; } @Override @@ -69,9 +71,39 @@ public class PreferenceListFragment extends ListFragment { super.onDestroyView(); - ViewParent p = lv.getParent(); - if(p != null) - ((ViewGroup)p).removeView(lv); + // Kill the list + mList = null; + + // Remove callbacks and messages. + mHandler.removeCallbacks(mRequestFocus); + mHandler.removeMessages(MSG_BIND_PREFERENCES); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) + { + super.onActivityCreated(savedInstanceState); + + if (mHavePrefs) + { + bindPreferences(); + } + + // Done initializing. + mInitDone = true; + + if (savedInstanceState != null) + { + Bundle container = savedInstanceState.getBundle(PREFERENCES_TAG); + if (container != null) + { + final PreferenceScreen preferenceScreen = getPreferenceScreen(); + if (preferenceScreen != null) + { + preferenceScreen.restoreHierarchyState(container); + } + } + } } @Override @@ -79,13 +111,8 @@ public class PreferenceListFragment extends ListFragment { super.onCreate(savedInstanceState); - if(savedInstanceState != null) - xmlId = savedInstanceState.getInt("xml"); - mPreferenceManager = onCreatePreferenceManager(); - lv = (ListView) LayoutInflater.from(getActivity()).inflate(R.layout.preference_list_content, null); - lv.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); - addPreferencesFromResource(xmlId); + postBindPreferences(); } @@ -111,7 +138,6 @@ public class PreferenceListFragment extends ListFragment { super.onDestroy(); - lv = null; try { Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityDestroy"); @@ -127,8 +153,15 @@ public class PreferenceListFragment extends ListFragment @Override public void onSaveInstanceState(Bundle outState) { - outState.putInt("xml", xmlId); super.onSaveInstanceState(outState); + + final PreferenceScreen preferenceScreen = getPreferenceScreen(); + if (preferenceScreen != null) + { + Bundle container = new Bundle(); + preferenceScreen.saveHierarchyState(container); + outState.putBundle(PREFERENCES_TAG, container); + } } @Override @@ -156,7 +189,11 @@ public class PreferenceListFragment extends ListFragment */ private void postBindPreferences() { - if (mHandler.hasMessages(MSG_BIND_PREFERENCES)) return; + if (mHandler.hasMessages(MSG_BIND_PREFERENCES)) + { + return; + } + mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget(); } @@ -165,14 +202,14 @@ public class PreferenceListFragment extends ListFragment final PreferenceScreen preferenceScreen = getPreferenceScreen(); if (preferenceScreen != null) { - preferenceScreen.bind(lv); + preferenceScreen.bind(getListView()); } } /** * Creates the {@link PreferenceManager}. * - * @return The {@link PreferenceManager} used by this activity. + * @return The {@link PreferenceManager} used by this fragment. */ private PreferenceManager onCreatePreferenceManager() { @@ -180,7 +217,8 @@ public class PreferenceListFragment extends ListFragment { Constructor c = PreferenceManager.class.getDeclaredConstructor(Activity.class, int.class); c.setAccessible(true); - PreferenceManager preferenceManager = c.newInstance(this.getActivity(), FIRST_REQUEST_CODE); + + PreferenceManager preferenceManager = c.newInstance(getActivity(), FIRST_REQUEST_CODE); return preferenceManager; } catch(Exception e) @@ -191,8 +229,9 @@ public class PreferenceListFragment extends ListFragment } /** - * Returns the {@link PreferenceManager} used by this activity. - * @return The {@link PreferenceManager}. + * Gets the {@link PreferenceManager} used by this fragment. + * + * @return The {@link PreferenceManager} used by this fragment. */ public PreferenceManager getPreferenceManager() { @@ -200,7 +239,7 @@ public class PreferenceListFragment extends ListFragment } /** - * Sets the root of the preference hierarchy that this activity is showing. + * Sets the root of the preference hierarchy that this fragment is showing. * * @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy. */ @@ -213,7 +252,11 @@ public class PreferenceListFragment extends ListFragment boolean result = (Boolean) m.invoke(mPreferenceManager, preferenceScreen); if (result && preferenceScreen != null) { - postBindPreferences(); + mHavePrefs = true; + if (mInitDone) + { + postBindPreferences(); + } } } catch(Exception e) @@ -223,7 +266,7 @@ public class PreferenceListFragment extends ListFragment } /** - * Gets the root of the preference hierarchy that this activity is showing. + * Gets the root of the preference hierarchy that this fragment is showing. * * @return The {@link PreferenceScreen} that is the root of the preference * hierarchy. @@ -292,4 +335,38 @@ public class PreferenceListFragment extends ListFragment return mPreferenceManager.findPreference(key); } + + public ListView getListView() + { + ensureList(); + return mList; + } + + private void ensureList() + { + if (mList != null) + { + return; + } + + final View root = getView(); + if (root == null) + { + throw new IllegalStateException("Content view not yet created"); + } + + final View rawListView = root.findViewById(android.R.id.list); + if (!(rawListView instanceof ListView)) + { + throw new RuntimeException("Content has view with id attribute 'android.R.id.list' that is not a ListView class"); + } + + mList = (ListView)rawListView; + if (mList == null) + { + throw new RuntimeException("Your content must have a ListView whose id attribute is 'android.R.id.list'"); + } + + mHandler.post(mRequestFocus); + } } \ No newline at end of file