how to develop android soft keyboard example with a database - android

I have done a database for the suggestion words
but where to put it into the android soft keyboard example and how to use the words from db in the program? so that I will not need to type the word completely and it will shown the suggestion word in database

Inside the SDK check out the Samples folder, this contains a soft keyboard example and more information on how to suggest results.

You just need to handle database in SoftKeyboard.java Class.

To get the suggestion words from .db, please use SQLiteOpenHelper or SQLiteAssetsHelper.
To show the suggestion words in candidate view, please modify the updateCandidates() method of SoftKeyboard.java file in Google SoftKeyboard example project.
/**
* Update the list of available candidates from the current composing
* text. This will need to be filled in by however you are determining
* candidates.
*/
private void updateCandidates() {
if (!mCompletionOn) {
// mComposing is current text you typed.
if (mComposing.length() > 0) {
// Get suggested words list from your database here.
ArrayList<String> list = new ArrayList<String>();
list.add(mComposing.toString());
// This method will show the list as suggestion.
setSuggestions(list, true, true);
} else {
setSuggestions(null, false, false);
}
}
}
To enter the picked word from candidate view to input text, please modify following method in SoftKeyboard example project.
public void pickSuggestionManually(int index) {
if (mCompletionOn && mCompletions != null && index >= 0
&& index < mCompletions.length) {
CompletionInfo ci = mCompletions[index];
getCurrentInputConnection().commitCompletion(ci);
if (mCandidateView != null) {
mCandidateView.clear();
}
updateShiftKeyState(getCurrentInputEditorInfo());
} else if (mComposing.length() > 0) {
// If we were generating candidate suggestions for the current
// text, we would commit one of them here. But for this sample,
// we will just commit the current text.
commitTyped(getCurrentInputConnection());
// You need to add getter method for suggested words shown in candidate view
}
}

Related

kotlin: How to get if EditText has setError enabled?

How can I validate if EditText has setError enabled ?
I want to disable a button if EditText has an error.
Any other way to achieve this.
It kinda works when I put view.calcbutton.setEnabled(false) inside the validateEditText-function, but I use the validateEditText-function to validate multiple EditTexts and only the last function-call disables the button.
if the first function-call disables the button, the second enables it again, and vice versa.
But I want do it outside this function because if one of the multiple EditTexts has setError the button should be disabled.
//global var blockcalcbutton
var blockcalcbutton = 0
//function to validate EditTexts and set blockcalcbutton=1 if setError
validateEditText(view.input_volt, view, getString(R.string.invalid_volt))
if(blockcalcbutton == 1) {
view.calcbutton.setEnabled(false)
view.calcbutton.setText(getString(R.string.calcbutton_disabled))
view.calcbutton.setBackgroundResource(R.color.buttonDisabled)
} else {
view.calcbutton.setEnabled(true)
view.calcbutton.setText(getString(R.string.calcbutton_enabled))
view.calcbutton.setBackgroundResource(R.color.buttonBackground)
}
fun validateEditText(editText: EditText, message: String) {
val myEditText = editText
myEditText.addTextChangedListener(object: TextWatcher {
override fun afterTextChanged(s: Editable?) {
if(myEditText.text.toString() == "" || myEditText.text.toString() == "." || myEditText.text.toString() == "0") {
//setError
myEditText.setError(message)
//var to disable Button
blockcalcbutton = 1
} else {
//delete setError
myEditText.setError(null)
//var to enable Button
blockcalcbutton = 0
}
}
You can create a callback to notify when you set an error or delete it.
interface EditTextErrorListener {
fun onErrorSet()
fun onErrorDeleted()
}
Here you can notify:
if(myEditText.text.toString() == "" || myEditText.text.toString() == "." || myEditText.text.toString() == "0") {
//setError
myEditText.setError(message)
---> listener.onErrorSet()
//var to disable Button
blockcalcbutton = 1
} else {
//delete setError
myEditText.setError(null)
---> listener.onErrorDeleted()
//var to enable Button
blockcalcbutton = 0
}
Try approaching the problem from further away; when you look at this issue, you have multiple inputs (all the fields in your form) and one boolean output:
All fields are OK -> Enable the button
One or more fields are NOT Ok -> disable the button.
Additionally, you have local validation on each field (to display the error, etc.).
I'd argue that the local validation on each field, is to be done at the callback from the edit text (onAfterText, etc.etc.). You are already doing this.
A way to ensure the final validation (of the form as a whole) is fast, you could use a reference counter. E.g.:
Each edit text, validates with afterTextChanged. Each one performs whatever validation you think is right (can be a shared one if they are all the same).
If validation fails, you keep a reference to the failed field.
This will not have side-effects because nothing happens whether the item is or is not on the list.
This is some pseudo-code:
// keep a list of fields (this is just a way to do it, there are many others)
var errorFields = MutableHashSet<EditText>
later in your "validation" (afterTextChanges for example):
if (xxx && yyy && zzz) { //your validations for the individual editText
//setError
myEditText.setError(message)
// Store the reference of the editField in error.
errorFields.add(theEditTextThatHasAFailure).
} else {
myEditText.setError(null)
// If the validation is ok, you remove it:
errorFields.remove(theEditTextThatHasFailure)
}
// The form may have changed, update the global button state.
updateButtonState();
All this method needs to do, is something like:
button.enabled = errorFields.isEmpty()
This will only be empty if there are no error fields.
This is just an idea you may need to combine with callbacks for further control, but remember this one thing:
EditTexts (or any other widget) is and should not be responsible for the business logic that drives the whole "Form"; they are merely individual pieces of a larger puzzle, and as such, it's incorrect to give them the responsibility to drive your Form's validations; they can (and should) however, validate themselves and handle their own error state (like you're doing), but that's as far as it should go.
They can inform of a state change (e.g. via the listener onAfterText, or after gaining/losing focus, etc.) but shouldn't make business logic decisions. EditTexts are designed to take user input and display it on screen, that's all.
Last but not least, don't forget to remove the references when you destroy your views
onDestroy() {
errorFields.clear()
}

I use AccessibilityEvent.getSource() get TextView.Can I do something to change the TextView's text?

This is my code.In my custom AccessibilityService,I get all TextView by the method,onAccessibilityEvent.And then I want to mark the text.
public void onAccessibilityEvent(AccessibilityEvent event) {
AccessibilityNodeInfo source = event.getSource();
if (source == null) {
return;
}
for (int i = 0; i < source.getChildCount(); i++) {
AccessibilityNodeInfo node = source.getChild(i);
if (TEXTVIEW.equals(node.getClassName())) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
Bundle arguments = new Bundle();
arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE,
node.getText().toString()+1);//just want to mark
node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
}
}
}
}
This bit of code works fine for me!
public void onAccessibilityEvent(AccessibilityEvent e) {
if (e.getSource() == null) return;
if (e.getSource().getClassName().equals(EditText.class.getName())) {
Bundle arguments = new Bundle();
arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE,
"android");
e.getSource().performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
}
}
And happily places the text "android" into the editable text container! AH, now, if you want to change the text of a TextView, now, this is an illegal thing to try and do. The text of a TextView is a readonly property. You can't edit it. An accessibility node info is an accessibility services representation of a rendered view. You can't ask the App to change the text of a TextView. This has MASSIVE security implications. Oh, so you have a service that tells everyone that the Password field is the Username field and vice versa? Isn't that handy? Basically, you can only edit the text of a view that makes sense to be Editable.
That being said, you can tell the user that the text is whatever you want to tell them it is, when you provide feedback. Not that I would use an accessibility service that spoke "kitten" for every view in the hierarchy... but, your use case/what you want to accomplish is not clear. If you would provide another question that asks "This is what I want to accomplish..." instead of "this is what I tried, why doesn't it work?" I would happily help.

