web-dev-qa-db-ja.com

PreferenceActivityで「addPreferencesFromResource」の代わりに使用するもの

私はちょうどAndroidのドキュメントでメソッドaddPreferencesFromResource(int preferencesResId)非推奨としてマークされているという事実に気づきました( Reference Entry )。

残念ながら、この方法の説明では代替方法は提供されていません。

PreferenceScreen.xmlを対応するPreferenceActivityに接続するには、代わりにどのメソッドを使用する必要がありますか?

352
mweisz

推奨されるアプローチ(APIレベル11以降)は、リソースファイルからプリファレンスをロードするために PreferenceFragment オブジェクトをインスタンス化することです。こちらのサンプルコードをご覧ください。 PreferenceActivity

333
glorifiedHacker

上記の正しい答えにさらに情報を追加するには、Android-erからの の例を読んだ後 、好みのアクティビティを好みのフラグメントに簡単に変換できることがわかりました。次のような活動があります。

public class MyPreferenceActivity extends PreferenceActivity
{
    @Override
    protected void onCreate(final Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.my_preference_screen);
    }
}

必要な変更は、内部フラグメントクラスを作成し、addPreferencesFromResources()をフラグメントに移動して、アクティビティからフラグメントを呼び出すことです。

public class MyPreferenceActivity extends PreferenceActivity
{
    @Override
    protected void onCreate(final Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        getFragmentManager().beginTransaction().replace(Android.R.id.content, new MyPreferenceFragment()).commit();
    }

    public static class MyPreferenceFragment extends PreferenceFragment
    {
        @Override
        public void onCreate(final Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.my_preference_screen);
        }
    }
}

フラグメントからより複雑な好みを作ることへの他の微妙なことがあるかもしれません。もしそうなら、誰かがここにそれらを書き留めてほしい。

187
Garret Wilson

@Garret Wilsonありがとうございます! Androidコーディングの癖として、私は嗜好の非互換性の問題に何時間も悩まされ続けてきたので、残念なことに、古いAPIではサポートされていない新しいメソッドに対するいくつかのメソッド/アプローチの使用を非難しました。アプリをさまざまなデバイスで動作させるには、あらゆる種類の回避策に頼る必要があります。本当にイライラする!

あなたのクラスは素晴らしいです、それはあなたがそれが以前のように好みで新しいAPIで働き続けることを可能にします、しかしそれは後方互換性がありません。私はさまざまなデバイスにアクセスしようとしているので、API 11以前のデバイスおよび新しいAPIで動作させるために、少しそれを調整しました。

import Android.annotation.TargetApi;
import Android.os.Bundle;
import Android.preference.PreferenceActivity;
import Android.preference.PreferenceFragment;

public class MyPrefsActivity extends PreferenceActivity
{
    private static int prefs=R.xml.myprefs;

    @Override
    protected void onCreate(final Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        try {
            getClass().getMethod("getFragmentManager");
            AddResourceApi11AndGreater();
        } catch (NoSuchMethodException e) { //Api < 11
            AddResourceApiLessThan11();
        }
    }

    @SuppressWarnings("deprecation")
    protected void AddResourceApiLessThan11()
    {
        addPreferencesFromResource(prefs);
    }

    @TargetApi(11)
    protected void AddResourceApi11AndGreater()
    {
        getFragmentManager().beginTransaction().replace(Android.R.id.content,
                new PF()).commit();
    }

    @TargetApi(11)
    public static class PF extends PreferenceFragment
    {       
        @Override
        public void onCreate(final Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(MyPrefsActivity.prefs); //outer class
            // private members seem to be visible for inner class, and
            // making it static made things so much easier
        }
    }
}

2つのエミュレータ(2.2と4.2)でテストに成功しました。

私のコードがなぜこんなにクレイジーに見えるのか:

私はAndroidのコーディングが大好きで、Javaの最大のファンではありません。

廃止予定の警告を回避し、Eclipseに強制的にコンパイルさせるには、アノテーションを使用する必要がありましたが、これらはクラスまたはメソッドにのみ影響するように思われるため、これを利用するにはコードを2つの新しいメソッドに移動する必要がありました。

新しいPreferenceActivityのためにクラスをコピーして貼り付けるたびにxmlリソースIDを2回記述する必要はないので、この値を格納するための新しい変数を作成しました。

これが他の人に役立つことを願っています。

P.S .:私の見解では申し訳ありませんが、あなたが新しくなってそのような障害を見つけたとき、あなたはそれを助けることができませんが欲求不満になります!

37
ecv

私のアプローチは Garret Wilsonの に非常に近いです(ありがとう、私はあなたに投票しました;)

さらに、Android <3との下位互換性を提供します。

私はちょうど私の解決策が Kevin Remo によってそれにさらに近いことを認識しました。 「期待」反パターン に依存していないので)それはほんの少しきれいです。

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

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
            onCreatePreferenceActivity();
        } else {
            onCreatePreferenceFragment();
        }
    }

    /**
     * Wraps legacy {@link #onCreate(Bundle)} code for Android < 3 (i.e. API lvl
     * < 11).
     */
    @SuppressWarnings("deprecation")
    private void onCreatePreferenceActivity() {
        addPreferencesFromResource(R.xml.preferences);
    }

    /**
     * Wraps {@link #onCreate(Bundle)} code for Android >= 3 (i.e. API lvl >=
     * 11).
     */
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private void onCreatePreferenceFragment() {
        getFragmentManager().beginTransaction()
                .replace(Android.R.id.content, new MyPreferenceFragment ())
                .commit();
    }
}

"本物の"(しかしより複雑な)例については、 NusicPreferencesActivityNusicPreferencesFragment .

22
schnatterer

例外の代わりに、単に使用してください:

if (Build.VERSION.SDK_INT >= 11)

そして使う

@SuppressLint("NewApi")

警告を抑制します。

6
Peter

設定を直接ロードするためにPreferenceActivityを使用する代わりに、設定をロードするAppCompatActivityをロードするPreferenceFragmentCompatまたは同等のものを使用してください。これはサポートライブラリ(現在はAndroid Jetpack)の一部であり、API 14との互換性があります。

build.gradleに、環境設定サポートライブラリへの依存関係を追加します。

dependencies {
    // ...
    implementation "androidx.preference:preference:1.0.0-alpha1"
}

注:設定XMLがすでに作成されていると仮定します。

あなたの活動のために、新しい活動クラスを作成します。重要なテーマを使用している場合は、AppCompatActivityを拡張する必要がありますが、これを使用すると柔軟に対応できます。

public class MyPreferencesActivity extends AppCompatActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_preferences_activity)
        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.fragment_container, MyPreferencesFragment())
                    .commitNow()
        }
    }
}

今度は重要な部分のために:XMLからあなたの好みをロードするフラグメントを作成します:

public class MyPreferencesFragment extends PreferenceFragmentCompat {

    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        setPreferencesFromResource(R.xml.my_preferences_fragment); // Your preferences fragment
    }
}

詳しくは、PreferenceFragmentCompatのAndroid Developers のドキュメント をご覧ください。

0