hijamoya / KeyboardView

Since KeyboardView was deprecated in API level 29. Google recommends to copy the file to your project.
51 stars 18 forks source link

android:popupLayout="@xml/keyboard_popup" #7

Open grobbo91 opened 3 years ago

grobbo91 commented 3 years ago

android:popupLayout="@xml/keyboard_popup"

This attributes not working what I do now? When I was using deprecated it was working fine now it crashed on null object reference

Originally posted by @adil9d in https://github.com/hijamoya/KeyboardView/issues/1#issuecomment-846950327

This is worthy of a new issue. I have tried modifying the example to have popup keyboards like

    <Key
        app:codes="69"
        app:keyLabel="E"
        app:popupKeyboard="@layout/popup_layout"
        app:popupCharacters="Ë É È E" />

Any attempt at a long press which has a popup keyboard crashes the app as described above. Before using this library, I did not experience this issue.

Side note: I am working on my own version of this to feature some additional features

1) a long press with only one popup character will just default to that character instead of bringing up the popup 2) I want to have an onRelease equivalent that notifies the parent controller if a long press was used, which can then be used in other parts of the code. 3) long term goal, make the popup keyboard more like iOS where you keep holding down, then slide to the preferred character of the popup, then release to select the character.

adil9d commented 3 years ago

@grobbo91 I have google samples code where I try to solve your first problem. Here is google sample link Google Sample Keyboard

In this sample we have LatinKeyboardView.java a custom view of keyboard. In this class we will get onLongPress method. In this method I have made some code for popup below is my method code

 override fun onTouchEvent(me: MotionEvent?): Boolean {

        X1 = 0f
        Y1 = 0f
        if (popup != null && popup?.isShowing!!) {
            popup?.dismiss()
        }
        return super.onTouchEvent(me)
    }

    override fun onLongPress(key: Keyboard.Key?): Boolean {
        var c: Char? = null
        Log.e("key", key?.label.toString() + " " + key?.codes!![0])
        this.key = key
        X1 = key?.x?.toFloat() ?: 0f
        Y1 = key?.y?.toFloat() ?: 0f
        if (X1 != 0f && Y1 != 0f && key.popupCharacters != null && key.popupCharacters.length == 1) {
            val view: View =
                LayoutInflater.from(context).inflate(R.layout.item, FrameLayout(context))
            val tv = view.findViewById(R.id.tv) as TextView
            tv.text = key.popupCharacters
            popup = PopupWindow(context)
            popup?.setContentView(view)
            popup?.setWidth(WindowManager.LayoutParams.WRAP_CONTENT)
            popup?.setHeight(WindowManager.LayoutParams.WRAP_CONTENT)
            popup?.showAtLocation(this, Gravity.NO_GRAVITY, X1.toInt(), Y1.toInt())
        }

        return when (key.codes[0]) {

            Keyboard.KEYCODE_CANCEL -> {
                onKeyboardActionListener.onKey(KEYCODE_OPTIONS, null)
                true
            }
//            Row 1
            9440, 113, 9414, 81, 7815, 490, 418 -> {
                onKeyboardActionListener.onKey(49, null)
                true
            }

In these methods I make own popup for long press and return which key is pressed long.

 9440, 113, 9414, 81, 7815, 490, 418 -> {
                onKeyboardActionListener.onKey(49, null)
                true
            }

This code is logic if my keycode is matched then in onKeyboardActionListener.onKey method I put 49 which means If 'q' long pressed I will show popup and onKeyboardActionListener.onKey will take 49 means '1'.

Now in simple words above code is work for 'q' which code=113 if I long press 'q' or 113 key then popup will appear and keyboard will print 49 means '1'. Its very hard to explain but try this your first problem will solve. Happy coding in advance.