【问题标题】:Get input text with customview without edittext android在没有edittext android的情况下使用customview获取输入文本
【发布时间】:2015-02-27 07:56:56
【问题描述】:

我创建了自定义视图。每当用户双击视图时,它应该显示键盘并且用户可以绘制新文本。

Holder 是一个扩展视图的自定义视图。但它显示键盘。如何获取文本?

 public Holder(Context context, AttributeSet attrs) {
    super(context, attrs);
    Log.e(TAG,"EXE");
    imm = (InputMethodManager)
           context. getSystemService(Context.INPUT_METHOD_SERVICE);



 public boolean onDoubleTap(MotionEvent e) {        

        View view = Holder.this.getRootView();
        imm.showSoftInput(view, InputMethodManager.SHOW_FORCED);
     // imm.showSoftInput(Holder.this, InputMethodManager.SHOW_FORCED);  not working

【问题讨论】:

  • 我知道这是一个老问题。但是,如果现在有人面临这个问题,您必须使视图具有焦点。只需设置“focusable=true”和“focusableInTouchMode=true”就可以了。

标签: android canvas android-input-method


【解决方案1】:

这是一个自定义的FrameLayout,当你点击它时,它会显示soft-keyboard,你可以输入任何东西,当你按下回车键时,它会显示你输入的内容,我希望它会给你的想法:

public class MyCustomFrameLayout extends FrameLayout {

    String mText;
    public MyCustomFrameLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }
    public MyCustomFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    public MyCustomFrameLayout(Context context) {
        super(context);
        init();
    }
    @Override
    public boolean onCheckIsTextEditor() {
        return true;
    }
    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
            BaseInputConnection fic = new BaseInputConnection(this, false);
            outAttrs.actionLabel = null;
            outAttrs.inputType = InputType.TYPE_NULL;
            outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE;
            return fic;      
    }
    public void init(){
        setFocusable(true);
        setFocusableInTouchMode(true);
        mText ="";
        setOnKeyListener(new OnKeyListener() {
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    if((keyCode >= KeyEvent.KEYCODE_A) && (keyCode <= KeyEvent.KEYCODE_Z)) {
                        mText = mText + (char) event.getUnicodeChar();
                        return true;
                    }
                    else if(keyCode >= KeyEvent.KEYCODE_ENTER){                 
                        Toast.makeText(getContext(), "The text is: " + mText , Toast.LENGTH_LONG).show();
                         return true;
                    }
                }
                return false;
            }
        }); 
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            InputMethodManager imm = (InputMethodManager) getContext()
                    .getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.showSoftInput(this, InputMethodManager.SHOW_FORCED);
        }
        return true;
    }
    public String getText(){        
        return mText;
    }
}

【讨论】:

  • 不,但你可以很容易地做到这一点,在收到每个按键调用无效并在 onDraw 方法中写入 mText。
  • 我正在扩展视图。我已在此处添加了这些代码。键盘未更改为 Ime Action Done
  • 我在那里放了一个日志。它不会继续 oncreateInputConnection();我正在使用此方法调用键盘 imm.toggleSoftInput(0, 0);
  • 您可以发布您的自定义视图以便我试用吗?
  • 我认为bug在这里imm.showSoftInput(view,InputMethodManager.SHOW_FORCED);因为根视图没有设置onCheckIsTextEditor或者其他方法。
【解决方案2】:

尝试动态创建edittext并将值发送到视图。这是我的代码。它的最佳选择..

public class CustomEditText extends EditText {

private KeyImeChange keyImeChangeListener;

public CustomEditText(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

public CustomEditText(Context context) {
    super(context);
}

public CustomEditText(Context context, AttributeSet attrs) {
    super(context, attrs);
}


public void setKeyImeChangeListener(KeyImeChange listener){
    keyImeChangeListener = listener;
}

public interface KeyImeChange {
    public void onKeyIme(int keyCode, KeyEvent event);
}

@Override
public boolean onKeyPreIme (int keyCode, KeyEvent event){
    if(keyImeChangeListener != null){
        keyImeChangeListener.onKeyIme(keyCode, event);
    }
    return false;
}

}

           MainActivity.editText2.setKeyImeChangeListener(new CustomEditText.KeyImeChange() {

                @Override
                public void onKeyIme(int keyCode, KeyEvent event) {
                //Update view on keyboard close
                      invalidate();


                }
            });

【讨论】:

