Clear focus EditText when back button is pressed when softkeyboard is showing - android

I know that there are quite some questions out here regarding this question. But non of them have the answer that I'm looking for.
I've got 7 ET inside a ScrollView. When I start the application no ET has focus because I've added the following two lines to my overall layout:
android:focusable="true"
android:focusableInTouchMode="true"
When I click on an ET the softkeyboard is shown, which I want, then I set the value (let say 20). I press a '2' followed by a '0' and then press the back button. At this point the keyboard disappears, but the focus stays. I would like to clear the focus too when pressing the back button to hide the keyboard.
Because when the focus is cleared the layout of the ET is set like I want.
They all have about the some code, which is:
// Right Cable
RightCable = (EditText) findViewById (R.id.RightCable);
RightCable.setRawInputType(Configuration.KEYBOARD_12KEY);
RightCable.setOnFocusChangeListener(FocusChanged);
RightCable.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
if(RightCable.isFocused()){
LengthRightCable = Double.parseDouble(RightCable.getText().toString());
Calculate();
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(s.toString().matches("")) {
RightCable.setText("0.00");
Selection.setSelection(RightCable.getText(), 0, 4);
}
}
});
I use a focus listener to change the input of the ET to a number like 5.00 instead of 0.
OnFocusChangeListener FocusChanged = new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
EditText et = (EditText) v;
et.setSelection(0, et.getText().length());
if(!hasFocus){
String userInput = et.getText().toString();
int dotPos = -1;
for (int i = 0; i < userInput.length(); i++) {
char c = userInput.charAt(i);
if (c == '.') {
dotPos = i;
}
}
if (dotPos == -1){
et.setText(userInput + ".00");
} else if(userInput.length() < 5) {
if ( userInput.length() - dotPos == 1 ) {
et.setText(userInput + "00");
} else if ( userInput.length() - dotPos == 2 ) {
et.setText(userInput + "0");
}
}
}
}
};

Just override `onBackPressed()`
method in your activity and check condition for Edittext
focus before run
super.onBackPressed();
#Override
public void onBackPressed() {
if( et_search.isFocused()){
et_search.clearFocus();
}else {
super.onBackPressed();
}
}

For this you have to take the onTouchListener on the parent layout of the Layout File. on the TouchListener you have to code to hide the Keyboard when click outside the EditText. Please follow following XML Layout and Java class to resolve this issue.
Please follow the follow the following url to resolve this issue http://amitthaperandroidquery.blogspot.com/2011/10/remove-keyboard-after-click-outside.html

Related

How to check EditText isEmpty in Android

I want to create a login page, I used EditText to insert user info. I want to check EditText to see if it is Empty Invisible login Button, when inserted any character with user visible Login Button.
I tried the code shown below, but it did not not work for me :
//Show Login Button
String login_phoneString = login_PhoneText.getText().toString().trim();
if (login_phoneString.isEmpty()) {
login_image.setVisibility(View.INVISIBLE);
} else {
login_image.setVisibility(View.VISIBLE);
}
When EditText is empty, the button is invisible, and when set character in EditText again the login button is not shown.
How can I fix this problem ?
You want to show/hide the Login button base on the text of EditText so you need to listen for changing in EditText by use TextWatcher.
Use this code inside onCreate() method
login_PhoneText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
String login_phoneString = login_PhoneText.getText().toString().trim();
if (login_phoneString.isEmpty()) {
login_image.setVisibility(View.INVISIBLE);
} else {
login_image.setVisibility(View.VISIBLE);
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {}
});
Using trim()
if(et.getText().toString().trim().length() == 0) //empty
Using TextUtils
if(TextUtils.isEmpty(et.getText().toString().trim()) //Empty
Using isEmpty()
if(et.getText().toString().isEmpty()) //Empty
EDIT
You can do this :
//Show Login Button
String login_phoneString = login_PhoneText.getText().toString().trim();
if (TextUtils.isEmpty(login_phoneString) {
login_image.setVisibility(View.INVISIBLE);
} else {
login_image.setVisibility(View.VISIBLE);
}
Try to check like this way
EditText edt = (EditText) findViewById(R.id.edittext);
String abc = edt.getText().toString();
if (abc.matches("")) {
Toast.makeText(this, "enter something", Toast.LENGTH_SHORT).show();
login_image.setVisibility(View.INVISIBLE);
return;
}
else
{
login_image.setVisibility(View.VISIBLE);
}
String login_phoneString = login_PhoneText.getText().toString().trim();
if (login_phoneString.equals("")) {
login_image.setVisibility(View.GONE);
} else {
login_image.setVisibility(View.VISIBLE);
}
Use View.GONE instead of INVISIBLE. when INVISIBLE it is still clickable.
Use TextUtils.isEmpty():
if (TextUtils.isEmpty(yourEditText.getText().toString())) {
//Empty
} else {
//Not empty
}

EditText not adding space after word swiped in

I have an android phone using googles keyboard. On any EditText field in any other app if I use the swipe method to enter text in, it adds a space after each word. However, I have written my own app and when I use the swipe method to enter text on my EditText field it does NOT add a space sothewordsbleedtogether. This is very annoying.
I have an AlertDialog with a linear view added. On that linear view there is a text EditText. Here is my code to create the EditText and add it to the view:
final EditText titleBox = new EditText(this);
titleBox.setInputType(InputType.TYPE_TEXT_FLAG_AUTO_CORRECT |
InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES |
InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE);
titleBox.setHint("Title");
layout.addView(titleBox);
Any ideas why its not adding spaces in between my words?
This was marked as a possible duplicate, but that question was about not allowing the first character to be a space....Im asking about allowing a space after words that are entered via a keyboard swipe.
Update
Here is the entire method of similar page, its having the same issue, its slightly less complex then the initial page I was troubleshooting. This one doesn't even have a LinearLayout associated:
private void addBudget(final Budget budget) {
EditText taskEditText = new EditText(this);
taskEditText.setId(R.id.add_budget_text);
taskEditText.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
String dialogTitle = "Add budget";
final AlertDialog dialog = new AlertDialog.Builder(this)
.setTitle(dialogTitle)
.setMessage("What do you want to call this budget?")
.setView(taskEditText)
.setPositiveButton("Save", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// final String task = ;
SQLiteDatabase db = mHelper.getWritableDatabase();
Budget lBudget = new Budget();
if (budget != null) {
lBudget = budget;
}
EditText taskEditText = (EditText) findViewById(R.id.add_budget_text);
lBudget.title = String.valueOf(taskEditText.getText());
// Init custom budget object //new Budget(){{ title=task; id = budgetID;}}
int retId = mHelper.saveBudget(db, lBudget);
db.close();
int retRow = updateUI(retId);
mTaskListView.smoothScrollToPosition(retRow);
}
})
.setNegativeButton("Cancel", null)
.create();
// Handle done on soft keyboard
taskEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
int result = actionId & EditorInfo.IME_MASK_ACTION;
if (result == EditorInfo.IME_ACTION_DONE) {
dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick();
return true;
}
return false;
}
});
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
dialog.show();
}
I didnt know if you got solved, i just had the same problem today and found a way to solve it.
I saw a "extrange" performance of the swipe, sometimes it showed the "blankspace" and sometimes not.
The way i found to check if it was shown and if it didnt, add it, was this:
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
checkCancel();
int compare = count-before;
if(compare>1){
String text = editText.getText().toString();
String lastChar = (text.substring(text.length()-1,text.length()));
if(!lastChar.equals(" ")){
String plus = text+" ";
editText.setText(plus);
editText.setSelection(editText.getText().length());
}
}
}
#Override
public void afterTextChanged(Editable s) {
}
} );
You can see, onTextChanged can use the variables "before" and "count" and if the compare (difference between last word and current one) is more than 1, it's a word entered by Swipe. Then you can check if the "blankspace" is shown, and if not, just add it and perfom anything you want with it.
Hope it helps!
Could you try this? Add the filter into the editText. I used it for enter code on my app.
EditText et = (EditText) findViewById(R.id.edit_text);
et.setFilters(new InputFilter[] {
new InputFilter() {
#Override
public CharSequence filter(CharSequence charSequence, int start, int end, Spanned spanned, int start, int end {
if(charSequence.equals("")){
return charSequence;
}
if(charSequence.toString().matches("[a-zA-Z ]+")){
return charSequence;
}
return "";
}
}
});
So I uninstalled the google keyboard and reinstalled and I changed the build to release. One of those two things fixed it.

Live txt field send without button

I'm trying to use a toggle button to switch between English -> Morse code and Morse code -> English. At this moment, I have to press the toggle button everytime I want the inputted data to be converted and this is not good. I want the toggle button only to be pressed once as desired to select to what it wants to translate to, and then while the user inputs data into the txt field, it will translate it as the user inputs data. Is this possible? And will this cause the app to lag?
If this will lag I'd like something else then.
A switch like the toggle button, to again choose to which one it needs to translate to. And then use to button to convert. This is somewhat possible now, but I need to click on the toggle button to translate, while I want to select the convert button to translate, and the toggle button to choose between English -> Morse code and Morse code -> English.
Here is some code I have for the toggle button:
final ToggleButton toggle = (ToggleButton) findViewById(R.id.toggleEnMo_Button);
toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
// to English
Toast.makeText(MainActivity.this, toggle.getText(), Toast.LENGTH_SHORT).show();
if (edit_convert.getText().length() != 0) {
morseCode.setEnInput(edit_convert.getText().toString());
String txtToEnglish = morseCode.getEnInput();
morseCode.setMorseInput(morseCode.toEnglish(txtToEnglish));
String txtToMorse = morseCode.getMorseInput();
txtEnglish.setText(txtToEnglish);
txtMorse.setText(txtToMorse);
} else {
txtEnglish.setText("Text field empty");
}
} else {
// to Morse
Toast.makeText(MainActivity.this, toggle.getText(), Toast.LENGTH_SHORT).show();
if (edit_convert.getText().length() != 0) {
morseCode.setEnInput(edit_convert.getText().toString());
String txtToEnglish = morseCode.getEnInput();
morseCode.setMorseInput(morseCode.toMorse(txtToEnglish));
String txtToMorse = morseCode.getMorseInput();
txtEnglish.setText(txtToEnglish);
txtMorse.setText(txtToMorse);
} else {
txtEnglish.setText("Text field empty");
}
}
}
});
And the code I use for radio buttons and convert button which works:
button_convert.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// show radio button text
int selectId = radioMorseGroup.getCheckedRadioButtonId();
radioMorseButton = (RadioButton) findViewById(selectId);
if (selectId == R.id.toEnglish) {
Toast.makeText(MainActivity.this,
radioMorseButton.getText(), Toast.LENGTH_SHORT).show();
// to english
if (edit_convert.getText().length() != 0) {
morseCode.setEnInput(edit_convert.getText().toString());
String txtToEnglish = morseCode.getEnInput();
morseCode.setMorseInput(morseCode.toEnglish(txtToEnglish));
String txtToMorse = morseCode.getMorseInput();
txtEnglish.setText(txtToEnglish);
txtMorse.setText(txtToMorse);
} else {
txtEnglish.setText("Text field empty");
}
} else if (selectId == R.id.toMorse) {
// to morse
Toast.makeText(MainActivity.this,
radioMorseButton.getText(), Toast.LENGTH_SHORT).show();
if (edit_convert.getText().length() != 0) {
morseCode.setEnInput(edit_convert.getText().toString());
String txtToEnglish = morseCode.getEnInput();
morseCode.setMorseInput(morseCode.toMorse(txtToEnglish));
String txtToMorse = morseCode.getMorseInput();
txtEnglish.setText(txtToEnglish);
txtMorse.setText(txtToMorse);
} else {
txtEnglish.setText("Text field empty");
}
}
}
});
I believe you are asking about intercepting user input as they type into a text field. You can use a TextWatcher. Here's some sample code that demonstrates this.
EditText mInputEt;
public void onCreate(Bundle savedInstanceState){
...
mInputEt.addTextChangedListener(mMyTextWatcher);
}
private TextWatcher mMyTextWatcher = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//take user input here and do something with it, like your translations
}
#Override
public void afterTextChanged(Editable s) {
}
};
Now to your question regarding lag, it shouldn't lag as long as all your intensive operations are executed in the background, off the main thread.

