In Cart Activity, i am allowing user to Edit Quantity of an item, and also getting changes in Total amount as user does change in Quantity, but here i am facing a small problem, whenever i do click on back button, it will reset my quantity, why?
please see below screen shot:
![enter image description here][1]
For an example, in above screen i have edited Quantity for my product Veggie from 1 to 15 and also getting change in Total, but the problem is once i do click on back button, then i will get again value for Quantity 1 not 15, which i have entered earlier
Please tell me how can i control on this ?
CartAdapter.java:
if(cost.getText().length() > 0)
{
try
{
itemamount = Double.parseDouble(cost.getText().toString());
Log.d("ProductInformationActivity", "ItemAmount :: " + itemamount);
}
catch(NumberFormatException e)
{
itemamount=0.00;
Log.d("ProductInformationActivity", "NumberFormatException :: " + e);
}
}
qty.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before,
int count) {
if (!qty.getText().toString().equals("")
|| !qty.getText().toString().equals("")) {
// accept quantity by user
itemquantity = Integer.parseInt(qty.getText()
.toString());
total.setText(new DecimalFormat("##.#").format(itemamount*itemquantity));
}
}
#Override
public void afterTextChanged(Editable s) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
});
return vi;
}
}
Why don't you save your values and populate them in your onCreate()? You can use any of three mechanisms to get what you want.
Shared Preferences
SQLite DB
Application
using SQLite DB looks like the best option considering the functionality you require...
If you are already storing the value and just want to control how the back button works you could use this in your cart activity:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
//Your code
return true; // so the super method doesn't get called
}
return super.onKeyDown(keyCode, event);
}
Related
In the first place, Thank everyone for coming in and sorry for my poor English, So I describe this situation directly,
I develop with SONY, When I clicked the clear button in EditText, it's working normally!, even I use others phone, like HTC, Oppo,mi.. All's well!
After that I tried to install it in Acer, the clear button still working,
BUT!!!!!
After I clicked the clear button, Next use keyboard again, the data of my first input still here.
The data of my first input.
So, "MyFirstData" will still appear when I input again like
Second-time input situation
I was really confused because I have no idea how to fix it.
So what can I do, clear keyboard data? How?
many thanks!!!!
Code here:
binding.searchView is my editext
binding.searchView.addTextChangedListener(new TextWatcherAdapter());
binding.searchView.setOnEditorActionListener(getSearchEditListener());
channelDialogHelper = new ChannelDialogHelper(this);
}
private TextView.OnEditorActionListener getSearchEditListener() {
return new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
messageResultAdapter.clearAdapter();
shareFileResultAdapter.clearAdapter();
keyword = MessageFactory.getInstance().parseSourceData(v.getText().toString());
if (StringUtil.isEmpty(keyword)) {
return false;
}
hasMessageResult = false;
hasFileResult = false;
if (binding.searchMessageButton.isSelected()) {
searchMessageListener(binding.searchMessageButton);
} else if (binding.searchFileButton.isSelected()) {
searchFileListener(binding.searchFileButton);
}
return true;
}
return false;
}
};
}
TextWatcherAdapter:
public class TextWatcherAdapter implements TextWatcher {
public TextWatcherAdapter() {
}
public void beforeTextChanged(CharSequence var1, int var2, int var3, int var4) {
}
public void onTextChanged(CharSequence var1, int var2, int var3, int var4) {
}
public void afterTextChanged(Editable var1) {
}
}
One possible solution is to remove the exact word(s) using ContentResolver.delete(). Example:
private int deleteWord(String word) {
if (TextUtils.isEmpty(word)) {
return -1;
}
return getContentResolver().delete(UserDictionary.Words.CONTENT_URI,
UserDictionary.Words.WORD + "=?", new String[] { word });
}
And of course, need
<uses-permission android:name="android.permission.WRITE_USER_DICTIONARY" />
defined in the manifest.
Hope this helps.
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.
been looking for a previous answer for this but can't seem to find an android version of it...
I'm making a login page for an app, and I've got 3 input fields (First name, last name, email) and a text watcher to tell the user if there's an error in their input ((e.g. nothing there/too long/not a valid email). I'm trying to make the log in button disabled until no errors are showing, but I can't seem to sort it. I'm very new to android, just been working from scraps of tutorials here and there really... I've tried setting a boolean for each input value that sets to false when the input is bad/true when it's acceptable, and something to check if all 3 are true or not to enable/disable the button but that doesn't seem to work...
In the emulator, the button doesn't disable at all and I've got warnings that the booleans I made are always true even though I've given instances to make them false, and defined them as false at the start...
Here's my java class at the moment:
public class Login extends Activity implements OnClickListener, TextWatcher {
EditText firstName;
EditText lastName;
EditText eMail;
ImageButton Begin;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
initialiseUI();
}
private void initialiseUI() {
eMail = (EditText)findViewById(R.id.edit_email);
eMail.addTextChangedListener(this);
firstName= (EditText)findViewById(R.id.edit_firstname);
firstName.addTextChangedListener(this);
lastName= (EditText)findViewById(R.id.edit_surname);
lastName.addTextChangedListener(this);
Begin= (ImageButton) findViewById(R.id.Beginbutton);
Begin.setOnClickListener(this);
}
boolean name=false;
boolean surname=false;
boolean email=false;
boolean isEmailValid(CharSequence eMail) {
return android.util.Patterns.EMAIL_ADDRESS.matcher(eMail)
.matches();
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {}
public void afterTextChanged(Editable s) {
Is_Valid_Email(eMail);
Is_Valid_Name(firstName);
Is_Valid_Surname(lastName);
Is_Login_Valid();
}
public void Is_Valid_Name(EditText firstName) {
if (firstName.getText().toString().trim().isEmpty()){
firstName.setError("Enter Name");
name=false;}
else if (firstName.getText().toString().length()>20){
firstName.setError("Name too long!");
name=false;}
else if (firstName.getText().toString().length()>1){
firstName.setError(null);
name=true;}
}
public void Is_Valid_Surname(EditText lastName){
if (lastName.getText().toString().trim().equalsIgnoreCase("")){
lastName.setError("Enter Surname");
surname=false;}
else if (lastName.getText().toString().length()>20){
lastName.setError("Surname too long!");
surname=false;}
else if (lastName.getText().toString().length()>1){
lastName.setError(null);
surname=true;}
}
public void Is_Valid_Email(EditText eMail) {
if (eMail.getText().toString().trim().equalsIgnoreCase("")) {
eMail.setError("Enter e-mail");
email=false;}
else if (!isEmailValid(eMail.getText().toString())) {
eMail.setError("Invalid Email Address");
email=false;}
else if (isEmailValid(eMail.getText().toString())) {
email=true;}
}
public void Is_Login_Valid() {
if (name=true){
if (surname=true){
if (email=true){
Begin.setEnabled(true);
}
else if (email=false){
Begin.setEnabled(false);
}
}
else if(surname=false){
Begin.setEnabled(false);
}
}
else if (name=false){
Begin.setEnabled(false);
}
}
/** Called when the user clicks the Login button */
public void onClick(View v) {
Intent intent = new Intent(Login.this, question_1.class);
startActivity(intent);
}
}
Please check setClickable(false)
http://developer.android.com/reference/android/view/View.html#setClickable%28boolean%29
I wouldn't use variables for check status. Have you tried what happens when a screen rotation? This might be chaos.
I recommend you to check your status everytime the text changes:
public void Is_Login_Valid() {
if(Is_Valid_Name(firstName) && Is_Valid_Surname(lastName) && Is_Valid_Email(eMail)){
Begin.setEnabled(true);
}else{
Begin.setEnabled(false);
}
I removed the name, surname, email booleans & Is_Login_Valid terms entirely and copied the acceptable conditions from Is_Valid_Name, Is_Valid_Surname and Is_Valid_Email into an if statement within the button's onClick term as below, and it seems to work fine now:
public void onClick(View v) {
if ((firstName.getText().toString().length() >= 1)
&& (firstName.getText().toString().length() < 20)
&& (lastName.getText().toString().length() >= 1)
&& (lastName.getText().toString().length() < 20)
&& (isEmailValid(eMail.getText().toString())))
{Intent intent = new Intent(Login.this, question_1.class);
startActivity(intent);}
else{ //TODO Login failed animation or popup
}
}
I have is an android class. I get some data from get extra which are displayed fine. All of the data is strings. Here is my class:
package adapter;
public class AddToCart extends Activity {
EditText quantity=null;
TextView total=null;
TextView name=null;
TextView price=null;
TextView ava=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.info);
Intent intent = getIntent();
final String itemprice = intent.getStringExtra("price");
String itemname = intent.getStringExtra("item");
final String itemava = intent.getStringExtra("ava");
int imagehandler = intent.getIntExtra("image", 0);
Log.e("image handler",imagehandler+"");
name = (TextView)findViewById(R.id.textView2);
price = (TextView)findViewById(R.id.textView4);
total = (TextView)findViewById(R.id.textView7);
ava = (TextView)findViewById(R.id.textView9);
quantity = (EditText)findViewById(R.id.editText1);
Button addtocart = (Button)findViewById(R.id.button1);
ImageView imageview=(ImageView)findViewById(R.id.imageView1);
name.setText(itemname);
price.setText(itemprice);
ava.setText(itemava);
imageview.setImageResource(imagehandler);
addtocart.setOnClickListener(new OnClickListener() {
int currentava = Integer.parseInt(itemava);
#Override
public void onClick(View v) {
try{
String checked = quantity.getText().toString();
if(checked==null) {
Toast.makeText(AddToCart.this,"please enter quantity for your item", Toast.LENGTH_LONG).show();
}
else {
int x=0;
double y=0.0;
x = Integer.parseInt(quantity.getText().toString());
y = Double.parseDouble(itemprice);
Log.e("x",x+"");
Log.e("y",y+"");
double totalprice=x*y;
total.setText(totalprice+"");
Toast.makeText(AddToCart.this,"your item added succesfully !", Toast.LENGTH_LONG).show();
}
}//view
catch(Exception e){
e.printStackTrace();
}
}
});
}
}
As you can see that quantity is edit text and when some number inserted into it multiply it by price value and show the total price in text view which works just fine when i click the button, but what I really need to do is to handle this functionality with two if statements. First if the edit text for quantity was empty and the user click the button I want a toast to be displayed to says : "please enter a value for quantity" and the other statement that if quantity larger than available to refuse the value and also toast : "please enter value less than available" It doesn't work as I have an invalid integer value exception. Please what is wrong with my code and how can i handle the previous issues?
Declare "itemava" globally and try again
Looks to me where you use ,
if(checked==null){
Toast.makeText(AddToCart.this,"please enter quantity for your item", Toast.LENGTH_LONG).show();
}
that there are 2 alternatives to this.
1.
Probably the easiest
if(checked==null || quantity.isEmpty()){
Toast.makeText(AddToCart.this,"please enter quantity for your item", Toast.LENGTH_LONG).show();
}
The addition is the || quantitiy.isEmpty()
I had tons of issues trying to solve for cases when the string was empty and this is the best way and also uses built in functions that are very easy to use.
2.
Not quite as easy but probably the better bet
Rather than checking to see if the string itself is null, it would be best to check if the editText has been changed at all, and then if it has been changed, make sure that it was changed to a non-empty string, like in 1. To do this add a textChangedListener like so:
quantity.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
//set a textChangedFlag to true
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
});
This will require a boolean flag that should always be initialized to false. Then after setting the flag to true in the onTextChanged method, you should still double check the string, just to be safe (this may be overkill, but I tend to error on the side of caution) by using a similar method as in 1.
if(textChangedFlag && !(checked == NULL || quantity.isEmpty())){
//do your math here
}
else{
Toast.makeText(AddToCart.this,"please enter a valid quantity", Toast.LENGTH_LONG).show();
}
Text can still be empty... Try something like this:
import android.text.TextUtils;
String value = quantity.getText().toString();
if (TextUtils.isEmpty(value)) {
// enter a value toast
} else if (!TextUtils.isDigitsOnly(value)) {
// must be numeric toast (notice the exclamation mark in condition)
} else {
int valueInt = Integer.parseInt(value);
// ...
}
TextWatcher works fine until my activity is destroyed and before restoring from old saved bundle. But when I restore from saved bundle onTextChanged() is called for both of my EditTexts. This happens even if I don't restore their values (don't call setText()). Note that user is not interacting in any way.
Code :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.create_trip);
Log.d(TAG, "onCreate");
fromLocation = (EditText) findViewById(R.id.from_location);
toLocation = (EditText) findViewById(R.id.to_location);
// Set EditTexts listeners
setFromLocationEditTextListeres();
setToLocationEditTextListeres();
// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null) {
Log.d(TAG, "Restoring state from saved bundle");
...
} else {
Log.e(TAG, "Setting default values");
...
}
}
// Set listener for fromLocation EditText
private void setFromLocationEditTextListeres() {
fromLocation.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
Log.d(TAG, "fromLocation gained focus.");
}
}
});
fromLocation.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
Log.e(TAG, "Fromlocation after.");
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
if (fromLocation == null) {
Log.d(TAG, "fromLocation is null................");
}
if (count != before) {
editTextValueChanged(fromLocation);
}
}
});
fromLocation.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
// If user pressed enter
if (keyCode == KeyEvent.KEYCODE_ENTER) {
}
// If pressed other than enter key then let others handle the
// event
return false;
}
});
}
// Set listener for toLocation EditText
private void setToLocationEditTextListeres() {
toLocation.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
Log.d(TAG, "toLocation gained focus.");
}
}
});
toLocation.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
Log.e(TAG, "Tolocation after.");
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
if (count != before) {
editTextValueChanged(toLocation);
}
}
});
toLocation.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
// If user pressed enter
if (keyCode == KeyEvent.KEYCODE_ENTER) {
}
// If pressed other than enter key then let others handle the
// event
return false;
}
});
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
Log.e(TAG, "onSaveInstanceState called.");
// Save activity state
savedInstanceState.putCharSequence(FROM_LOCATION_TEXT,
fromLocation.getText());
savedInstanceState.putCharSequence(TO_LOCATION_TEXT,
toLocation.getText());
super.onSaveInstanceState(savedInstanceState);
}
After headache of few hours the reason of issue comes out to be my following code :
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
Log.e(TAG, "onSaveInstanceState called.");
// Save activity state
savedInstanceState.putCharSequence(FROM_LOCATION_TEXT,
fromLocation.getText());
savedInstanceState.putCharSequence(TO_LOCATION_TEXT,
toLocation.getText());
super.onSaveInstanceState(savedInstanceState);
}
What happens is android itself stores my EditText's state (if id attribute is specified in layout file) and when activity is restored using saved bundle it restores EditText's value by calling myEditText.setText(). This was triggering call to text changed listeners.
Solution is removing lines from above code which saves EditText's text. Do not save EditText or similar View's state explicitly. Let android do it for you.
The answer to this is that you first #Override the onTextChanged() in fromLocation.addTextChangedListener and then you #Override it once more inside of toLocation.addTextChangedListener. Then in the onCreate inside of if (savedInstanceState != null) { you have:
fromLocation.setText(savedInstanceState
.getCharSequence(FROM_LOCATION_TEXT));
toLocation.setText(savedInstanceState
.getCharSequence(TO_LOCATION_TEXT));
Which triggers both mentioned addTextChangedListeners.
EDIT (following the update of the question):
In the onCreate you call this, before any if statements:
// Set EditTexts listeners
setFromLocationEditTextListeres();
setToLocationEditTextListeres();
Then you have:
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
Log.e(TAG, "onSaveInstanceState called.");
// Save activity state
savedInstanceState.putCharSequence(FROM_LOCATION_TEXT,
fromLocation.getText());
savedInstanceState.putCharSequence(TO_LOCATION_TEXT,
toLocation.getText());
super.onSaveInstanceState(savedInstanceState);
}
So, you're restoring the text in the EditTexts from here above, then in the onCreate you set the listeners - thus setting the text on the EditTexts triggers the onTextChanged for bothe the EditTexts. Afterwards in the onCreate method you have:
if (savedInstanceState != null) {
Log.d(TAG, "Restoring state from saved bundle");
// Restore value of members from saved state
.../*Intentionnaly missed part*/
fromLocation.setText(savedInstanceState
.getCharSequence(FROM_LOCATION_TEXT)); <- Here you set the text again and trigger the `onTextChanged`
.../*Intentionnaly missed part*/
toLocation.setText(savedInstanceState
.getCharSequence(TO_LOCATION_TEXT)); <- Here you set the text again and trigger the `onTextChanged
} else {
Log.e(TAG, "Setting default values");
.../*Intentionnaly missed part*/
fromLocation.setText("Hello");<- Here you set the text again and trigger the `onTextChanged
}
I think that the described behaviour (e.g. "TextWatcher works fine until my activity is destroyed and before restoring from old saved bundle. But when I restore from saved bundle onTextChanged() is called for both of my EditTexts. This happens even if I don't restore their values (don't call setText()). Note that user is not interacting in any way.") happens only in the case of fromLocation (EditText) and not in both the cases (e.g. fromLocation and toLocation).
To finish this - you have also lots and lots of flags, which I don't even know what are they used for. To underline also the function editTextGainedFocus(EditText) which is not described here.
Cheers.