2

私のアプリには ListPreference があり、そのエントリはネットワーク API から取得されます。PreferenceActivity の onCreate() で、API 呼び出しを行うバックグラウンド スレッドを生成し、1 ~ 2 秒後に ListPreference のエントリを設定します。

オプションがダウンロードされる前にユーザーが設定画面で ListPreference ボタンをクリックした場合、設定ダイアログが表示されないようにし、代わりにオプションのリストがまだロードされていることをユーザーに通知したいと考えています。

正しいアプローチは、次のように OnPreferenceClickListener をオーバーライドすることだと思います。

ListPreference dpref = (ListPreference) findPreference("debug");
String[] s = {"one", "two", "three"};
dpref.setEntries(s);
dpref.setEntryValues(s);
dpref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
    @Override
    public boolean onPreferenceClick(Preference preference) {
        Toast.makeText(this, "hi there", Toast.LENGTH_SHORT).show();
        return true;
    }
});

トーストが表示されますが、ListPreference 選択ダイアログも表示されます。OnPreferenceClickListener のドキュメントtrueには、クリックが処理された場合にonPreferenceClick が返されるはずであると記載されていますが、返されfalseても同じ結果になります。

設定ダイアログが表示されないようにするにはどうすればよいですか?

オプションを表示する前にダウンロードする必要がある設定を処理するより良い方法はありますか?

4

7 に答える 7

6

私は同じ問題に苦しんでいましたが、より単純な環境でした。私の PreferenceScreen は xml ファイルで定義されています。自分で処理したいプリファレンスが 1 つあります。したがって、「ListPreference」または「EditTextPreference」の代わりに「Preference」オブジェクトをxmlファイルに入れるだけです

    <Preference android:title="@string/preloadmaps1" android:summary="@string/preloadmaps2"
        android:key="preloadMaps" />

これで、設定に接続されたエディターがなくなり、「OnPreferenceClickListener」で自分で編集を安全に処理できます。

于 2011-05-23T09:26:04.860 に答える
5

showDialogについてのAndroiddveloperドキュメントを参照してください。

このプリファレンスに関連付けられているダイアログを表示します。これは通常、設定をクリックすると自動的に開始されます。他のイベントでダイアログを表示する必要がある場合は、このメソッドを呼び出します。

したがって、クリック設定がshowDialog()を自動的に呼び出す場合、クリック設定でダイアログが表示されないように制御する場合は、次のようなカスタム設定を実装する必要があります。

public class MyPreference extends ListPreference {
    private Context context;

    // a flag to control show dialog
    private boolean showDialog = false;

    public MyPreference(Context context) {
        super(context);
        this.context = context;
    }

    public MyPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;       
    }

    @Override
    protected void showDialog(Bundle state) {        
        if (showDialog) {
            // show dialog 
            super.showDialog(state);
        } else {
            // if you don't want to show a dialog when click preference
            return;
        } /* end of if */
    }
}
于 2012-06-27T16:09:27.513 に答える
2

なぜあなたのやり方がうまくいかないのかわかりませんが、ここに簡単な回避策があります:

ダウンロードする必要があるプリファレンスごとにスタブプリファレンスを追加します。クリック時のアクションは、任意の方法でカスタマイズできます。ダイアログは表示されません。

設定オプションの準備ができたら、古い設定を(その名前で)削除し、オプションを使用して新しいListPreference(削除したものと同じ名前)を作成します。

これにより、必要なイベントにあらゆる種類のカスタム設定を柔軟に追加できます。ご覧のとおり、追加のコーディングが必要です。

于 2011-01-12T00:37:26.580 に答える
1

これは古い質問であることは知っていますが、これらのダイアログをキャンセルする方法はまだ答えがありません。設定ダイアログをキャンセルする方法は次のとおりです。

dpref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
    @Override
    public boolean onPreferenceClick(Preference preference) {
        ((ListPreference)preference).getDialog().dismiss();   <<< This will do it
        Toast.makeText(this, "hi there", Toast.LENGTH_SHORT).show();
        return true;
    }
});

ただし、ダイアログを閉じるのではなく、後でオプションのリストが Web から読み込まれたときに表示できるように、ダイアログを非表示にすることをお勧めします。そうする:

dpref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
    @Override
    public boolean onPreferenceClick(Preference preference) {
        ((ListPreference)preference).getDialog().hide();   <<< This will just hide the dialog and you still can show it later
        Toast.makeText(this, "hi there", Toast.LENGTH_SHORT).show();
        return true;
    }
});

後で、オプションのリストがロードされたら、次を実行します。

...
dpref.setEntries(<array_of_options_here>);
dpref.getdialog().show();  <<< If you dismiss the dialog earlier and not hide it, then getDialog() returns null here 
...
于 2014-12-02T14:46:34.620 に答える
0

Activity設定をダウンロードして実際の設定を起動するプロキシ(ダイアログのスタイル)を使用しますPreferenceActivity

于 2011-01-12T04:43:08.763 に答える
0

onResume()設定アクティビティで次のことができます。

  • を開始async callします...
    • 値がフェッチされているというヒントを使用して、設定を無効に設定します
    • 値を取得するためのネットワーク (値がない場合、または常に) - 非同期であるため、再開を停止しません。
    • 取得した値で設定エントリを更新します
    • 設定を有効にしてデフォルトのヒントを表示する

この場合の欠点は、設定があまりにも頻繁に更新されることです (たとえば、設定画面が開始されたときに常に)。ただし、これにより、ネットワーク呼び出しの結果が前に選択された値ではないリストを生成する場合に対処できます。 (たとえば、ユーザーの選択が利用できなくなったことを示すダイアログをユーザーに表示します)。

Handlerまた、これはかなり複雑なタスクです(非同期実行は別のスレッドに存在するため、を定義する必要があるため...)

これは次のようになります (これを で行うと仮定しますPreferenceActivity) 。

import android.os.Handler;
import android.os.AsyncTask;
import android.os.Message;

public class xyz extends PreferenceActivity {
    ...
    // define a handler to update the preference state
    final Handler handler = new Handler() {
        public void handleMessage( Message msg ) {
            ListPreference dpref = (ListPreference) getPreferenceManager().findPreference("debug");
            dpref.setEnabled( msg.getData().getBoolean("enabled") );
            dpref.setSummary( msg.getData().getString("summary") );
        }
    };



    private class updatePref extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... arg) {

            Message msg = handler.obtainMessage();
            Bundle data = new Bundle();
            data.putBoolean("enabled", false ); // disable pref
            data.putString("summary", "Getting vals from network..." ); // set summary
            msg.setData( data );
            handler.sendMessage(msg); // send it do the main thread

            ListPreference dpref = (ListPreference) getPreferenceManager().findPreference("debug");


            String values[];
            // call network function and let it fill values[]

            // do things according to the returned values, 
            // eg check if there are any, check if the user has 
            // already selected one, display a message if the 
            // user has selected one before but the values do not
            // contain them anymore, ...

            // set the new values     
            dpref.setEntries(values);
            dpref.setEntryValues(values);

            data.putBoolean("enabled", true ); // enable pref
            data.putString("summary", "Please choose" ); // set summary
            msg.setData( data );
            handler.sendMessage(msg); // send it do the main thread

            return null;
        }
    }

    public void onResume() {
        ....
        new updatePref().execute();

    }

}

もちろん、どこでも呼び出すことができるので、 、またはnew updatePref().execute()どこにでもバインドできます( でこれを行う必要はありません)。ButtononCreate()onResume()

于 2011-01-29T11:32:15.507 に答える