Calling notifyDataSetChanged in my onFocusChangedListener causes focus to freak out in my ListView

I have a ListView which has multiple EditTexts per item. When I change an EditText on one item, I'd like it to affect the text on the next item. I'm using an onFocusChanged listener and I can successfully update the underlying data, but My actual focus is lost (and my cursor ends up in weird places). Please review my code and offer any insight. I've been banging my head about this for a while.
Note:
I am not recycling items using a holder, as this was giving me odd behavior and my performance is not suffering. Every time I've tried re-enabling the recycling, things get messier.
I have overriden hasStableIds to return true, but it doesn't seem to make any difference.
Assigning the Listener:
MyFocusChangeListener myFocusListener = new MyFocusChangeListener(myItem, position);
holder.et_min.setOnFocusChangeListener(myFocusListener);
Defining the Listener:
private class MyFocusChangeListener implements View.OnFocusChangeListener{
private EditText et;
private EditText curView;
private ScaleItem item;
private Integer pos;
public MyFocusChangeListener(ScaleItem item, Integer pos){
this.item = item;
this.pos = pos;
}
#Override
public void onFocusChange(View v, boolean hasFocus){
if(!hasFocus){
et = (EditText) v;
System.out.println("EditText lost focus on row: " + et.getText().toString() + " et id: " + et.getId());
if(pos < data.size()){
data.get(pos + 1).setMax(Double.valueOf(et.getText().toString()));
notifyDataSetChanged();
System.out.println("Updated dataset and called notifyDataSetChanged()");
}
} else {
et = (EditText) v;
if(et != null)
System.out.println("EditText just RECEIVED focus on row : " + et.getText().toString() + " et id: " + et.getId());
}
}
}
This is the console output I get, if I enter the activity, click field A, and then click field B.
Notice:
Each EditText (regardless of row) has the same ID (I think this is expected)
The only change I'm making is to the underlying data. In fact, I have the same issue if I change nothing but call notifyDataSetChanged.
The target field loses focus, I've no idea why.
TL;DR - Calling notifyDataSetChanged() in my onFocusChangedListener causes focus to freak out in my ListView.
See? The cursor is drunk.
If you focus a EditText in ListView get position value, after updating ListView redrawn and automatically it will select last position.
Step 1:
if (_Curserposition == position) {
holder.textViewStake.setFocusableInTouchMode(true);
//holder.textViewStake.clearFocus();
holder.textViewStake.requestFocus();
holder.textViewStake.setSelection(holder.textViewStake.getText().toString().length());
}
Step 2:
holder.textViewStake.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
_Curserposition = position;
Log.d(">>>", "setOnFocusChangeListener" + _Curserposition);
/*
//showVirtualKeyboard(con_text, v);
// holder.textViewStake.requestFocus();
InputMethodManager imm = (InputMethodManager) activityContext.getSystemService(Context.INPUT_METHOD_SERVICE);
if (hasFocus) {
imm.showSoftInput(holder.textViewStake, InputMethodManager.SHOW_FORCED);
} else {
imm.hideSoftInputFromWindow(holder.textViewStake.getWindowToken(), 0);
}*/
}
});
Step 3:
holder.textViewStake.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
betlist_view.setFocusable(false);
if (s.length() > 0) {
try {
if (Integer.parseInt(holder.textViewStake.getText().toString()) > 0) {
int _Stackamt = Integer.parseInt(holder.textViewStake.getText().toString());
int _picknumber = arrayDailyGameDrawList.get(position).getID();
//Log.d(">>>", "_picknumber" + position + "-" + arrayDailyGameDrawList.get(position).getBetNumberID() + "-" + Common.DrawId + "-" + _Stackamt + "-" + arrayDailyGameDrawList.get(position).getBetNumberID());
AddUpdateDailyGameNumberIntoList(
position,
2,
arrayDailyGameDrawList.get(position).getBetNumberID(),
Common.DrawId,
_Stackamt,
arrayDailyGameDrawList.get(position).getBetNumberID()
);
/* new Handler().postDelayed(new Runnable() {
#Override
public void run() {
}
}, 3000);*/
}
} catch (Exception e) {
}
} else {
holder.textViewStake.setText("0");
}
}
#Override
public void afterTextChanged(Editable s) {
}
});

