捕捉键盘“完成”的NumberPicker [英] Catch keyboard 'Done' for NumberPicker

查看:150
本文介绍了捕捉键盘“完成”的NumberPicker的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 AlertDialog 与只是一些文本, NumberPicker ,一个确定和取消。

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

公共类FooFragment扩展DialogFragment {
    @覆盖
    公共无效onAttach(活动活动){
        super.onAttach(活动);
        mParent =(MainActivity)的活动;
    }

    @覆盖
    公共对话onCreateDialog(包savedInstanceState){
        AlertDialog.Builder建设者=新AlertDialog.Builder(getActivity());
        builder.setPositiveButton(android.R.string.ok,
                新DialogInterface.OnClickListener(){
            @覆盖
            公共无效的onClick(DialogInterface对话框,INT ID){
                mParent.setFoo(FOO());
            }
        })
        .setNegativeButton(android.R.string.cancel,NULL);

        查看查看= getActivity()。getLayoutInflater.inflate(
                R.layout.dialog_foo,NULL);
        mPicker =(NumberPicker)view.findViewById(R.id.numberPicker1);
        mPicker.setValue(mParent.getFoo());
        builder.setView(视图);
        返回builder.create();
    }

    公众诠释富(){
        返回mPicker.getValue();
    }

    私人MainActivity mParent;
    私人NumberPicker mPicker;
}
 

(此对话框还没有做的事情,就应该以preserve状态的暂停和恢复,我知道了。)

我想软键盘或其他输入法上的完成行动,关闭对话框,就好像OK是pressed,因为只有一个小工具来编辑。

它看起来像对付一个IME完成最好的办法通常是 setOnEditorActionListener 的TextView 。但是,我没有任何的的TextView 变量和 NumberPicker 没有明显暴露任何的TextView ,或类似的编辑器回调。 (也许 NumberPicker 包含的TextView 以恒定的ID我可以搜索使用 findViewById ?)

NumberPicker.setOnValueChangedListener 不会被触发的完成行动,但敲击或弹数,这绝对不应该关闭该对话框的列表时,它也激发。

根据<α

href="http://stackoverflow.com/questions/3031887/how-to-catch-a-done-key-$p$pss-from-the-soft-keyboard">this的问题,我想检查出 setOnKeyListener ,但使用软键盘时,该接口并没有触发的。不是总有意外惊喜,因为 的KeyEvent 文件表明,它的意思更多的硬件事件,并在最近的API软键盘会不会送他们。

我如何连接输入法完成我的对话框中的确定动作?

编辑:从源头的容貌,一个 NumberPicker 布局确实包含的EditText ,但它的ID是 ID / numberpicker_input 封装 com.android.internal 。使用这不会是容易的,而且显然是不鼓励。不过好像有可能只是黑客的方法来获得我想要的行为。

解决方案
  

我如何连接输入法完成我的对话框中的确定动作?

现在的问题是,你无法通过输入法的事件,如果你没有一个监听器上的的TextView 控件,它目前与输入法设置。做你想做的一种方式是挂钩我们自己的逻辑来的 NumberPicker 的孩子而与IME的工作(如你已经讲过你的问题的最后一部分) 。为了避免使用某些ID或其他布局的技巧(这可能是有问题)来获取持有的小部件,你可以使用一个贪婪的战术,听者设置为从 NumberPicker 这可能触发( TextViews 的TextView 的任何子类)所需的事件。事情是这样的:

 私人AlertDialog mCurrentDialog;
    私人列表&LT; TextView的&GT; mTargets =新的ArrayList&LT; TextView的&GT;();
    私人OnEditorActionListener mListener =新OnEditorActionListener(){

        @覆盖
        公共布尔onEditorAction(TextView的V,诠释actionId,
                KeyEvent的事件){
            如果(actionId == EditorInfo.IME_ACTION_DONE){
                //如果NumberPicker的孩子触发DONE编辑事件
                //得到一个参照正按钮(您在使用
                // code)和点击
               mCurrentDialog.getButton(Dialog.BUTTON_POSITIVE).performClick();
            }
            返回false;
        }
    };

@覆盖
公共对话onCreateDialog(包savedInstanceState){
     // ...
     mPicker =(NumberPicker)view.findViewById(R.id.numberPicker1);
        mPicker.setValue(mParent.getFoo());
        //清除任何previous目标
        mTargets.clear();
        //发现在NumberPicker可能的目标
        findTextViews(mPicker);
        //设置我们自己的逻辑的可能目标
        setupEditorListener();
        builder.setView(视图);
        //得到一个参考目前显示对话框
        mCurrentDialog = builder.create();
        返回mCurrentDialog;
    }
 

当的方法是:

 私人无效findTextViews(ViewGroup中父){
        最终诠释计数= parent.getChildCount();
        的for(int i = 0; I&LT;计数;我++){
            最后查看孩子= parent.getChildAt(我);
            如果(孩子的instanceof的ViewGroup){
                findTextViews((ViewGroup中)的孩子);
            }否则,如果(孩子的instanceof的TextView){
                mTargets.add((TextView的)子女);
            }
        }
    }

    私人无效setupEditorListener(){
        最终诠释计数= mTargets.size();
        的for(int i = 0; I&LT;计数;我++){
            最后的TextView目标= mTargets.get(我);
            target.setOnEditorActionListener(mListener);
        }
    }
 

其他可能的(合理的)解决方案(如已经在他的评论中提到纳文)是使用 NumberPicker 类的端口中的一个(或修改从一该SDK)存在,并且插入自己的小部件标识(这将使获得一个参考部件一个简单的任务)。这将是更容易实现,但现在不方便就长期来看维持。

I have an AlertDialog with just some text, a NumberPicker, an OK, and a Cancel.

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

(This dialog doesn't yet do the things it should to preserve state on Pause and Resume, I know.)

I would like the "Done" action on the soft keyboard or other IME to dismiss the dialog as though "OK" were pressed, since there's only the one widget to edit.

It looks like the best way to deal with an IME "Done" is usually to setOnEditorActionListener on a TextView. But I don't have any TextView variable, and NumberPicker doesn't obviously expose any TextView, or similar editor callbacks. (Maybe NumberPicker contains a TextView with a constant ID I could search for using findViewById?)

NumberPicker.setOnValueChangedListener does get triggered on the "Done" action, but it also fires when tapping or flicking the list of numbers, which definitely should not dismiss the dialog.

Based on this question, I tried checking out setOnKeyListener, but that interface didn't trigger at all when using the soft keyboard. Not a total surprise, since the KeyEvent documentation suggests it's meant more for hardware events, and in recent APIs the soft keyboard won't send them at all.

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

Edit: From the looks of the source, a NumberPicker layout does contain a EditText, but its id is id/numberpicker_input in package com.android.internal. Using that would not be easy, and is obviously discouraged. But it seems like there might only be hack ways to get the behavior I want.

解决方案

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.

这篇关于捕捉键盘“完成”的NumberPicker的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