SettingsActivityPresenter.java生成此错误:无法解析方法'setTitle(java.lang.Integer)'
如果我将SettingsActivityPresenter
扩展为Activity
,则会得到:尝试在null对象引用上调用虚拟方法'android.content.res.Resources android.content.Context.getResources()'。 android.content.ContextWrapper.getResources(ContextWrapper.java:89)
是否有一种无需扩展setTitle
就能使用Activity
的方法?或者,如果我必须扩展Activity
,该如何解决以上错误?
SettingsActivityPresenter.java:
package org.dolphinemu.dolphinemu.features.settings.ui;
import android.content.IntentFilter;
import android.os.Bundle;
import android.text.TextUtils;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization.DirectoryInitializationState;
import org.dolphinemu.dolphinemu.utils.DirectoryStateReceiver;
import org.dolphinemu.dolphinemu.utils.Log;
import java.util.HashMap;
import java.util.Map;
public final class SettingsActivityPresenter
{
private static final String KEY_SHOULD_SAVE = "should_save";
private SettingsActivityView mView;
private Settings mSettings = new Settings();
private int mStackCount;
private boolean mShouldSave;
private DirectoryStateReceiver directoryStateReceiver;
private MenuTag menuTag;
private String gameId;
private static final Map<MenuTag, Integer> titles = new HashMap<>();
static
{
titles.put(MenuTag.CONFIG, R.string.preferences_settings);
titles.put(MenuTag.CONFIG_GENERAL, R.string.general_submenu);
titles.put(MenuTag.CONFIG_INTERFACE, R.string.interface_submenu);
titles.put(MenuTag.CONFIG_GAME_CUBE, R.string.gamecube_submenu);
titles.put(MenuTag.CONFIG_WII, R.string.wii_submenu);
titles.put(MenuTag.WIIMOTE, R.string.grid_menu_wiimote_settings);
titles.put(MenuTag.WIIMOTE_EXTENSION, R.string.wiimote_extensions);
titles.put(MenuTag.GCPAD_TYPE, R.string.grid_menu_gcpad_settings);
titles.put(MenuTag.GRAPHICS, R.string.grid_menu_graphics_settings);
titles.put(MenuTag.HACKS, R.string.hacks_submenu);
titles.put(MenuTag.ENHANCEMENTS, R.string.enhancements_submenu);
titles.put(MenuTag.STEREOSCOPY, R.string.stereoscopy_submenu);
titles.put(MenuTag.GCPAD_1, R.string.controller_0);
titles.put(MenuTag.GCPAD_2, R.string.controller_1);
titles.put(MenuTag.GCPAD_3, R.string.controller_2);
titles.put(MenuTag.GCPAD_4, R.string.controller_3);
titles.put(MenuTag.WIIMOTE_1, R.string.wiimote_4);
titles.put(MenuTag.WIIMOTE_2, R.string.wiimote_5);
titles.put(MenuTag.WIIMOTE_3, R.string.wiimote_6);
titles.put(MenuTag.WIIMOTE_4, R.string.wiimote_7);
titles.put(MenuTag.WIIMOTE_EXTENSION_1, R.string.wiimote_extension_4);
titles.put(MenuTag.WIIMOTE_EXTENSION_2, R.string.wiimote_extension_5);
titles.put(MenuTag.WIIMOTE_EXTENSION_3, R.string.wiimote_extension_6);
titles.put(MenuTag.WIIMOTE_EXTENSION_4, R.string.wiimote_extension_7);
}
SettingsActivityPresenter(SettingsActivityView view)
{
mView = view;
}
public void onCreate(Bundle savedInstanceState, MenuTag menuTag, String gameId)
{
if (savedInstanceState == null)
{
this.menuTag = menuTag;
this.gameId = gameId;
}
else
{
mShouldSave = savedInstanceState.getBoolean(KEY_SHOULD_SAVE);
}
}
public void onStart()
{
prepareDolphinDirectoriesIfNeeded();
}
private void loadSettingsUI()
{
if (mSettings.isEmpty())
{
if (!TextUtils.isEmpty(gameId))
{
mSettings.loadSettings(gameId, mView);
}
else
{
mSettings.loadSettings(mView);
}
}
mView.showSettingsFragment(menuTag, null, false, gameId);
mView.onSettingsFileLoaded(mSettings);
}
private void prepareDolphinDirectoriesIfNeeded()
{
if (DirectoryInitialization.areDolphinDirectoriesReady())
{
loadSettingsUI();
}
else
{
mView.showLoading();
IntentFilter statusIntentFilter = new IntentFilter(
DirectoryInitialization.BROADCAST_ACTION);
directoryStateReceiver =
new DirectoryStateReceiver(directoryInitializationState ->
{
if (directoryInitializationState ==
DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED)
{
mView.hideLoading();
loadSettingsUI();
}
else if (directoryInitializationState ==
DirectoryInitializationState.EXTERNAL_STORAGE_PERMISSION_NEEDED)
{
mView.showPermissionNeededHint();
mView.hideLoading();
}
else if (directoryInitializationState ==
DirectoryInitializationState.CANT_FIND_EXTERNAL_STORAGE)
{
mView.showExternalStorageNotMountedHint();
mView.hideLoading();
}
});
mView.startDirectoryInitializationService(directoryStateReceiver, statusIntentFilter);
}
}
public void setSettings(Settings settings)
{
mSettings = settings;
}
public Settings getSettings()
{
return mSettings;
}
public void onStop(boolean finishing)
{
if (directoryStateReceiver != null)
{
mView.stopListeningToDirectoryInitializationService(directoryStateReceiver);
directoryStateReceiver = null;
}
if (mSettings != null && finishing && mShouldSave)
{
Log.debug("[SettingsActivity] Settings activity stopping. Saving settings to INI...");
mSettings.saveSettings(mView);
}
}
public void addToStack()
{
mStackCount++;
}
public void onBackPressed()
{
if (mStackCount > 0)
{
mView.popBackStack();
mStackCount--;
}
else
{
mView.finish();
}
if (titles.containsKey(menuTag))
{
setTitle(titles.get(menuTag));
}
}
public boolean handleOptionsItem(int itemId)
{
switch (itemId)
{
case R.id.menu_save_exit:
mView.finish();
return true;
}
return false;
}
public void onSettingChanged()
{
mShouldSave = true;
}
public void saveState(Bundle outState)
{
outState.putBoolean(KEY_SHOULD_SAVE, mShouldSave);
}
public void onGcPadSettingChanged(MenuTag key, int value)
{
if (value != 0) // Not disabled
{
Bundle bundle = new Bundle();
bundle.putInt(SettingsFragmentPresenter.ARG_CONTROLLER_TYPE, value / 6);
mView.showSettingsFragment(key, bundle, true, gameId);
}
}
public void onWiimoteSettingChanged(MenuTag menuTag, int value)
{
switch (value)
{
case 1:
mView.showSettingsFragment(menuTag, null, true, gameId);
break;
case 2:
mView.showToastMessage("Please make sure Continuous Scanning is enabled in Core Settings.");
break;
}
}
public void onExtensionSettingChanged(MenuTag menuTag, int value)
{
if (value != 0) // None
{
Bundle bundle = new Bundle();
bundle.putInt(SettingsFragmentPresenter.ARG_CONTROLLER_TYPE, value);
mView.showSettingsFragment(menuTag, bundle, true, gameId);
}
}
}
SettingsActivity.java:
package org.dolphinemu.dolphinemu.features.settings.ui;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
import org.dolphinemu.dolphinemu.utils.DirectoryStateReceiver;
import java.util.HashMap;
import java.util.Map;
public final class SettingsActivity extends AppCompatActivity implements SettingsActivityView
{
private static final String ARG_MENU_TAG = "menu_tag";
private static final String ARG_GAME_ID = "game_id";
private static final String FRAGMENT_TAG = "settings";
private SettingsActivityPresenter mPresenter = new SettingsActivityPresenter(this);
private ProgressDialog dialog;
private static final Map<MenuTag, Integer> titles = new HashMap<>();
static
{
titles.put(MenuTag.CONFIG, R.string.preferences_settings);
titles.put(MenuTag.CONFIG_GENERAL, R.string.general_submenu);
titles.put(MenuTag.CONFIG_INTERFACE, R.string.interface_submenu);
titles.put(MenuTag.CONFIG_GAME_CUBE, R.string.gamecube_submenu);
titles.put(MenuTag.CONFIG_WII, R.string.wii_submenu);
titles.put(MenuTag.WIIMOTE, R.string.grid_menu_wiimote_settings);
titles.put(MenuTag.WIIMOTE_EXTENSION, R.string.wiimote_extensions);
titles.put(MenuTag.GCPAD_TYPE, R.string.grid_menu_gcpad_settings);
titles.put(MenuTag.GRAPHICS, R.string.grid_menu_graphics_settings);
titles.put(MenuTag.HACKS, R.string.hacks_submenu);
titles.put(MenuTag.ENHANCEMENTS, R.string.enhancements_submenu);
titles.put(MenuTag.STEREOSCOPY, R.string.stereoscopy_submenu);
titles.put(MenuTag.GCPAD_1, R.string.controller_0);
titles.put(MenuTag.GCPAD_2, R.string.controller_1);
titles.put(MenuTag.GCPAD_3, R.string.controller_2);
titles.put(MenuTag.GCPAD_4, R.string.controller_3);
titles.put(MenuTag.WIIMOTE_1, R.string.wiimote_4);
titles.put(MenuTag.WIIMOTE_2, R.string.wiimote_5);
titles.put(MenuTag.WIIMOTE_3, R.string.wiimote_6);
titles.put(MenuTag.WIIMOTE_4, R.string.wiimote_7);
titles.put(MenuTag.WIIMOTE_EXTENSION_1, R.string.wiimote_extension_4);
titles.put(MenuTag.WIIMOTE_EXTENSION_2, R.string.wiimote_extension_5);
titles.put(MenuTag.WIIMOTE_EXTENSION_3, R.string.wiimote_extension_6);
titles.put(MenuTag.WIIMOTE_EXTENSION_4, R.string.wiimote_extension_7);
}
public static void launch(Context context, MenuTag menuTag, String gameId)
{
Intent settings = new Intent(context, SettingsActivity.class);
settings.putExtra(ARG_MENU_TAG, menuTag);
settings.putExtra(ARG_GAME_ID, gameId);
context.startActivity(settings);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
Intent launcher = getIntent();
String gameID = launcher.getStringExtra(ARG_GAME_ID);
MenuTag menuTag = (MenuTag) launcher.getSerializableExtra(ARG_MENU_TAG);
mPresenter.onCreate(savedInstanceState, menuTag, gameID);
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_settings, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
return mPresenter.handleOptionsItem(item.getItemId());
}
@Override
protected void onSaveInstanceState(Bundle outState)
{
// Critical: If super method is not called, rotations will be busted.
super.onSaveInstanceState(outState);
mPresenter.saveState(outState);
}
@Override
protected void onStart()
{
super.onStart();
mPresenter.onStart();
}
/**
* If this is called, the user has left the settings screen (potentially through the
* home button) and will expect their changes to be persisted. So we kick off an
* IntentService which will do so on a background thread.
*/
@Override
protected void onStop()
{
super.onStop();
mPresenter.onStop(isFinishing());
}
@Override
public void onBackPressed()
{
mPresenter.onBackPressed();
}
@Override
public void showSettingsFragment(MenuTag menuTag, Bundle extras, boolean addToStack,
String gameID)
{
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
if (addToStack)
{
if (areSystemAnimationsEnabled())
{
transaction.setCustomAnimations(
R.animator.settings_enter,
R.animator.settings_exit,
R.animator.settings_pop_enter,
R.animator.setttings_pop_exit);
}
transaction.addToBackStack(null);
mPresenter.addToStack();
}
transaction.replace(R.id.frame_content, SettingsFragment.newInstance(menuTag, gameID, extras),
FRAGMENT_TAG);
transaction.commit();
if (titles.containsKey(menuTag))
{
setTitle(titles.get(menuTag));
}
}
private boolean areSystemAnimationsEnabled()
{
float duration = Settings.Global.getFloat(
getContentResolver(),
Settings.Global.ANIMATOR_DURATION_SCALE, 1);
float transition = Settings.Global.getFloat(
getContentResolver(),
Settings.Global.TRANSITION_ANIMATION_SCALE, 1);
return duration != 0 && transition != 0;
}
@Override
public void startDirectoryInitializationService(DirectoryStateReceiver receiver,
IntentFilter filter)
{
LocalBroadcastManager.getInstance(this).registerReceiver(
receiver,
filter);
DirectoryInitialization.start(this);
}
@Override
public void stopListeningToDirectoryInitializationService(DirectoryStateReceiver receiver)
{
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
}
@Override
public void showLoading()
{
if (dialog == null)
{
dialog = new ProgressDialog(this);
dialog.setMessage(getString(R.string.load_settings));
dialog.setIndeterminate(true);
}
dialog.show();
}
@Override
public void hideLoading()
{
dialog.dismiss();
}
@Override
public void showPermissionNeededHint()
{
Toast.makeText(this, R.string.write_permission_needed, Toast.LENGTH_SHORT)
.show();
}
@Override
public void showExternalStorageNotMountedHint()
{
Toast.makeText(this, R.string.external_storage_not_mounted, Toast.LENGTH_SHORT)
.show();
}
@Override
public org.dolphinemu.dolphinemu.features.settings.model.Settings getSettings()
{
return mPresenter.getSettings();
}
@Override
public void setSettings(org.dolphinemu.dolphinemu.features.settings.model.Settings settings)
{
mPresenter.setSettings(settings);
}
@Override
public void onSettingsFileLoaded(
org.dolphinemu.dolphinemu.features.settings.model.Settings settings)
{
SettingsFragmentView fragment = getFragment();
if (fragment != null)
{
fragment.onSettingsFileLoaded(settings);
}
}
@Override
public void onSettingsFileNotFound()
{
SettingsFragmentView fragment = getFragment();
if (fragment != null)
{
fragment.loadDefaultSettings();
}
}
@Override
public void showToastMessage(String message)
{
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
@Override
public void popBackStack()
{
getSupportFragmentManager().popBackStackImmediate();
}
@Override
public void onSettingChanged()
{
mPresenter.onSettingChanged();
}
@Override
public void onGcPadSettingChanged(MenuTag key, int value)
{
mPresenter.onGcPadSettingChanged(key, value);
}
@Override
public void onWiimoteSettingChanged(MenuTag section, int value)
{
mPresenter.onWiimoteSettingChanged(section, value);
}
@Override
public void onExtensionSettingChanged(MenuTag menuTag, int value)
{
mPresenter.onExtensionSettingChanged(menuTag, value);
}
private SettingsFragment getFragment()
{
return (SettingsFragment) getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG);
}
}
SettingsActivityView.java:
package org.dolphinemu.dolphinemu.features.settings.ui;
import android.content.IntentFilter;
import android.os.Bundle;
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
import org.dolphinemu.dolphinemu.utils.DirectoryStateReceiver;
/**
* Abstraction for the Activity that manages SettingsFragments.
*/
public interface SettingsActivityView
{
/**
* Show a new SettingsFragment.
*
* @param menuTag Identifier for the settings group that should be displayed.
* @param addToStack Whether or not this fragment should replace a previous one.
*/
void showSettingsFragment(MenuTag menuTag, Bundle extras, boolean addToStack, String gameId);
/**
* Called by a contained Fragment to get access to the Setting HashMap
* loaded from disk, so that each Fragment doesn't need to perform its own
* read operation.
*
* @return A possibly null HashMap of Settings.
*/
Settings getSettings();
/**
* Used to provide the Activity with Settings HashMaps if a Fragment already
* has one; for example, if a rotation occurs, the Fragment will not be killed,
* but the Activity will, so the Activity needs to have its HashMaps resupplied.
*
* @param settings The ArrayList of all the Settings HashMaps.
*/
void setSettings(Settings settings);
/**
* Called when an asynchronous load operation completes.
*
* @param settings The (possibly null) result of the ini load operation.
*/
void onSettingsFileLoaded(Settings settings);
/**
* Called when an asynchronous load operation fails.
*/
void onSettingsFileNotFound();
/**
* Display a popup text message on screen.
*
* @param message The contents of the onscreen message.
*/
void showToastMessage(String message);
/**
* Show the previous fragment.
*/
void popBackStack();
/**
* End the activity.
*/
void finish();
/**
* Called by a containing Fragment to tell the Activity that a setting was changed;
* unless this has been called, the Activity will not save to disk.
*/
void onSettingChanged();
/**
* Called by a containing Fragment to tell the containing Activity that a GCPad's setting
* was modified.
*
* @param menuTag Identifier for the GCPad that was modified.
* @param value New setting for the GCPad.
*/
void onGcPadSettingChanged(MenuTag menuTag, int value);
/**
* Called by a containing Fragment to tell the containing Activity that a Wiimote's setting
* was modified.
*
* @param menuTag Identifier for Wiimote that was modified.
* @param value New setting for the Wiimote.
*/
void onWiimoteSettingChanged(MenuTag menuTag, int value);
/**
* Called by a containing Fragment to tell the containing Activity that an extension setting
* was modified.
*
* @param menuTag Identifier for the extension that was modified.
* @param value New setting for the extension.
*/
void onExtensionSettingChanged(MenuTag menuTag, int value);
/**
* Show loading dialog while loading the settings
*/
void showLoading();
/**
* Hide the loading the dialog
*/
void hideLoading();
/**
* Show a hint to the user that the app needs write to external storage access
*/
void showPermissionNeededHint();
/**
* Show a hint to the user that the app needs the external storage to be mounted
*/
void showExternalStorageNotMountedHint();
/**
* Start the DirectoryInitialization and listen for the result.
*
* @param receiver the broadcast receiver for the DirectoryInitialization
* @param filter the Intent broadcasts to be received.
*/
void startDirectoryInitializationService(DirectoryStateReceiver receiver, IntentFilter filter);
/**
* Stop listening to the DirectoryInitialization.
*
* @param receiver The broadcast receiver to unregister.
*/
void stopListeningToDirectoryInitializationService(DirectoryStateReceiver receiver);
}
答案 0 :(得分:1)
鉴于您发布的内容,我认为最好的方法是
1)将此方法添加到您的SettingsActivityView
界面中:
void setTitle(int titleId);
2)在您的SettingsActivityPresenter
中,每当您想更改标题时,请致电
mView.setTitle(R.string.foo);