Getting user input from dynamically created views

I've this problem of not being able to get the user input from the second inflated view.
I've upload an picture to this site http://postimage.org/image/b4syhdzrr/
as I'm still not allowed to post images directly on SO.
As you can see, the TextView only displays the top two EditText inputs + calculations, the third input however was not taken into consideration.(The first EditText for numbers is not inflated)
As I'm not sure how many EditText the end user would need.
How should I go about getting user inputs from all of the EditText ?
Here's what I had tried, setting up a SharePreferences to store the user input inside a TextWatcher, inside a OnClickListener, but with this code, the OnClickListener for the Plus button crashes the app even if the TextWatcher is empty.
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
// TODO Auto-generated method stub
int position = spinner.getSelectedItemPosition();
switch (position) {
case 0:
ll = (LinearLayout) findViewById(R.id.llSetView);
ll.removeAllViews();
View person1 = View.inflate(BillCalculator1.this,R.layout.person1, null);
ll.addView(person1);
btP1Add = (Button) ll.findViewById(R.id.buttonP1Add);
btP1Gst = (Button) ll.findViewById(R.id.buttonP1GST);
btP1Add.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
llNewRow = (LinearLayout) findViewById(R.id.llP1AddNewRow);
etNewRow = (EditText) findViewById(R.id.editTextNewRow);
View newRow = View.inflate(BillCalculator1.this,R.layout.newrow, null);
llNewRow.addView(newRow);
TextWatcher input = new TextWatcher() {
public void afterTextChanged(Editable s) {
}
//SharedPreferences here
public void beforeTextChanged(CharSequence s,
int start, int count, int after) {
}
public void onTextChanged(CharSequence s,
int start, int before, int count) {
}
};
}
});
The XML for the inflated view
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:id="#+id/editTextNewRow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="numberDecimal"
android:hint="Enter new amount">
<requestFocus />
</EditText>
Very new to programming and Android, do let me know if there's any additional information needed, Thank you very much.
I would try another approach to what you're trying to do. I would add a special TextWatcher to the inflated EditText and store the user entered values in an ArrayList. First of all you'll need two extra fields in your class:
private ArrayList<String> mData = new ArrayList<String>(); // this will store the entered values
private static int counter = 0; // to identify the rows
Make a class that implements the TextWatcher interface like this:
public class InputWatcher implements TextWatcher {
private int mRowNumber;
public InputWatcher(int rowNumber) {
mRowNumber = rowNumber;
}
#Override
public void afterTextChanged(Editable s) {
// here you'll add the text as the user enters it in the correct position in the
mData.set(mRowNumber, s.toString());
}
}
Then:
int position = spinner.getSelectedItemPosition();
switch (position) {
case 0:
mData.clear();
counter = 0;
ll = (LinearLayout) findViewById(R.id.llSetView);
ll.removeAllViews();
// I sure hope that you have the Buttons with the id button1Add and buttonP1GST in the layout that you inflate
// otherwise the code will throw a NullPointerException when you use them below
View person1 = View.inflate(BillCalculator1.this,R.layout.person1, null);
ll.addView(person1);
btP1Add = (Button) ll.findViewById(R.id.buttonP1Add);
btP1Gst = (Button) ll.findViewById(R.id.buttonP1GST);
btP1Add.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// add an entry in the data holder for this row
mData.add("");
View newRow = View.inflate(BillCalculator1.this,
R.layout.newrow, null);
EditText justAdded = (EditText) newRow
.findViewById(R.id.editTextNewRow);
justAdded.addTextChangedListener(new InputWatcher(counter));
ll.addView(newRow);
counter++;
}
});
When it's time to calculate the total, in a Button's OnClickListener, just do:
#Override
public void onClick(View v) {
int storedSize = mData.size();
int sum = 0;
for (int i = 0; i < storedSize; i++) {
sum += Integer.parseInt(mData.get(i).equals("") ? "0"
: mData.get(i));
}
Toast.makeText(getApplicationContext(), "Total" + sum, Toast.LENGTH_SHORT).show();
}
From your picture I didn't understand if you already start with one EditText in the layout(the one to the left of the + Button). If this is the case then you would have to manually set the InputWatcher to it and move the counter incrementation before adding the InputWatcher where you add the rows.

Categories

Resources