Android KeyBoard.Key disable iconPreview of special keys?

我的梦境 提交于 2019-12-22 07:00:29

问题


I customize my own soft keyboard by implementing the KeyboardView.OnKeyboardActionListener interface.

When the keys are pressed, it will show a preview popup.

My problem is how to disable the preview popup for special keys such as SHIFT and DELETE?

I have tried to set the android:iconPreview attribute to null but it didn't work.

<Key
    android:codes="-1"
    android:keyIcon="@drawable/key_shift" 
    android:keyWidth="15%p"
    android:isModifier="true"
    android:isSticky="true"
    android:keyEdgeFlags="left" />

Have any idea?

Thanks in advance!


回答1:


First you must implement OnKeyboardActionListener

then use onPress() and onRelease() to control the preview popup like this:

public void onPress(int primaryCode) {
    if (primaryCode==-2||primaryCode==-5||primaryCode==-4){
        mInputView.setPreviewEnabled(false);
    }
}

public void onRelease(int primaryCode) {
    mInputView.setPreviewEnabled(true);
}



回答2:


public void onCreate() {

    mInputView.setPreviewEnabled(false);

}

public void onPress(int primaryCode) {
    if (primaryCode==-1||primaryCode==-2||primaryCode==-5||primaryCode==-4){

    } else {
       mInputView.setPreviewEnabled(true);
    }
}

public void onRelease(int primaryCode) {
    mInputView.setPreviewEnabled(false);
}



回答3:


The problem with the above solution, as commented is that

if I press other key (e.g. key A) and move my finger to the key SHIFT, the preview icon still popup

To counter this, I had to extend the KeyboardView class Disclaimer - The following contains reflection api

Here is the modified Keyboard class

import android.content.Context
import android.inputmethodservice.KeyboardView
import android.os.Build
import android.support.annotation.RequiresApi
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.widget.TextView
import com.continental.testapplication.utils.dpToPx
import java.lang.reflect.Method

class ModifiedKeyboardView :KeyboardView{
    constructor(context: Context, attrs: AttributeSet):super(context, attrs)
    constructor(context: Context, attrs: AttributeSet, defStyleAttr:Int):super(context, attrs, defStyleAttr)
    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    constructor(context: Context, attrs: AttributeSet, defStyleAttr:Int, defStyleRes:Int):
            super(context, attrs, defStyleAttr, defStyleRes)

    /**
     * Return true, if preview is to be shown, false otherwise. If not implemented,
     * the preview is going to be shown.....
     */
    var keyPreviewIndexListener:((Int)->Boolean) ?= null

    private val findKeyIndicesMethod:Method = KeyboardView::class.java.getDeclaredMethod(
            "getKeyIndices",Int::class.java,Int::class.java, (IntArray::class).java).also {
        it.isAccessible = true
    }
    private val previewText:TextView = KeyboardView::class.java.getDeclaredField(
            "mPreviewText").let {
        it.isAccessible = true
        it.get(this) as TextView
    }


    override fun onTouchEvent(me: MotionEvent?): Boolean {
        if(me == null) return super.onTouchEvent(me)
        when(me.action){
            MotionEvent.ACTION_DOWN -> isPreviewEnabled = true
            MotionEvent.ACTION_MOVE -> {
                val touchX = me.x - paddingLeft
                var touchY = me.y.toInt() - paddingTop
                val verticalCorrection = dpToPx(14f, context)
                if (touchY >= -verticalCorrection)
                    touchY += verticalCorrection.toInt()

                val keyIndex:Int = findKeyIndicesMethod.invoke(this, touchX.toInt(), touchY.toInt(), null) as Int

                    isPreviewEnabled = keyPreviewIndexListener?.invoke(keyIndex)?:true
                    if(!isPreviewEnabled){
                        previewText.visibility = View.INVISIBLE
                    }


            }
        }
        return super.onTouchEvent(me)
    }
}

Paste it as is.

Next, in the class where you are manipulating the keyboard,

 keyboardView.keyPreviewIndexListener = {
            it != spaceIndex && it != doneIndex && it != deleteIndex && it != `your_custom_index`
        }

To find the indexes you can just do the following

 doneIndex = keyboardView.keyboard.keys.indexOfFirst {
            it.codes[0] == Keyboard.KEYCODE_DONE
        }

This will prevent the movement. Please append the other solution also. i.e

override fun onPress(primaryCode: Int) {
            Log.e("onPress", primaryCode.toString())
            checkAndActivatePreview(primaryCode)

        }

        override fun onRelease(primaryCode: Int) {
            Log.e("onRelease", primaryCode.toString())
            deactivatePreview()
        }

 private fun checkAndActivatePreview(primaryCode: Int) {
        keyboard.isPreviewEnabled =
                (primaryCode != `your_custom_code`
                && primaryCode != SPACE_KEY_CODE && primaryCode != Keyboard.KEYCODE_DELETE
                && primaryCode != Keyboard.KEYCODE_DONE)
    }


来源:https://stackoverflow.com/questions/8180942/android-keyboard-key-disable-iconpreview-of-special-keys

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