9

私は(サブ)PreferenceScreensの束を持つPreferenceActivityを持っています。このような (Sub)PreferenceScreen はそれぞれアカウントを表し、そのタイトルとして account-username を持ちます。

PreferenceScreen root = mgr.createPreferenceScreen(this);
for (MyAccountClass account : myAccounts) {
    final PreferenceScreen accScreen = mgr.createPreferenceScreen(this);

    accScreen.setTitle(account.getUsername());

    // add Preferences to the accScreen
    // (for instance a "change username"-preference)
    ...

    root.add(accScreen);
}

ユーザーが sub-PreferenceScreen に入り、アカウントのユーザー名を編集すると、外側の PreferenceScreen で問題のアカウントの PreferenceScreen-title を更新する必要があります。

私は追加しようとしました...

usernamePref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        accScreen.setTitle(newValue.toString());
        return true;
    }
});

...しかし、accScreen.setTitle は外側の PreferenceScreen では有効にならないようです。onContentChanged();呼び出すと実際に機能することに注意しましたが、これはおそらく好ましい方法ではないことを認識しています。

どこかで何らかのビューを呼び出す必要postInvalidate()があると思いますが、どのビューでいつそれを行うべきか本当にわかりません。

PreferenceScreen android:まとめ更新!私と同じ悩みを抱えているかもしれません。

どんな助けでも感謝します。

4

8 に答える 8

16

これに対する解決策を見つけました。私はこのような階層を持っています。これらはそれぞれ PreferenceScreen です:

main settings
  -> users list
    -> user1 settings
    -> user2 settings
    ...

ユーザー一覧では、サブ画面のタイトルはユーザー設定に依存します。ここで、ユーザー リストを作成するときに、リスト アダプターを PreferenceActivity の変数に格納します。

 PreferenceScreen usersListScreen = ...
 userScreenListAdapter = (BaseAdapter)usersListScreen.getRootAdapter();

userX-settings が編集されると、usersListScreen にタイトルを設定し、その後、次のように呼び出します。

userScreenListAdapter.notifyDataSetChanged();

これにより、リスト UI が更新され、変更が表示されます。

于 2011-02-18T11:41:06.577 に答える
2

これは遅い答えかもしれませんが、それでも...私は今それに取り組んでいます:)

私が達成した方法は、そのライフサイクルのPreferenceFragmentCompatonResume()メソッドにフックし、値をリセットして必要なフィールドを手動で更新できることです。

注 : この例では、すべての設定をリセットしないように、編集した設定のインデックスも追跡しています。

    // let's say you need to update title of the parent screen
    // when back from sub-screen(s) edition

    private int edited = -1;

    // this gets called everytime you get back to the parent screen
    @Override
    public void onResume ()
    {
        super.onResume();
        if ( edited != -1 )
        {
            PreferenceScreen root = getPreferenceScreen();
            Preference preference = root.getPreference( edited );

            if ( preference != null )
            {
                String updatedValue = getPreferenceManager()
                .getSharedPreferences()
                .getString( "your-preference-key", "your-default-value" );

                preference.setTitle( updatedValue );
            }

            edited = -1;
        }
    }

    // everytime you are about to navigate to a sub-screen 
    @Override
    public boolean onPreferenceTreeClick ( Preference preference )
    {
        // beware to save it first
        if ( preference instanceof MySubScreenPreference )
        {
            edited = preference.getOrder();
        }

        return super.onPreferenceTreeClick( preference );
    }

ドキュメントで指定されているとおり:

onResume

フラグメントがユーザーに表示され、アクティブに実行されているときに呼び出されます。これは通常、含まれているアクティビティのライフサイクルの Activity.onResume に関連付けられています。

もちろん、FragmentManagerTransactionsでも機能します。

これがお役に立てば幸いです。コーディングをお楽しみください。:)

于 2017-09-01T08:32:26.313 に答える
1

これと同じ問題が発生していますが、 onContentChanged() が機能していません。私の問題は、ルートから複数のレベルにある PreferenceScreens にあります。

例に従うと、最初に「Accounts」 PreferenceScreen を作成し、その下に個々のアカウントの PreferenceScreen オブジェクトをそれぞれ追加したとします。このような:

ルート画面
  →「アカウント」画面
    →「foo@example.com」画面
      -> ユーザー名を編集
      -> パスワードの編集
      -> など...
    →「bar@example.com」画面
    →「baz@example.com」画面
    -> など...

ユーザーがユーザー名を編集して [保存] をクリックした場合、PreferenceActivity.onContentChanged() を呼び出すと、ルート PreferenceScreen の直接の子孫にのみ影響するようです。第 3 世代の画面のタイトルと概要は再描画されず、古い値が反映されています。

onContentChanged() のコードを見ると、ルート Screen を ListActivity の ListView に re-bind() しているように見えますが、後続の PreferenceScreens が ListView にバインドされることはないと思います (そうですか?)。手動で何かを再バインドすることはできません...

私が考えることができる唯一の回避策は、サブメニューを PreferenceScreens ではなく分離された PreferenceActivitys として作成することです。これにより、直接の祖先で onContentChanged() を意図的に呼び出すことができます。しかし、それは現在の回避策よりもさらに面倒です。何か案は?

于 2010-05-02T05:40:02.310 に答える
0

ソース

// Import required classes (Win: CTRL+SHIFT+O & Mac: CMD+SHIFT+O)
public class YourCustomPreference extends PreferenceActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Load the preferences from an XML resource
        addPreferencesFromResource(R.xml.preferences);
    }

    // some logic goes above, when you want to reset value and update
    // EditTextPreference value. For convenience, I am going to wrap two
    // different task in different methods
    private void resetPreferenceValue() {
        SharedPreferences sharedPref = PreferenceManager
                .getDefaultSharedPreferences(this.getApplicationContext());
        // Get preference in editor mode
        SharedPreferences.Editor prefEditor = sharedPref.edit();
        // set your default value here (could be empty as well)
        prefEditor.putString("your_edit_text_pref_key", "DEFAULT-VALUE");
        prefEditor.commit(); // finally save changes
        // Now we have updated shared preference value, but in activity it
        // still hold the old value
        this.resetElementValue();
    }

    private void resetElementValue() {
        // First get reference to edit-text view elements
        EditTextPreference myPrefText = (EditTextPreference) super
                .findPreference("your_edit_text_pref_key");
        // Now, manually update it's value to default/empty
        myPrefText.setText("DEFAULT-VALUE");
        // Now, if you click on the item, you'll see the value you've just
        // set here
    }
}
于 2012-01-24T21:18:25.827 に答える
-1

これは私にとってはうまくいきます。PreferenceScreen の基になるダイアログを取得し、そこからタイトルを設定する必要があります。非常に簡単です。

somePrefScreen.getDialog().setTitle("Whatever you want");
于 2012-01-03T01:39:38.883 に答える