    【解决方案3】:

    @Asthme:检查链接后 How to Capture soft keyboard input in a View?,为了使视图可编辑,您还需要自定义 BaseInputConnection 以使视图可编辑。

    下面的链接给出了可能的代码解决方案,该链接由 Dianne Hackborne(Android 框架工程师)提供。

    https://groups.google.com/forum/#!topic/android-developers/N0ITpZZ16Bw

    到此链接的最后一个,您会发现自定义 BaseInputConnection 以使 View 可编辑。

    我正在发布示例代码的相关代码和屏幕截图:

    class MyInputConnection extends BaseInputConnection {
        private SpannableStringBuilder myeditable;
        Holder mycustomview;
    
        public MyInputConnection(View targetView, boolean fullEditor) {
            super(targetView, fullEditor);
            mycustomview = (Holder) targetView;
        }
    
        public Editable getEditable() {
            if (myeditable == null) {
                myeditable = (SpannableStringBuilder) Editable.Factory.getInstance()
                .newEditable("Placeholder");
            }
            return myeditable;
        }
    
        public boolean commitText(CharSequence text, int newCursorPosition) {
            invalidate();
            myeditable.append(text);
            mycustomview.setText(text);
            return true;
        }
    }
    

    由于这是自定义视图,我们需要提供 setText 的实现。

        public void setText(CharSequence text) {
                    mText = text;
                    requestLayout();
                    invalidate();
                }
    

    以下是完整的自定义视图代码,这与您的实现不同(我将保留 Gesture* API 未实现)

         package com.example.soappdemo;
    
            import android.content.Context;
            import android.graphics.Canvas;
            import android.graphics.Paint;
            import android.text.Editable;
            import android.text.InputType;
            import android.text.SpannableStringBuilder;
            import android.util.AttributeSet;
            import android.util.Log;
            import android.view.GestureDetector;
            import android.view.KeyEvent;
            import android.view.MotionEvent;
            import android.view.View;
            import android.view.inputmethod.BaseInputConnection;
            import android.view.inputmethod.EditorInfo;
            import android.view.inputmethod.InputConnection;
            import android.view.inputmethod.InputMethodManager;
            import android.widget.TextView;
    
            public class Holder extends View implements GestureDetector.OnDoubleTapListener {
    
                InputMethodManager imm;
                private Paint paint;
                private static final String TAG="Holder";
                 private CharSequence mText="original";
                public Holder(Context context, AttributeSet attrs) {
                    super(context, attrs);
                    init();
                    //requestFocus();
                    setFocusableInTouchMode(true);
                    setFocusable(true);
                    requestFocus();
    
    
                    setOnKeyListener(new OnKeyListener() {
                        public boolean onKey(View v, int keyCode, KeyEvent event) {
                            Log.d(TAG, "onKeyListener");
                            if (event.getAction() == KeyEvent.ACTION_DOWN) {
                                // Perform action on key press
                                Log.d(TAG, "ACTION_DOWN");
                                return true;
                            }
                            return false;
                        }
                    });
    
                }
    
                 public void init(){
                        paint = new Paint();
                        paint.setTextSize(12);
                        paint.setColor(0xFF668800);
                        paint.setStyle(Paint.Style.FILL);
                    }
    
                 @Override
                    protected void onDraw(Canvas canvas) {
                        canvas.drawText(mText.toString(), 100, 100, paint);
                    }
    
                    @Override
                    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                        this.setMeasuredDimension(150,200);     
                    }
    
                    public void setText(CharSequence text) {
                        mText = text;
                        requestLayout();
                        invalidate();
                    }
    
    
    
    
                public boolean onTouchEvent(MotionEvent event) {
                    super.onTouchEvent(event);
                    Log.d(TAG, "onTOUCH");
                    if (event.getAction() == MotionEvent.ACTION_UP) {
    
                        // show the keyboard so we can enter text
                        InputMethodManager imm = (InputMethodManager) getContext()
                                .getSystemService(Context.INPUT_METHOD_SERVICE);
                        imm.showSoftInput(this,0);
                    }
                    return true;
                }
    
                @Override
                public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
                    Log.d(TAG, "onCreateInputConnection");
    
