简体   繁体   中英

Make Buttons function like keyboard

I have an application that should work on a tablet, and there's a page where a recyclerview is present and in its row item there is 2 edit texts (with numberDecimal as input), the default keyboard shouldn't appear because it's covering a considerable large portion of screen.

I created buttons in the activity to act like the keyboard buttons however the problem is how to make the button from activity to communicate with the edit texts in the adapter.

how can i know that if I press (Button "1") for example that it should display 1 in the focused edittext in the adapter, and how if I pressed "<" or ">" button it should know the previous and next edit texts

please help

  1. Intiliased the Adapter before clicking the buttons. because, required the instance of your Adapter to perform.
  2. create a method add() in your Adapter
ArrayList<String> dataList = new ArrayList<>();
public void add(String element) {
     dataList.add(element);
     notifyItemInserted(dataList.size() - 1);//this will update the recyclerview with data inserted
}

from your button click call this method with your Adapter instance

yourAdapter.add(btn1.getText().toString());

I'll provide example in Kotlin, I assume that is what you are using. So you can simply override the key handling in the parent class like:

Make a method that you call one time from onCreate like:

 fun keydown_onClick(){
        try{
            myActivity.setOnKeyListener { _, keyCode, event ->
                if (keyCode == android.view.KeyEvent.KEYS_YOU_CARE_ABOUT) {
                    //handle it
                    if(activeViewHolder != null){
                        var displayText = activeViewHolder.yourEditText.text
                        keyPressedChar = (char)event.getUnicodeChar()+""
                        //if it's a special key you care about, then handle it in a when statement or if and pass to your adapter if needed to go to next row for example.
                        displayText += keyPressedChar
                        activeViewHolder.yourEditText.text = displayText
                    }
                    return@setOnKeyListener true//we've processed it
                } else
                    return@setOnKeyListener false// pass on to be processed as normal
            }
        }catch (ex: Exception){
            A35Log.e(mClassTag, "Error handling onkeydown listener: ${ex.message}")
        }
    }

Next up is how do you handle it. well you should keep track of the active row. You can do this by creating a callback in your activity that gets notified when a different row is selected or gains focus.

interface IFocusChangeListener {
    fun onNewItemFocused(holder: MyApdaterViewHolder, item: DataItem, index: Int)
}

This will be passed into your adapter and used to fire back to your activity class.

//in activity

var activeViewHolder: MyAdapterViewHolder? = null
var activeIndex: Int? = null
var activeItem: DataItem? = null
fun onNewItemFocused(holder: MyAdapterViewHolder, item: DataItem, index: Int){
     activeViewHolder = holder
     activeIndex = index
     activeItem = item
}

//now in your key down event you simply pass through the value to the editText in the activeViewHolder,

So last piece is in the adapter.

//on bind View create View holder, the usual bloat. Then when you have your editText you simply add.

var item = currentDataItem
var index = currentDataItemIndex
var viewHolder = currentViewHolder //from onBind
viewHolder.setOnFocusChangeListener(object: View.OnFocusChangeListener{
            override fun onFocusChange(v: View?, hasFocus: Boolean) {
                if(hasFocus){
                    mFocusListener?.onNewItemFocused(viewHolder, item, index)
                }
            }
        })

//in adapter you may also need

fun onNextEditTextClicked(item: DataItem, index: Int){
    //get next data Item by index + 1 if exist and get it's viewholder.editText and set focus to it, this will automatically trigger the focus event back to the activity
}
fun onPreviousEditTextClicked(item: DataItem, index: Int){
    //get next data Item by index - 1 if exist and get it's viewholder.editText and set focus to it, this will automatically trigger the focus event back to the activity
}

Now you have the focused viewholder in your calling activity, you can catch the keys you care to catch, probably all of them. You can pass them in, you should be good to go.

NOTE*

For the record, if you are using modern practices, aka Data Binding, then you should be able to just update a bindable string in your model and it will show up on the screen without having to pass it around. You could also bind the focus to being selected and just update the selected boolean of the models. There are cleaner ways to do this if you use binding. But for now, just helping you without complicating it.

This solution may need tweaked, I just typed it here so could be off a bit, but should mostly get you there.

Happy Coding.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM