8

いくつAlertDialogかのテキスト、a NumberPicker、OK、およびキャンセルがあります。

package org.dyndns.schep.example;
import android.os.Bundler;
import android.view.View;
import android.widget.NumberPicker;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;

public class FooFragment extends DialogFragment {
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        mParent = (MainActivity) activity;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setPositiveButton(android.R.string.ok,
                new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                mParent.setFoo(foo());
            }
        })
        .setNegativeButton(android.R.string.cancel, null);

        View view = getActivity().getLayoutInflater.inflate(
                R.layout.dialog_foo, null);
        mPicker = (NumberPicker) view.findViewById(R.id.numberPicker1);
        mPicker.setValue(mParent.getFoo());
        builder.setView(view);
        return builder.create();
    }

    public int foo() {
        return mPicker.getValue();
    }

    private MainActivity mParent;
    private NumberPicker mPicker;
}

(このダイアログは、一時停止と再開の状態を保持するために必要なことをまだ実行していません。)

編集するウィジェットは1つしかないため、ソフトキーボードまたは他のIMEの[完了]アクションで、[OK]が押されたかのようにダイアログを閉じたいと思います。

IMEの「完了」を処理する最良の方法は、通常、setOnEditorActionListenerで行うことのようTextViewです。しかし、私にはTextView変数がなく、明らかに、または同様のエディターコールバックをNumberPicker公開していません。TextView(たぶん、私が使用して検索できる定数IDを持つNumberPickerが含まれていますか?)TextViewfindViewById

NumberPicker.setOnValueChangedListener「完了」アクションでトリガーされますが、番号のリストをタップまたはフリックしたときにも起動します。これにより、ダイアログが閉じられることはありません。

この質問に基づいてチェックアウトしてみましsetOnKeyListenerたが、ソフトキーボードを使用したときにそのインターフェイスがまったくトリガーされませんでした。ドキュメントではハードウェアイベント向けであることが示されているため、まったく驚くことではありませんKeyEvent。最近のAPIでは、ソフトキーボードはそれらをまったく送信しません。

IMEの「完了」をダイアログの「OK」アクションに接続するにはどうすればよいですか?

編集:ソースの外観から、NumberPickerレイアウトにはが含まれていますがEditText、そのIDはid/numberpicker_inputパッケージに含まれていますcom.android.internal。それを使用するのは簡単ではなく、明らかにお勧めできません。しかし、私が望む振る舞いを得るにはハックの方法しかないようです。

4

2 に答える 2

9

IMEの「完了」をダイアログの「OK」アクションに接続するにはどうすればよいですか?

TextView問題は、現在IMEで動作しているウィジェットにリスナーが設定されていない場合、IMEのイベントを渡すことができないことです。必要なことを行う1つの方法は、IMEで動作する子に独自のロジックをフックすることですNumberPicker(質問の最後の部分ですでに説明したように)。特定のIDまたは他のレイアウトトリック(問題になる可能性があります)を使用してそのウィジェットを取得することを回避するには、貪欲な戦術を使用してNumberPicker、目的のイベント(TextViewsまたはのサブクラスTextView)をトリガーする可能性のあるウィジェットにリスナーを設定します。 。このようなもの:

    private AlertDialog mCurrentDialog;
    private List<TextView> mTargets = new ArrayList<TextView>();
    private OnEditorActionListener mListener = new OnEditorActionListener() {

        @Override
        public boolean onEditorAction(TextView v, int actionId,
                KeyEvent event) {
            if (actionId == EditorInfo.IME_ACTION_DONE) {
                // if a child of NumberPicker triggers the DONE editor event
                // get a reference to the positive button(which you use in your
                // code) and click it
               mCurrentDialog.getButton(Dialog.BUTTON_POSITIVE).performClick();
            }
            return false;
        }
    };

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
     // ...
     mPicker = (NumberPicker) view.findViewById(R.id.numberPicker1);
        mPicker.setValue(mParent.getFoo());
        // clear any previous targets
        mTargets.clear();
        // find possible targets in the NumberPicker 
        findTextViews(mPicker);
        // setup those possible targets with our own logic 
        setupEditorListener();          
        builder.setView(view);
        // get a reference to the current showed dialog 
        mCurrentDialog = builder.create();          
        return mCurrentDialog;
    }

メソッドは次のとおりです。

private void findTextViews(ViewGroup parent) {
        final int count = parent.getChildCount();
        for (int i = 0; i < count; i++) {
            final View child = parent.getChildAt(i);
            if (child instanceof ViewGroup) {
                findTextViews((ViewGroup) child);
            } else if (child instanceof TextView) {
                mTargets.add((TextView) child);
            }
        }
    }

    private void setupEditorListener() {
        final int count = mTargets.size();
        for (int i = 0; i < count; i++) {
            final TextView target = mTargets.get(i);
            target.setOnEditorActionListener(mListener);
        }
    }

他の可能な(そして合理的な)解決策(彼のコメントですでに述べたNaveenのような)は、NumberPickerクラスのポートの1つを使用して(またはSDKからポートを変更して)、独自のウィジェットIDを挿入することです(これにより、ウィジェットへの参照は簡単なタスクです)。これは今では実装が簡単ですが、長期的に維持するには不便です。

于 2013-02-20T10:31:01.420 に答える
0

私の検索と実験も手ぶらでした。とはいえ、あまり意味がないので、この種の行動は奨励しません。

NumberPickerが必要な場合は、入力するのではなく、必要な値までスクロールする機能が必要なためです(可能ですが)。値を入力する場合は、EditTextを使用すると、必要なものを問題なく実装できます。

または、ソースからNumberPicker実装をコピーしてから、必要に応じて変更する必要があります(imeオプションを追加してfx)。

于 2013-02-20T09:50:41.817 に答える