                    outAttrs.actionLabel = null;
                    outAttrs.label="TEST TEXT";
                    outAttrs.inputType = InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
                    outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE;
    
                    return new MyInputConnection(this,true);
    
                }
    
                @Override
                public boolean onCheckIsTextEditor() {
                    Log.d(TAG, "onCheckIsTextEditor");
                    return true;
                }
    
                @Override
                public boolean onDoubleTap(MotionEvent e) {
                    // TODO Auto-generated method stub
                    View view = Holder.this.getRootView();
                    imm.showSoftInput(view, InputMethodManager.SHOW_FORCED);
                    return false;
                }
    
                @Override
                public boolean onDoubleTapEvent(MotionEvent e) {
                    // TODO Auto-generated method stub
                    return false;
                }
    
                @Override
                public boolean onSingleTapConfirmed(MotionEvent e) {
                    // TODO Auto-generated method stub
                    return false;
                }
    
    
    
                class MyInputConnection extends BaseInputConnection {
                    private SpannableStringBuilder myeditable;
                    Holder mycustomview;
    
                    public MyInputConnection(View targetView, boolean fullEditor) {
                        super(targetView, fullEditor);
                        mycustomview = (Holder) targetView;
                    }
    
                    public Editable getEditable() {
                        if (myeditable == null) {
                            myeditable = (SpannableStringBuilder) Editable.Factory.getInstance()
                            .newEditable("Placeholder");
                        }
                        return myeditable;
                    }
    
                    public boolean commitText(CharSequence text, int newCursorPosition) {
                        invalidate();
                        myeditable.append(text);
                        mycustomview.setText(text);
                        return true;
                    }
                }
    
    
            }
    

    附上截图。 Pic-1 是在触摸之前,UI 是一些文本。 图 2 是触摸自定义视图并从软键盘接收文本时。 ![Pic-1,自定义视图中的初始文本][1]

    ![Pic-2 when custom view is tapped][2]
    
    
    
    
    
      [1]: http://i.stack.imgur.com/rLYmR.png
      [2]: http://i.stack.imgur.com/gTnYY.png
    

    【讨论】:

      【解决方案4】:

      检查这个link ○ 试试这个它可能会工作:

      imm.showSoftInput(view,0);
      

      【讨论】:

      • 调用键盘后如何获取文本
      【解决方案5】:

      试试这个

      InputMethodManager imm =    (InputMethodManager)     getSystemService(Context.INPUT_METHOD_SERVICE);
      mSearchEditText.requestFocus();
      imm.showSoftInput(mSearchEditText, InputMethodManager.SHOW_IMPLICIT);
      

      【讨论】:

        【解决方案6】:

        您可以在活动中覆盖onKeyUp(int keyCode, KeyEvent event),然后将关键信息(keyCode 和/或event)发送到您的视图。确保你有一个合适的自定义方法来处理你的视图中的关键代码/事件(我们称之为handleKeyEvent)。

        @Override
        public boolean onKeyUp(int keyCode, KeyEvent event) {
            yourCustomView.handleKeyEvent(keyCode, event);
        }
        

        来源:https://groups.google.com/forum/#!topic/android-developers/0tQSZufLZTg

        【讨论】:

          【解决方案7】:

          试试这个....

          view.requestFocus();
          view.setFocusableInTouchMode(true);
          InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
          imm.showSoftInput(InputEditText, InputMethodManager.SHOW_FORCED);
          

          也检查一下

          How to show soft-keyboard when edittext is focused

          【讨论】:

          • @MS Gadaj 调用键盘后我将如何获取文本
          • 当我双击它会打开键盘。在用户添加一些文本之后很好吗?我如何获取文本?
          【解决方案8】:

          使用文本视图本身。文本视图上的 Seteditable(true) 使其行为类似于编辑文本。所以在 seteditable(true) 和 seteditable(false) 之间切换,决定何时要编辑和何时阅读

          【讨论】:

            【解决方案9】:

            接受的答案对我不起作用。要打开特定视图的键盘,它必须是可聚焦的,否则键盘将不会显示。

            android:focusable="true"
            android:focusableInTouchMode="true"
            

            这应该可以解决问题。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2020-06-02
              • 2012-02-24
              • 2014-04-29
              • 1970-01-01
              • 2013-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-04-26
              相关资源
              最近更新 更多