问题
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