PreferenceActivityで「addPreferencesFromResource」の代わりに何を使用しますか?


360

addPreferencesFromResource(int preferencesResId)は、メソッドがAndroidのドキュメント(参照エントリ)で非推奨とマークれているという事実に気づきました。

残念ながら、メソッドの説明では代替メソッドは提供されていません。

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


2
非常に簡単なアプローチは、stackoverflow.com
Sabin

そこでのソリューションはまだ使用していaddPreferencesFromResource(int preferencesResId)ます。何か不足していますか?
Jammo

@Jammoはい。ただし、アクティビティからフラグメントに移動され、新しい方法を反映しています->フラグメント。
WannaGetHigh

回答:


332

推奨される方法(APIレベル11以降)はPreferenceFragmentオブジェクトをインスタンス化してリソースファイルから設定をロードするため、メソッドの説明に代替メソッドはありません。こちらのサンプルコードをご覧ください:PreferenceActivity


ご回答どうもありがとうございました。「Video2Brain-Android Development」の非推奨の指示に従っていたため、PreferenceActivityのバージョンのメソッドを使用するようになりました。ところで、私ができる限り、あなたの答えを有用だと評価したいと思います。
mweisz '25

33
今PreferenceFragmentが、それはそれを使用するために理にかなって、互換性パッケージに含まれた場合にのみstackoverflow.com/questions/5501431/...
クリストフ

1
私はアクションバーシャーロックを使用しているので、私が見...、この問題を解決するために、次のブログを追っ commonsware.com/blog/2012/10/16/...
誰かがどこかで

2
11(Android 3.0)より前のAPIレベルとの下位互換性をアプリに持たせたい場合は、引き続きaddPreferencesFromResource(int PreferencesID)を呼び出す必要があります。しかし、私はあなたがそれらの古いデバイスが同様に除かれたと考えることができると思います。
Einar Sundgren 2013年

5
@EinarSundgren私はNexus Oneの所有者であり、利用可能な最大バージョンは2.2です。あなたは私を止めません!私は決して非難されません!グレイスカルの力で...私は力を持っています!
TechNyquist 2015年

186

上記の正解にさらに情報を追加するには、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);
        }
    }
}

フラグメントからより複雑な設定を行うには他にも微妙な点があるかもしれません。もしそうなら、誰かがここでそれらをメモしてくれることを願っています。


6
ニース、これをありがとう。Javaとこの種の考え方は、これまでのところ私の小さな.netの世界からは外れています:)
Tom

44
なぜ彼らaddPreferencesFromResources()はPreferenceFragmentの取引で減価するのですか?初心者からは不要に見えます。
Howdy_McGee 2013

4
呼び出しにはAPIレベル11が必要
mehmet 2014

1
APIがレベル9の場合はどうでしょうか?@mehmet
gumuruh

2
素晴らしい答え!android.R.id.contentを変更せずにこれを達成する方法はありますか?何かの理由で私には
無能に思え

37

@ギャレット・ウィルソンありがとうございます!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回記述する必要がないので、この値を格納する新しい変数を作成しました。

これが誰かに役立つことを願っています。

PS:私の意見では申し訳ありませんが、新しく来てそのようなハンディキャップを見つけたとき、あなたはそれを助けることができず、欲求不満になります!


まあ...コピーして貼り付けるたびに、外部クラス名を2回変更する必要があることに気づきました。内部クラスに設定を渡すことによって、これを回避する方法が実際にあります。prefsをパラメーターとして受け入れる内部クラスコンストラクターを作成することはできません。PreferenceFragment派生クラスには明らかに推奨されないためです。また、内部クラスにメソッドを作成して設定を取得し、すぐにaddPreferencesFromResourceを呼び出すことはできません。これは、super.onCreateが呼び出された後にaddPreferencesFromResourceを呼び出す必要があり、PreferenceFragment派生クラスが呼び出された直後にonCreateが呼び出されないためです...
ecv

...インスタンス化されます。したがって、内部クラスで新しい変数を作成し、内部クラスでその変数のパブリックsetメソッドを作成し、super.onCreateへの呼び出しの後の場所にaddPreferencesFromResourceを残して、onCreate内で内部クラスをインスタンス化し、設定を設定する必要があります。 、前と同じようにgetFragmentManager()...の呼び出しで使用します。
ecv

2
あなたのコードは命の恩人です!! 古い電話と新しい電話の両方をターゲットにしようとして、3日間を無駄にしました。そして、答えはとても簡単です。ありがとう
Devdatta Tengshe 2013年

22

私のアプローチは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();
    }
}

「実際の」(しかしより複雑な)例については、NusicPreferencesActivityおよびNusicPreferencesFragmentを参照してください。


@SuppressLint("NewApi")-避けてください-より正確に。低APIで実行しましたか?スローしますVerifyError
Mr_and_Mrs_D 2013

APIレベル10を実行しているエミュレータで上記をテストしました。APKはSDKバージョン19を使用してビルドされました。ビルドにはどのSDKバージョンを使用しましたか?どのデバイスAPIレベルで実行しましたか?エミュレーターまたは物理デバイスで実行しましたか?エラーはいつ発生したのですか?SDKが16以下のUrビルドの場合は、この応答を参照してください。
schnatterer 2014年

あなたは要点を逃している-そして私に通知されたい場合は@Mr_and_Mrs_Dを追加してください。VEについては、こちらをご覧ください:stackoverflow.com/questions/20271593/…。これ@SuppressLint("NewApi")はただの悪いスタイルです
Mr_and_Mrs_D 2014年

@Mそれでは@SuppressLint("NewApi")、この特定の状況で回避する方法についての提案はどうですか?
schnatterer 2014年

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
-apiの

6

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

if (Build.VERSION.SDK_INT >= 11)

そして使う

@SuppressLint("NewApi")

警告を抑制するため。


1
クラッシュ以外は何もしないからです:D
Ishtiaq 2014

1
それのクラッシュ場合...それを試してみて、キャッチ:D
gumuruh

0

を使用し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
    }
}

詳細については、Android Developersのドキュメントをご覧くださいPreferenceFragmentCompat

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.