Get an event triggered when text change unity?

Here the Text Area is constantly changing in terms of number and I want to trigger an event when the Text Area gets a particular number example I have tried this -
public void myfunction45(Canvas Panel)
{
if (Indicator = 45) {
Panel.enabled = false;.
}
} //(indicator- www.progress).
But it does not work(it does not read it nothing happens). how do I match the condition as the number is to be specific. please give an example for explanation. Thanks in advance.
That if statement would cause you problems.
You would want:
if(Indicator == 5)
instead. At the moment you're assigning the value without checking it, this would cause a compiler error. If it's just a typo, then update your answer, slightly confusing otherwise.
With regards to checking the text value. You'd have to grab the text value, for that you need a reference to the Text area. This approach assumes that the text area has it's value set by a user. Currently you're not grabbing any text values to compare, as a result, the if statement won't know what to compare.
Here's one approach:
public void myfunction5(Canvas Panel)
{
float result;
string textValue = yourTextArea.text;
if(Single.TryParse(textValue, out result))
{
if(result == Indicator)
{
Panel.enabled = false;
}
}
}
You use TryParse to avoid any potential exceptions that would be thrown if the user entered something that wasn't a number. This method will take the value from your text area, how you get your text area is up to you, and try to parse the text value into a float. The method will return true if the parse was a success, false otherwise.
Here's the reference for the TryParse stuff:
https://msdn.microsoft.com/en-us/library/26sxas5t(v=vs.110).aspx
If you wanted to parse it to an int, then you'd be using the Int32's version of TryParse, https://msdn.microsoft.com/en-us/library/system.int32_methods(v=vs.110).aspx
I'd also recommend having a peak at the Input Field documentation: https://docs.unity3d.com/Manual/script-InputField.html
You can subscribe your method to the Input-fields On Value Changed event, your function will need to tweaked slightly though:
public void myfunction5(string text)
{
float result;
if(Single.TryParse(text, out result))
{
if(result == Indicator)
{
CachedPanel.enabled = false;
}
}
}
Don't forget to store a reference to the panel you want to disable.
Hopefully this is what you're after.
Panel is already a Canvas type, it doesn't make any sense to GetComponent<Canvas> on the same type.
Try using Panel.enabled = false;.
For the rest, we don't know how you get the Indicator reference, or how you built the UI hierarchy, so we can't assess if the problem is there.
Edit: I could I miss the single = baffles me lol. I should avoid answering questions when I'm tired.

