Android - deleting characters on button press - android

Below is the method I've coded to input numbers for a calculator. The code is fully functional and is error-free.
I'm trying to figure out how I would write a separate method called backspace to remove one character at a time from the user input.
To give an example of how onClick1 works (just to make it crystal clear what I want to do), if I entered 2+4*6 (using buttons; their onClick action linked to onClick1), then textViewCalcHistExp1 would display the text 2+4*6, and arrayList would hold the following values: [2,+,4,*,6].
I want backspace to work so that if I clicked the button (linked with the backspace method), textViewCalcHistExp1's display would now be 2+4* and arrayList would now hold the following values: [2,+,4,*].
Here is the code:
ArrayList<String> arrayList = new ArrayList<String>();
String stringInput = "";
String stringInputWithOp = "";
public String prevCalc = "";
public void onClick1 (View view) {
TextView textViewCalcHistExp1 = (TextView) findViewById(R.id.textViewCalcHistExp1);
Button button = (Button) view;
stringInput = (String) button.getText().toString();
if (!stringInput.contains("+") && !stringInput.contains("-") && !stringInput.contains("×") && !stringInput.contains("÷")) {
stringInputWithOp = stringInputWithOp+stringInput;
if (arrayList.size()>0) {
arrayList.remove((arrayList.size()-1));
}
arrayList.add(stringInputWithOp);
}
else {
arrayList.add(stringInput);
arrayList.add(stringInput);
stringInputWithOp="";
}
//This version truncates array formatting i.e. entering "2+4*6" would display "2+4*6"
textViewCalcHistExp1.setText(textViewCalcHistExp1.getText().toString()+stringInput);
//This version leaves array formatting i.e. entering "2+4*6" would display [2,+,4,*,6] ;good for debugging
//textViewCalcHistExp1.setText(arrayList.toString());
}

You could do something like this:
private void backspace() {
if (!arrayList.isEmpty()) {
// removing the last item from the ArrayList
arrayList.remove(arrayList.size() - 1);
}
String string = textViewCalcHistExp1.getText().toString();
if (string.length() > 0) {
// removing the last character from the TextView
textViewCalcHistExp1.setText(string.substring(0, string.length() - 1));
}
}
You'd also need to make textViewCalcHistExp1 an instance variable (arrayList already is), by declaring it outside onClick1().

Related

How to make a search in scrollview and be able to get next indexOf?

