1

Androidアプリで基本設定のアクティビティを実装しようとしていて、空白の画面が表示されたりクラッシュしたりしています。私が見たドキュメンテーションやサンプルは、古くても矛盾していても役に立たない。たとえば、表示する場所によっては、設定アクティビティがActivity,PreferenceActivity、またはAppCompatPreferenceActivity(ファイル>新規>アクティビティ>設定アクティビティの一部)のいずれかになります。Android PreferenceFragmentを設定する適切な方法は何ですか?

developer.android.comでは、次を実装する必要が言う:

public class SettingsActivity extends Activity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     // Display the fragment as the main content. 
     getFragmentManager().beginTransaction() 
      .replace(android.R.id.content, new SettingsFragment()) 
      .commit(); 
    } 
} 

しかし、アンドロイドStudioで生成された設定の活動は、それが作成する3つのフラグメントのいずれかのために、このコールをしない使用しています。これはプリファレンスヘッダーを使用します。

だからここに私の質問です:

  1. あなたは、単一のPreferenceFragmentとプリAPI 19互換性とシンプルな、単一あるpreferences.xmlファイルを使用している場合は必須ではありません、SettingsActivityは、どのようなクラスを拡張する必要がありますか? Activity、PreferenceActivity、またはAppCompatPreferenceActivity(すべてのサポートメソッドと委任に対して)?
  2. SettingsActivity.onCreate()でgetFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit()に電話する必要がありますか?
  3. さまざまな組み合わせで、アクションバーやクラッシュのない白い空白の設定画面が表示されます。アプリアクションバーを表示するアクティビティ内に単一のPreferencesFragmentを設定する正しい方法は何ですか?

答えて

1

SettingsActivityはどのクラスに適用されますか?

AppCompatActivityの拡張機能が有効でした。

static final String ANIMATION = "animation" ; 
static final String COUNTDOWN_ON_OFF = "countdown_on_off"; 

@Override 
protected void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 

    if (getFragmentManager().findFragmentById(android.R.id.content) == null) 
    { 
     getFragmentManager().beginTransaction().add(android.R.id.content, new Prefs()).commit(); 
    } 
} 

私は好みのヘッダに関連するすべての生成されたコードを追い出さ、私のPreferenceFragment

public static class Prefs extends PreferenceFragment 
{ 
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     addPreferencesFromResource(R.xml.preferences); 

     // Bind the summaries of EditText/List/Dialog/Ringtone preferences 
     // to their values. When their values change, their summaries are 
     // updated to reflect the new value, per the Android Design 
     // guidelines. 

     // findPreference() uses android:key like in preferences.xml ! 

     bindPreferenceSummaryToValue(findPreference(ANIMATION)); 

    } 
} 

私の静的メソッドのために(Androidのメーカーはいくつかの以前のバージョンで生成された)いくつかのテンプレートメソッド/変数を保持しましたActivityクラス(テンプレートから適合)。アクションバーを除く -

/** 
* A preference value change listener that updates the preference's summary 
* to reflect its new value.<br> 
* template by Android Studio minus Ringtone Preference 
*/ 
private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() 
{ 
    @Override 
    public boolean onPreferenceChange(Preference preference, Object value) 
    { 
     String stringValue = value.toString(); 

     if (preference instanceof ListPreference) 
     { 
      // For list preferences, look up the correct display value in 
      // the preference's 'entries' list. 
      ListPreference listPreference = (ListPreference) preference; 
      int index = listPreference.findIndexOfValue(stringValue); 

      // Set the summary to reflect the new value. 
      preference.setSummary(
        index >= 0 
          ? listPreference.getEntries()[index] 
          : null); 

     } 
     else if (preference instanceof RingtonePreference) 
     { 
      // my app didn't need that 
      return true; 
     } 
     else if (preference instanceof CheckBoxPreference) 
     { 
      Context ctx = preference.getContext(); 
      boolean isChecked = (Boolean) value; 

      if (preference.getKey().equals(ANIMATION)) 
      { 
       preference.setSummary(isChecked ? ctx.getString(R.string.sOn) : ctx.getString(R.string.sOff)); 
      } 
      else if (preference.getKey().equals(COUNTDOWN_ON_OFF)) 
      { 
       preference.setSummary(isChecked ? ctx.getString(R.string.sWhenPaused) : ctx.getString(R.string.sNever)); 
      } 
     } 
     else 
     { 
      // For all other preferences, set the summary to the value's 
      // simple string representation. 
      preference.setSummary(stringValue); 
     } 
     return true; 
    } 
}; 
} 
+0

これは動作します:

/** * Binds a preference's summary to its value. More specifically, when the * preference's value is changed, its summary (line of text below the * preference title) is updated to reflect the value. The summary is also * immediately updated upon calling this method. The exact display format is * dependent on the type of preference. * * @see #sBindPreferenceSummaryToValueListener */ private static void bindPreferenceSummaryToValue(Preference preference) { // Set the listener to watch for value changes. preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener); // Trigger the listener immediately with the preference's // current value. if (preference instanceof CheckBoxPreference) { sBindPreferenceSummaryToValueListener.onPreferenceChange(preference, PreferenceManager .getDefaultSharedPreferences(preference.getContext()) .getBoolean(preference.getKey(), true)); } else { sBindPreferenceSummaryToValueListener.onPreferenceChange(preference, PreferenceManager .getDefaultSharedPreferences(preference.getContext()) .getString(preference.getKey(), "")); } } 

そして最後に、(また、テンプレートから適応)ActivityPreference.OnPreferenceChangeListenerなどの静的変数は:あなたは他の好みのタイプをチェックすることもできます不足している。 SettingsActivity.onCreate()では、アクティビティがAndroidManifest.xmlにアクションバーを持つMainActivityの子として設定されていても、getSupportActionBar()を呼び出すとnullが返されます。私はまた、SettingsFragment.onCreate()でsetHasOptionsMenu()を呼び出しますが、おそらくそれは疑問です。あなたはどのようにActionBarを表示できますか? – Phil

+1

@ Phil - デフォルトではActionBarを持つActivity型を使用しました。 ActionBarを設定する必要がある場合は、MainActivityからその部分をコピーし、フラグメントをR.id.contentに入れずにツールバーの下のコンテナに配置する必要があります。他のフラグメント – 0X0nosugar

+0

ありがとう@ 0X0nosugar私がこのような基本的な質問をする理由は、Android Studioによって挿入されたSettingsActivityを使用しており、ツールバーを拡張する必要もなく、XMLフラグメントを定義したり、その位置を指定したりもしないということです。getSupportActionBar()を呼び出して取得します。 My SettingsActivityは、それに基づいてgetSupportActionBar()を呼び出し、nullを取得します。私は重要なロジックをどこか外してしまったか、見出しスタイルの設定に暗黙的なActionBarの処理が含まれています。 – Phil

関連する問題