Replace gesture library templates in android

Is it possible to replace a gesture template of template library from a running application?
I am building a handwriting recognizer system in which there are templates of letters in gesture library file.So basically after loading the library inside the code i compare user input gesture like:
public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
ArrayList<Prediction> predictions = gesturelib.recognize(gesture);
if (predictions.size() > 1) {
for(Prediction prediction: predictions){
//i compare prediction name here and if matches print it in an edittext
}
This should work good until user will give the same pattern like i did during building the library template.But i want to give an user that flexibility to replace an template item with his handwritten pattern when there is a mismatch of prediction.
Because below 2 handwritten gesture samples are different in terms of pattern,but not as a letter.Suppose,my system supports the 1st image pattern,i want when user will give 2nd image pattern the system will ask confirmation from user to replace it with the library pattern of A and then replace it after confirm.So next time the system will recognize user pattern much better.
Any help would be greatly appreciated.
If I understand correctly, you want to replace an already existing gesture with a new one?
So, when the user inputs a gesture that isn't in the library, your app asks the user to select which gesture they wish to replace? From your question, I will assume that when user draws a lowercase a(and if a isn't in the library), user is presented with a list of all available gestures/letters that your app currently supports. And then, the user selects capital A, and now, capital A must be replaced with lowercase a. In the following code, oldGesture is the Gesture corresponding to A. And newGesture is the Gesture just drawn.
The process for that would be: delete the old gesture, add the new one using old gesture's name. To delete a gesture, use GestureLibrary.removeGesture(String, Gesture):
public void onGesturePerformed(GestureOverlayView overlay, final Gesture gesture) {
ArrayList<Prediction> predictions = gesturelib.recognize(gesture);
if (predictions.size() > 1) {
for(Prediction prediction: predictions){
if (prediction.score > ...) {
} else {
if (user wants to replace) {
showListWithAllGestures(gesture);
}
}
}
}
}
public void showListWithAllGestures(Gesture newGesture) {
....
....
// User picks a gesture
Gesture oldGesture = userPickedItem.gesture;
String gestureName = userPickedItem.name;
// delete the gesture
gesturelib.removeGesture(gestureName, oldGesture);
gesturelib.save();
// add gesture
gesturelib.addGesture(gestureName, newGesture);
gesturelib.save();
}
To get a list of all available gestures:
// Wrapper to hold a gesture
static class GestureHolder {
String name;
Gesture gesture;
}
Load gestures using GestureLibrary.load():
if (gesturelib.load()) {
for (String name : gesturelib.getGestureEntries()) {
for (Gesture gesture : gesturelib.getGestures(name)) {
final GestureHolder gestureHolder = new GestureHolder();
gestureHolder.gesture = gesture;
gestureHolder.name = name;
// Add `gestureHolder` to a list
}
}
// Return the list that holds GestureHolder objects
}
Edit:
Sorry, but the check I have suggested: if (wants to replace) is being carried out at the wrong place in code.
if (predictions.size() > 1) {
// To check whether a match was found
boolean gotAMatch = false;
for(int i = 0; i < predictions.size() && !gotAMatch; i++){
if (prediction.score > ... ) {
....
....
// Found a match, look no more
gotAMatch = true;
}
}
// If a match wasn't found, ask the user s/he wants to add it
if (!gotAMatch) {
if (user wants to replace) {
showListWithAllGestures(gesture);
}
}
}

AutoCompleteTextView allow only suggested options

I have a DialogFragment that contains AutoCompleteTextView, and Cancel and OK buttons.
The AutoCompleteTextView is giving suggestions of usernames that I'm getting from server.
What I want to do is to restrict the user to be able to enter only existing usernames.
I know I can do check if that username exists when the user clicks OK, but is there some other way, let's say not allow the user to enter character if there doesn't exist such username. I don't know how to do this because on each entered character I'm getting only up to 5 suggestions. The server is implemented that way.
Any suggestions are welcomed.
Thank you
I couldn't find more suitable solution then this:
I added this focus change listener
actName.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
ArrayList<String> results =
((UsersAutoCompleteAdapter) actName.getAdapter()).getAllItems();
if (results.size() == 0 ||
results.indexOf(actName.getText().toString()) == -1) {
actName.setError("Invalid username.");
};
}
}
});
Where the method getAllItems() returns the ArrayList containing the suggestions.
So when I enter some username, and then move to another field this listener is triggered and it checks if the suggestions list is not empty and if the entered username is in that list. If the condition is not satisfied, an error is shown.
Also I have the same check on OK button click:
private boolean checkErrors() {
ArrayList<String> usernameResults =
((UsersAutoCompleteAdapter) actName.getAdapter()).getAllItems();
if (actName.getText().toString().isEmpty()) {
actName.setError("Please enter a username.");
return true;
} else if (usernameResults.size() == 0 || usernameResults.indexOf(actName.getText().toString()) == -1) {
actName.setError("Invalid username.");
return true;
}
return false;
}
So if the AutoComplete view is still focused, the error check is done again.

Categories

Resources