I want to create a custom keyboard which will be available in my application only (It's used jut for a single EditText in one activity), and I was wondering what would be the best way to do so. Here are my specifications for the keyboard:
It should always be displayed in the activity it is used (Regardless whether the EditText is focused or not).
It will have 2 or more keys layouts (Similar to the regular keyboard which has letters layout and a few numbers/symbols layouts).
Some keys may require some special action (Rather than simply adding their android:codes key value to the EditText).
It doesn't offer candidates for completion/correction.
It doesn't offer more than one input type (Like the regular keyboard which has TYPE_CLASS_NUMBER, TYPE_CLASS_DATETIME and so on...).
How should I develop it? Should I create a full input method service for it? Or should I create just a KeyboardView and add it to the activity's layout? (I want to use KeyboardView for the convenience of keys creation and click events handling)
Since it's a one-off thing and not meant as a separate app, You can simply use whatever method is easiest for you (The KeyboardView method).
Try it out and make sure it's responsive and snappy. If it works, then simple and easy method would be my recommendation.
Maybe you could take a look at this. I think the best way is to make a custom layout and inflate it. Theres a tutorial given here too.
Related
I'm trying to write UI automation tests for the custom soft keyboard using UI Automator and\or Espresso. Tried different ways but I can't find a proper solution to "find the exact button on the opened keyboard and click it".
Problems:
UIAtomator's UiDevice.findObject(By.text("Q")).click() doesn't find Q button on keyboard.
Espresso's onView(withText("Q")).perform(click()) doesn't find the button either.
For now, it looks like the only way to click button is to measure XY coordinates based on screen height and keyboard height. But this solution is ugly and not persistent.
typeText("text")and uiObject.text = "text" don't work since it bypasses keyboard input.
Was anyone working with custom keyboards? Please help.
Since you're building a custom soft keyboard then I expect you're using a KeyboardView. KeyboardView draws the keys using a canvas therefore it is not possible to get the resource ids of the keys... so no chance to find them through the UiDevice's findObject method.
Considering the KeyboardView class is deprecated since API 29, a possible solution will be to reimplement your own KeyboardView (as suggested here) and use AccessibilityNodeInfo class to build virtual elements (one for each key) that will be included into the view hierarchy.
The best solution in my opinion would be to create your own TCP server to solve this issue. Please refer to this link to find out how: https://ops.tips/blog/a-tcp-server-in-c/
I am developing a custom keyboard app. I have created my custom keyboard settings screen using a PreferenceActivity. I want to include "Auto correct", "Auto Capitalize Word" and "Vibrate" options in my custom keyboard settings section. All these options are available for the default Android keyboard. Please suggest any tutorials or reference links for achieving this.
You can implement those settings on your own.
Auto Capitalize Word and Vibrate are easy to implement with just a couple method overrides (for example you could override this method and when the the method is called you can send a small vibration if the user has set the Vibrate option to true). Auto capitalize can also be achieved via various ways.
Now the Auto Correct function is a little trickier to implement than the first two. First of all you will need a vocabulary of which to draw your suggestions on AutoCorrect and several other things that depend on your implementation. This is an example of a ready view that you could possibly subclass to achieve something different if you wish.
Finally the most important part that might interest you is this blog entry.
I'm writing an app using Titanium. I want to be able to automatically dismiss the keyboard anytime something outside of the text field is clicked. I have yet to find an elegant solution for this issue.
Couple things that I've thought about, but am still looking for a better solution:
Assign event listeners to basically everything else present in the view, and dismiss the keyboard (using textField.blur()). I want to avoid this since it results in a LOT of code just to dismiss the keyboard. Also, if I end up adding anything else to the view, I'll have to add a click listener to that object as well, so it's not very maintainable.
Create a large transparent view, and have it take up the entire screen. Place it directly beneath the text field and add to it one click listener on that which will dismiss the keyboard. This is a better solution than #1, but still isn't great because I've had a lot of trouble getting zIndexes to work properly. It's also inefficient for my purposes because I've got views with a specific width and height that encapsulate text fields. I've used these for the sake of code simplicity and I re-use them throughout my application.
I've tried adding a listener for the "blur" event for the text field but that doesn't seem to get fired appropriately.
That's about it. I'm sort of at a loss. The zIndexing also behaves strangely on the iPhone, and I haven't tried on Android yet. Also, as I mentioned above, many of the text fields I use are encapsulated within small views with set widths/heights-- so I think that will affect the functionality of Z-indexes.
So the root question is: What's the best way to dismiss a keyboard whenever anything outside the text field that's in focus is clicked?
If I'm correct the click event propagates through all views and windows therefore your #1 option could be modified to check for clicks on the bottom most layer (view or window), check for its source then decide what to do.
I have a custom view for which I want the user to be able to enter characters from an app-defined set of characters. To do this, as I understand it, I need to write an input method service. The user not only needs to install it, but then needs to enable the IME in the Settings > Language & keyboard, and then select the custom IME for use in the view.
This seems really crazy. I want this IME to be used for just one view in one application. I don't want it to be available system-wide or force the user to make global setting changes.
The only alternative I can see is defining my own in-app custom view and simulate an IME (probably a full-screen one) when the view gains focus. Isn't there anything better?
I do not think the IMEs are conceived for that kind of task. Their concept is to allow user input in a standardized way so it can be used across multiple applications from different vendors.
My strategy would be similar to what you are thinking:
prevent the soft keyboard from appearing,
intercept the menu button key press to show your own instead,
add a custom layout (probably a GridView or a TableView inside a RelativeLayout with bottom gravity)
use an OnItemClickListener
send the required KeyEvents to the root View. If the characters are invented, the KeyCodes do not even need to relate to the ASCII character. You just intercept the code and use at will.
Sorry I can't give you an option as you asked, but this alternative does not seem to be much more work than creating a whole new IME.
Edit: upon reading the related question, it makes sense to use android.inputmethodservice.KeyboardView instead of reinventing the wheel with the GridView.
I need to bring up a few different keyboards: a 'standard' keyboard with Ctrl and Alt keys; maybe a cursor pad; and so on.
I have found the Keyboard class, which would let me define a keyboard in an XML resource. I have found that the KeyboardView class has a setKeyboard method ... and, so far, I have not found any other class that takes a Keyboard instance.
How am I supposed to use the KeyboardView? I tried adding one to my activity's XML; finding it at runtime with findViewById; and then calling setKeyboard ... but all this did was mess up my layout and not bring up the special keyboard.
This turns out to be very doable, and my initial problems probably had more to do with general Android newbiness (this is my first Android app) and not the KeyboardView. In particular, I'm used to visibility being a simple binary property.
Anyhow:
Declare the KeyboardView in your XML file with android:visibility="gone".
Before you make the view visible, call setKeyboard() to attach a keyboard. This is important, as the KeyboardView gets its size from the keyboard.
To get raw key events, call KeyboardView.setOnKeyboardActionListener(). After refactoring this functionality from a Dialog back to my main View, I put the OnKeyboardActionListener functionality in a stand-alone class, but this is not necessary.
I call keyboardView.setEnabled(true);. This does not seem to be necessary, but I am not sure (yet) under what circumstances it would matter; perhaps only if you call setEnabled(false).
I call keyboardView.setPreviewEnabled(true); - this is especially useful if the user won't be getting visual feedback from an input biox right above the keyboard.
Then, with the keyboard all set, call keyboardView.setVisibility(VISIBLE);.
To hide the keyboard when appropriate, just call keyboardView.setVisibility(GONE);. To change the keyboard (as on a shift key, or a cycle-through-the-symbol-keyboards key, just call setKeyboard again. I use a Map<<Integer, Keyboard> to implement a lazy-create pattern; a weak reference may be desirable, if the program will run for a long time and the keyboard will not be used much.
Keyboard and KeyboardView are for making alternative input method engines (IME). These are then able to be chosen by the user, just as they can install Swype, Graffiti, and other ones from the Android Market.
You, as a developer, can create such an IME, but you cannot force it upon the user.
using the inputType attribute in your editText view will help pick between the different system keyboards (phone, email, etc) Also the APIDemos application that comes with the SDK has an example of how to implement a forced custom keyboard for your app only.