I have a editText and a search button, Now it just shows the first results.
But I want to be able to press the search button again and then show the next indexOf. How can I do this ?
public void searchMethod(final String search) {
int i = mTextCurrentArticle.toLowerCase().indexOf(search.toLowerCase().trim());
if (i == -1) {
mEditTextSearch.setTextColor(Color.RED);
// String cap = search.substring(0, 1).toUpperCase() + search.substring(1);
//i = mTextCurrentArticle.indexOf(cap);
} else {
mEditTextSearch.setTextColor(Color.BLACK);
}
// int line = mTextViewCurrentArticle.getLayout().getLineForOffset(i);
Layout layout = mTextViewCurrentArticle.getLayout();
mScrollView.scrollTo(0, layout.getLineTop(layout.getLineForOffset(i)));
You can use the overloaded version of indexOf which takes a starting index for the search and pass the original index like this:
int i = mTextCurrentArticle.toLowerCase().indexOf(search.toLowerCase().trim());
int nextPosition = mTextCurrentArticle.toLowerCase().indexOf(search.toLowerCase().trim(), i+1);
EDIT:
If you need to cycle through subsequent positions then just make the index i a global variable and initialize it to -1
then inside your searchMethod use
i = mTextCurrentArticle.toLowerCase().indexOf(search.toLowerCase().trim(), i+1);
This will ensure that it returns the first position when called for the first time and then gives the next position when called subsequently

Two-way data-binding infinite loop

I have a list of items. In each item's row I have 2 EditTexts side-by-side. EditText-2 depends on EditText-1's value. This list is bound with data-binding values in HashMap<String, ItemValues>
For Example:
Total _____1000____
Item A __1__ __200__
Item B __1__ __200__
Item C __1__ __200__
Item D __2__ __400__
First EditText is the share and the second value is its value calculated based on total and share. So, in example if I change any 1 share, all the values will be changed. So, shown in example total no of shares are = 1+1+1+2 = 5. So amount per share = 1000/5 = 200 and is calculated and shown in next EditText.
I have bound this values with two-way data binding like this:
As, this is a double value, I have added 2 binding adapters for this like this:
#BindingAdapter("android:text")
public static void setShareValue(EditText editText, double share) {
if (share != 0) {
editText.setText(String.valueOf(share));
} else {
editText.setText("");
}
}
#InverseBindingAdapter(attribute = "android:text")
public static double getShareValue(EditText editText) {
String value = editText.getText().toString();
if (!value.isEmpty()) {
return Double.valueOf(value);
} else
return 0;
}
Now, to calculate new values, I need to re-calculate whole thing after any share value is changed. So, I added android:onTextChagned method to update Calculations. But it gets me an infinite loop.
<EditText
android:text="#={items[id].share}"
android:onTextChanged="handler.needToUpdateCalculations"
.... />
public void needToUpdateCalculations(CharSequence charSequence, int i, int i1, int i2) {
updateCalculations();
}
This gets an infinete loop because when data changes, it is rebound to the EditText, and each EditText has an onTextChanged attached it will fire again and it will get really large - infinite loop.
It also updates the value of itself, ended up loosing the cursor as well.
I have also tried several other methods like adding TextWatcher when on focus and removing when losses focus. But at least it will update it self and will loose the cursor or infinite loop.
Unable to figure this problem out. Thank you for looking into this problem.
EDIT:
I have tried with the below method. But, it doesn't allow me to enter . (period).
#BindingAdapter("android:text")
public static void setDoubleValue(EditText editText, double value) {
DecimalFormat decimalFormat = new DecimalFormat("0.##");
String newValue = decimalFormat.format(value);
String currentText = editText.getText().toString();
if (!currentText.equals(newValue)) {
editText.setText("");
editText.append(newValue);
}
}
The reason you stated is correct and it will make a infinite loop definitely. And there is a way to get out from the infinite loop of this problem, android official provided a way to do so (But it is not quite obvious.)(https://developer.android.com/topic/libraries/data-binding/index.html#custom_setters)
Binding adapter methods may optionally take the old values in their
handlers. A method taking old and new values should have all old
values for the attributes come first, followed by the new values:
#BindingAdapter("android:paddingLeft")
public static void setPaddingLeft(View view, int oldPadding, int newPadding) {
if (oldPadding != newPadding) {
view.setPadding(newPadding,
view.getPaddingTop(),
view.getPaddingRight(),
view.getPaddingBottom());
}
}
You can use the old value and new value comparison to make the setText function called conditionally.
#BindingAdapter("android:text")
public static void setShareValue(EditText editText, double oldShare,double newShare) {
if(oldShare != newShare)
{
if (newShare!= 0) {
editText.setText(String.valueOf(newShare));
} else {
editText.setText("");
}
}
}

swithcing to next textview

Ok im making app and it have 15 button's and 6 textview's.I want when I press first button to change value of first textview(value is "") to something (number one for example).But problem is when i press second button if first textview is already set to some value to set set second textview to second value.
If you need something else ask in comments (sorry for bad English)
here is what I was doing(this is under onclick)when i press second button
if(textview1.equals("1")){
textview2.setText("2");}
else if (textview1.equals("")){
textview1.setText("2");
}
It sounds like you wish to show last 6 buttons pressed.
Store all pressed buttons in a List (i.e. LinkedList) of size 6. Initially, it will be empty.
Then whenever any button is pressed do two things:
1) add it to the List and delete old elements if size exceeds six.
2) set button values from List.
Second step can be achieved like this:
// all TextViews should be in a list
private List<TextView> textViews;
// declare as field
private List<String> memoryQueue = new ArrayList<String>();
public void update() {
//set fields for the pressed buttons
for (int i=0; i<6 && i<memoryQueue.size(); i++) {
String text = memoryQueue.get(i);
textViews.get(i).setText(text);
}
// set empty fields
for (int i = memoryQueue.size(); i<6; i++) {
textViews.get(i).setText("");
}
}
This code snippet assumes that you store your TextViews in a List.
And Easiest way to keep track of last six button:
public void buttonPressed(Button button) {
//get text based on your button
String text = button.getText();
if (memoryQueue.contains(text)) {
return;
}
memoryQueue.add(text);
if (memoryQueue.size() > 6) {
memoryQueue.remove(0);
}
}
Since you're concerned with the text inside of your text view, you should be using the object's getText method:
if( textview1.getText().equals("1") ){ // Edited
textview2.setText("2");
} else if (textview1.getText().equals("")){ //Edited
textview1.setText("2");
}
At first, you have to get the String text from TextView using getText() method then you can compare that String with another String. Now, change your condition as follows...
if(textview1.getText().toString().equals("1")){
textview2.setText("2");}
else if (textview1.getText().toString().equals("")){
textview1.setText("2");
}

