Catch keyboard 'Done' for NumberPicker

半城伤御伤魂 提交于 2019-12-04 03:16:18

How can I connect the IME "Done" to my dialog's "OK" action?

The problem is that you can't pass the IME's events if you don't have a listener set on the TextView widget which currently works with the IME. One way to do what you want is to hook our own logic to the NumberPicker's child which works with the IME(like you already talked in the last part of your question). To avoid using certain ids or other layout tricks(which can be problematic) to get a hold of that widget, you could use a greedy tactic, setting the listener to any widget from the NumberPicker which could trigger the desired event(TextViews or any subclass of TextView). Something like this:

    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;
    }

Where the methods are:

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);
        }
    }

The other possible(and reasonable) solution(like Naveen already mentioned in his comment) is to use one of the ports of the NumberPicker class(or modify the one from the SDK) out there and insert your own widget ids(which will make getting a reference to the widget a simple task). This would be easier to implement now but inconvenient to maintain on the long run.

My search and experimentation has also turned out empty handed. That said I wouldn't encourage this kind of behavior as it doesn't make much sense.

If you need a NumberPicker it is because you want the feature of scrolling to the value that you need, not entering it (though it is possible). If you want to enter the value you'd use an EditText and you would be able to implement what you need without problems.

Alternatively you have to copy NumberPicker implementation from the source and then change it according to your needs (fx by adding ime options).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!