Android - 画面上のダイアログの向きの変更に対処する
-
26-09-2019 - |
質問
onCreateDialog メソッドと onPrepareDialog メソッド、または Dialog クラスをオーバーライドしています。
Reto Meier の『プロフェッショナル Android アプリケーション開発』の第 5 章の例に従って、XML データを取得し、ダイアログを使用して情報を表示しました。
基本的にはこれに正確に従いましたが、独自の XML スキーマに合わせて変数を次のように変更しました。
@Override
public Dialog onCreateDialog(int id) {
switch(id) {
case (SETTINGS_DIALOG) :
LayoutInflater li = LayoutInflater.from(this);
View settingsDetailsView = li.inflate(R.layout.details, null);
AlertDialog.Builder settingsDialog = new AlertDialog.Builder(this);
settingsDialog.setTitle("Provisioned Settings");
settingsDialog.setView(settingsDetailsView);
return settingsDialog.create();
}
return null;
}
@Override
public void onPrepareDialog(int id, Dialog dialog) {
switch(id) {
case (SETTINGS_DIALOG) :
String afpunText = " ";
if(setting.getAddForPublicUserNames() == 1){
afpunText = "Yes";
}
else{
afpunText = "No";
}
String Text = "Login Settings: " + "\n"
+ "Password: " + setting.getPassword() + "\n"
+ "Server: " + setting.getServerAddress() + "\n";
AlertDialog settingsDialog = (AlertDialog)dialog;
settingsDialog.setTitle(setting.getUserName());
tv = (TextView)settingsDialog.findViewById(R.id.detailsTextView);
if (tv != null)
tv.setText(Text);
break;
}
}
画面の向きを変更してみるまでは正常に動作します。これを行うと、onPrepareDialog が呼び出されますが、すべての変数で null ポインター例外が発生します。
マニフェストで画面の向きを無視するようにアクティビティに指示した場合でも、エラーが発生します。
それで、本の例から何かが抜け落ちていると思いますが、変数を保存するために別のメソッドをオーバーライドする必要がありますか?
現在、次の内容を追加しました。
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save UI state changes to the savedInstanceState.
// This bundle will be passed to onCreate if the process is
// killed and restarted.
savedInstanceState.putString("Username", setting.getUserName());
savedInstanceState.putString("Password", setting.getPassword());
savedInstanceState.putString("Server", setting.getServerAddress());
super.onSaveInstanceState(savedInstanceState);
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
settings.clear();
// Restore UI state from the savedInstanceState.
// This bundle has also been passed to onCreate.
username = savedInstanceState.getString("Username");
password = savedInstanceState.getString("Password");
serveraddress = savedInstanceState.getString("Server");
Settings setting = new Settings(username, password, serveraddress);
addNewSettings(setting);
}
しかし、依然として Null Pointer 例外が発生します
解決
私は Reto の本を持っていないのでコードを確認できませんが、本に間違いがある場合は、Twitter で簡単に彼に連絡して議論することができます。 http://twitter.com/retomeier
画面の向きが変わると、アクティビティが再作成されることに注意してください。つまり、前回設定した静的ではない変数は、アクティビティが新しい方向で再作成された後は失われます。
私の推測では、ここで NullPointerException が発生したと思われます。
if(setting.getAddForPublicUserNames() == 1){
その場合、何らかのユーザーアクションによって「setting」変数が null 以外の値に変更される可能性が高く、アクティビティが再作成されるときにこれが再度設定されていることを確認する必要があります。
ここでは、方向間のアクティビティ状態を保存/取得する最も標準的な方法について詳しく説明します。 「インスタンス状態の保存」を使用して Android アクティビティの状態を保存する
他のヒント
あなたが向きを変え、アンドロイドあなたの活動を再開するときは、
で不動産を保存する必要がありますonSaveInstanceState
と
と回復savedInstanceState
あなたは活動が時に向きの変更、再作成したくない場合。 AndroidManifest.xmlに以下の行を挿入します。
android:configChanges="keyboardHidden|orientation
例:
<activity android:name=".FABSLogin" android:label="@string/app_name"
android:theme="@style/Theme.NoWindowTitle" android:noHistory="true" **android:configChanges="keyboardHidden|orientation**">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>