Android viewing an arraylist in text view

I have a program that has a text input and a button. When I type something into the input and press the button I want that String to be added to a String Arraylist and have that Arraylist displayed in a TextView. Right now I have a method:
public void addString(View view)
{
EditText editText = (EditText) findViewById(R.id.edit_choice);
String message = editText.getText().toString();
choices.add(message);
}
"edit-choices" is the name of the text input and "choices" is the name of the array list. First of all am I doing this correctly? Second, how to I get the text view to display the contents of "choices". Right now my TextView id is just textView1
Please keep in mind that it is not the best way to show list items in a TextView. You can do this using a ListView. Anyhow, see pseudo code below (didn't test that in Eclipse, however, it should show how it is basically going to work):
public class YourActivity extends Activity {
Vector<String> choices = new Vector<String>();
public void onCreate(Bundle ....) {
(Button) myButton = (Button) findViewById(R.id.button);
myButton.setOnClickListener(new OnClickListener() {
#Override
public boolean button.onClick() {
addString();
TextView textView = (TextView) findViewById(R.id.text_view);
String listRepresentation = "";
for (String choice : choices)
if ("".equals(listRepresentation))
listRepresentation = choice; else
listRepresentation = ", " +choice;
textView.setText(listRepresentation );
}
});
}
public void addString(View view)
{
EditText editText = (EditText) findViewById(R.id.edit_choice);
String message = editText.getText().toString();
choices.add(message);
}
}
So simply assign an OnClickListener to your button that does what you need.
The question is how you want the Text to be displayed...
Either like a list view or just as a normal text.
If you want to show the text as a normal text in the text view you can simply do something like this.
for(String msg : choices)
{
textView1.setText(textView1.getText()+msg);
}
If you want the choices to be displayed in list view you need to set an adapter to the list view using the choices that you have.
First of all am I doing this correctly?
If it works for you, sure. I would maybe cache the EditText so you don't have to "find" it every time you want to access it's content.
Your only "problem" here is, that a TextView has no method that accepts a List<String>. So, you'll need to make a single string out of your list of strings.
You can simply iterate over the list and con-cat them together:
StringBuilder b = new StringBuilder();
for (String s : choices){
b.append(s+"\n");
}
textview.setText(b.toString());
This will simply build one string from all the items in your list, adding line-breaks after every item.
You'll need to set your TextView's android:inputType-attribute to textMultiLine, so it will actually show you multiple lines.

Android Form Reset?

I have a simple calculator that has six EditText views where users will enter numbers to perform a simple math function. This app will satisfy a repetitive task wherein the users will enter the information, press the submit button and the answer is displayed in a separate textView.
I want to add a simple 'clear' button that will reset the form so the users can begin a new calculation and the EditText views will show their hints for user input once again.
Is there a 'reset' type function that will clear all of the form data and reload the hints or do I have to kill the app and start it again? If so, whats a good starting place for how to do this?
Thanks!
The most basic way to do this would be to simply reset your EditText views. If you have logic that drives the update of these fields, then resetting them to an empty String and requesting a "recalculation" to update the hints.
Something like this:
private void onClear()
{
EditText firstField = (EditText)this.findById(R.id.firstField);
EditText secondField = (EditText)this.findById(R.id.secondField);
//...etc...
if (firstField != null) firstField.setText("");
if (secondField != null) secondField.setText("");
updateHints();
}
private void updateHints()
{
//Logic for your "hints"
}
No, you have to implement it yourself. I suggest you create an int array with the IDs of all your EditTexts you want to reset (R.id.xyz). Then create a loop to .setText() to each of the EditTexts from the array, which you can call every time you want the fields to be cleared. Something like:
private void resetFields() {
EditText temp;
for (int i = 0; i < myEditTexts.length; i++) {
temp = (EditText) findViewById(textViews[i]);
temp.setText("");
}
}
My answer is just a better way but it still a kind of hard code. Anyone could find another way faster, please share.
protected void clearForm() {
Button btnClear = (Button) findViewById(R.id.btn_clear_text);
btnClear.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
EditText temp;
final int[] txtId = new int[] {
R.id.txt_s_free_word,
R.id.txt_s_property_name,
R.id.txt_s_ad_expense_from,
R.id.txt_s_ad_expense_to,
R.id.txt_s_station
};
for (int i = 0; i < txtId.length; i++) {
temp = (EditText) findViewById(txtId[i]);
temp.setText(null);
}
}
});
}

Categories

Resources