Getting user input from dynamically created views - android

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.

Related

I want to add the numbers in all the columns in dynamic added tableview

I am making a dynamic table with 5 columns... I want when I click the total button I get the sum of all the amounts previous of one particular column added to one text view... like in the picture I want to add the total amounts of each row to the below text view.... please help me.. I have tried many things but none of them is making a logic to me
et8 = new EditText(this);
et9 = new EditText(this);
et10 = new EditText(this);
et7.setText("");
et8.setText("");
et9.setText("");
et10.setText("");
et6.setBackgroundResource(R.drawable.edittext3);
et6.setGravity(Gravity.CENTER);
et6.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
et7.setBackgroundResource(R.drawable.edittext3);
et7.setGravity(Gravity.CENTER);
et7.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
et8.setBackgroundResource(R.drawable.edittext3);
et8.setGravity(Gravity.CENTER);
et8.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
et9.setBackgroundResource(R.drawable.edittext3);
et9.setGravity(Gravity.CENTER);
et9.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
et10.setBackgroundResource(R.drawable.edittext3);
et10.setGravity(Gravity.CENTER);
et10.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
tr1.addView(et6);
tr1.addView(et7);
tr1.addView(et8);
tr1.addView(et9);
tr1.addView(et10);
t1.addView(tr1);
try {
for (i = 0; i <= t1.getChildCount()-1; i++)
qty.setText(String.valueOf(i));
}
catch (Exception e)
{
Toast.makeText(this, "failed to add qty", Toast.LENGTH_SHORT).show();
}
et9.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) {
try {
int i, j;
int mul;
i = Integer.parseInt(et8.getText().toString());
j = Integer.parseInt(et9.getText().toString());
mul = i * j;
et10.setText("" + (Integer.toString(mul)));
}
catch (Exception e)
{
Toast.makeText(getApplicationContext(), "please calculate before adding row", Toast.LENGTH_SHORT).show();
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
final Snackbar snbr = Snackbar.make(view,"Row added",Snackbar.LENGTH_SHORT);
snbr.getView().setBackgroundColor(ContextCompat.getColor(view.getContext(),R.color.colorsnac1));
snbr.setActionTextColor(getResources().getColor(R.color.snactxt));
snbr.show();
snbr.setAction("Dismiss", new View.OnClickListener() {
#Override
public void onClick(View v) {
t1.removeView(tr1);
}
});
}
}
To start with, you should really be using a RecyclerView rather than trying to insert each row manually. Then, you could create a global ArrayList variable that stores the prices in the Price column. Each price EditText gets a TextChangedListener that updates its corresponding element in the ArrayList. The TextChangedListeners also iterate through the ArrayList, check if each value is a number, and if so add it to the price total and then display the newly computed total.
Their are many ways to do it
1) one way is while adding view to viewgroup set id or index
int tablerow = 1;
.....
tr1.setId(tablerow);
use this id and value of mul store in hashmap
use additional variable to store value of 'mul' in for loop
while removing view in use view's id that is index
you can decrease total amount by searching view's index in hashmap

check that all edittext is filled and display alert message

I have 9 edittext. Each edittext is in the form of a square. I look if all edittext has values, then an alert message is displayed without click of any button.
I tried with this code but it does not run.
Any help would be appreciated.
public int Summ(int x, int y, int z) {
int sum = 0;
sum = x + y + z;
return sum;
}
private void alertDialogLost()
{
int a= Integer.parseInt(et1.getText().toString());
int b = Integer.parseInt(et2.getText().toString());
int c = Integer.parseInt(et3.getText().toString());
int d = Integer.parseInt(et4.getText().toString());
int e = Integer.parseInt(et5.getText().toString());
int f = Integer.parseInt(et6.getText().toString());
int g = Integer.parseInt(et7.getText().toString());
int h = Integer.parseInt(et8.getText().toString());
int k = Integer.parseInt(et9.getText().toString());
if ((Summ(a,b,c)== Solution)&&(Summ(d,e,f)== Solution)&&(Summ(g,h,k)==Solution)&&
(Summ(a,d,g)==Solution)&&(Summ(b,e,h)== Solution)&&(Summ(c,f,k)==Solution)
&&(Summ(a,e,k)==Solution)&&(Summ(c,e,g)==Solution))
{
AlertDialog.Builder builder1 = new AlertDialog.Builder(MainActivity.this);
View view1 = LayoutInflater.from(MainActivity.this).inflate(R.layout.alertdiag, null);
TextView title = (TextView) view1.findViewById(R.id.title);
TextView message = (TextView) view1.findViewById(R.id.message);
ImageView icone = (ImageView) view1.findViewById(R.id.icone);
title.setText("Result");
icone.setImageResource(R.drawable.smilega);
message.setText("you have winner");
builder1.setPositiveButton("contenue", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent=new Intent(MainActivity.this,Main2Activity.class);
startActivity(intent);
finish();
}
});
builder1.setView(view1);
builder1.setCancelable(false);
AlertDialog alertDialog1 = builder1.create();
alertDialog1.show();
}
}
If you just want to show an AlertDialog the moment all nine EditText fields have values in them, using a TextWatcher would probably do the trick.
First, let's start with making things easier on ourselves. We'll add each EditText to an ArrayList, so we can iterate through them with a forEach loop:
List<EditText> editTextArrayList= new ArrayList<>();;
editTextArrayList.add(et1);
editTextArrayList.add(et2);
editTextArrayList.add(et3);
editTextArrayList.add(et4);
editTextArrayList.add(et5);
editTextArrayList.add(et6);
editTextArrayList.add(et7);
editTextArrayList.add(et8);
editTextArrayList.add(et9);
Then, let's set up a method to iterate through all nine EditText fields, checking if each one has a value. If any of them do not, the AlertDialog will not show:
private void checkAllEditTexts() {
boolean allFilled = true;
for (EditText editText : editTextArrayList) {
if (editText.getText().toString().isEmpty()) {
allFilled = false;
break;
}
}
if (allFilled) {
// show your AlertDialog
}
}
Then we set up our TextWatcher, which will call the checkAllEditTexts() method if any text is changed on the EditText fields we'll be assigning it to:
private TextWatcher textWatcher = 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) {
}
#Override
public void afterTextChanged(Editable s) {
checkAllEditTexts();
}
};
And finally, just below where we added the EditText fields to the ArrayList, we set up a forEach loop to add the TextWatcher:
List<EditText> editTextArrayList= new ArrayList<>();;
editTextArrayList.add(et1);
editTextArrayList.add(et2);
editTextArrayList.add(et3);
editTextArrayList.add(et4);
editTextArrayList.add(et5);
editTextArrayList.add(et6);
editTextArrayList.add(et7);
editTextArrayList.add(et8);
editTextArrayList.add(et9);
for (EditText editText : editTextArrayList) {
editText.addTextChangedListener(textWatcher);
}
...and that should display your AlertDialog as soon as all nine text fields have a value.

How to change the background of many images when user entered a text in EditText in Android

I have a program that has 10 images. I want to change the background of each image when the user enters valid text in editText. So basically if user enters valid text in the editText it will change the first image (image 1). If the user enters text again in editText it should change image 2 etc. until image 10.
I have tried to create a list of images and retrieve every element in the image.
I don't know if my logic is wrong
The images are stamp1, stamp2, stamp3, stamp4 ....stamp12
final String Entercode = codeNumber.getEditableText().toString().trim();
Toast.makeText(getApplicationContext(),Entercode,Toast.LENGTH_SHORT).show();
if (Entercode.equals("sweet")){
for (int i = 0; i < stampImageList.size(); i++) {
Object obj = stampImageList.get(i);
stampImageList = new ArrayList();
stampImageList.add(stamp1);
stampImageList.add(stamp2);
stampImageList.add(stamp3);
stampImageList.add(stamp4);
stampImageList.add(stamp5);
stampImageList.add(stamp6);
stampImageList.add(stamp7);
stampImageList.add(stamp8);
stampImageList.add(stamp9);
stampImageList.add(stamp10);
stampImageList.add(stamp11);
stampImageList.add(stamp12);
if (obj == stampImageList.get(2)) {
// stamp4.setBackgroundResource(R.drawable.earned_stamp);
stamp3.setBackgroundResource(R.drawable.earned_stamp);
AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());
builder.setIcon(R.drawable.logo);
builder.setMessage("Stamp Earned");
} else if (obj == stampImageList.get(3)) {
stamp5.setBackgroundResource(R.drawable.earned_stamp);
AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());
builder.setIcon(R.drawable.logo);
builder.setMessage("Stamp Earned");
}
}
} else{
AlertDialog.Builder alert = new AlertDialog.Builder(getApplicationContext());
alert.setIcon(R.drawable.logo);
alert.setTitle("Validation results");
alert.setMessage("validation failed");
}
You should use TextWatcher to EditText.In afterchange method you compare with values.
EditText et = (EditText)findViewById(R.id.editText);
Log.e("TextWatcherTest", "Set text xyz");
et.setText("xyz");
et.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) { }
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
#Override
public void afterTextChanged(Editable s) {
Log.e("TextWatcherTest", "afterTextChanged:\t" +s.toString());//Compare here with stamp1 or like that
}
});
#steve, here I have prepared a code for 10 Drawable Images in your project.
public class Pictures_Activity_stack extends AppCompatActivity {
private String TAG= "Pictures_Activity---";
private ImageView picture;
private EditText text;
private Button validate;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pictures_stack);
picture = (ImageView)findViewById(R.id.picture); //imageview where your picture changes
text = (EditText) findViewById(R.id.text);//edittext where you input text
validate = (Button) findViewById(R.id.button);//button to validate the text and change picture accordingly
// array to store your drawable images
final int pictures[] = {
R.drawable.firstimage,
R.drawable.secondimage,
R.drawable.p3,
R.drawable.p4,
R.drawable.p5,
R.drawable.p6,
R.drawable.p7,
R.drawable.p8,
R.drawable.p9,
R.drawable.p10
};
// click the button to set the image
validate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String input = text.getText().toString(); //input from edittext
if (input.equals("first")) {
picture.setImageResource(pictures[0]); //set first image in array if input=first
Toast.makeText(getBaseContext(),input,Toast.LENGTH_SHORT).show();
}
else if (input.equals("second")) {
picture.setImageResource(pictures[1]);//set first image in array if input=secind
Toast.makeText(getBaseContext(),input,Toast.LENGTH_SHORT).show();
}
// else if (input.equals("third")) {
// // and so on for other string values...
// .................................
// }
else
{
// if your input does not matches any string do this
Toast.makeText(getBaseContext(),"NO MATCHED STRING",Toast.LENGTH_SHORT).show();
}
}
});
}
}
The above code set images according to input in edit Text, when button is clicked.

android How to enable or disable a dynamically created switch when data is entered into a edit text field

I create a table with a switch and a edit text fields. What I want to happen is to set the switch to enable when I entry a certain text in the edit text field that is on the same tablerow So How to I set the switch in says row 8 to enable if I enter text in edit text row 8.
for (int i = 0; i< dbarray_id.size(); i++ )
{
CODE IS HERE TO CREATE A TABLEROW
//Now add a switch to the row
Switch switch1 = new Switch(getActivity());
switch1.setId(i);
switch1.setTag(i);
switch1.setSwitchMinWidth(50);
switch1.setEnabled(false)
//Add a edittext field to the row
final EditText txtaccesscode = new EditText(getActivity());
txtaccesscode.setId(i);
txtaccesscode.setTag(i);
txtaccesscode.setHint("CODE?");
txtaccesscode.setInputType(TYPE_TEXT_FLAG_NO_SUGGESTIONS);
txtaccesscode.addTextChangedListener(new TextWatcher()
{
#Override
public void beforeTextChanged(
....etc... for after change ...
repeat for the number of rows in the database.
So when I enter text into any row the corresponding switch is enabled.
Thanks
Encapsulate both EditText and Swith references in a class, then when textWatcher fires both references will be the expected.
public static class SwitchToggleListener {
public SwitchToggleListener(final Switch switchView, final EditText editText) {
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) {
//Do nothing
}
#Override
public void onTextChanged(final CharSequence s, final int start, final int before, final int count) {
//Your own condition here
switchView.setEnabled(s.toString().equals("ok"));
}
#Override
public void afterTextChanged(final Editable s) {
//Do nothing
}
});
}
}
Then in your loop do this:
new SwitchToggleListener(switch1, editText1);
new SwitchToggleListener(switch2, editText2);
new SwitchToggleListener(switch3, editText3);
If you have too many rows maybe this is inneficient, there are other ways to do this, let me know if that is the case.
The switch need to be final or a field.
final Switch switch = new Switch(getActivity());
Then you can access it on your beforeTextChanged listener, in there you change like always.
txtaccesscode.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(){
switch.setEnable(true);
}
}
);
After the loop reaching the end you can't access the variable anymore but it still exist. And on the next iteration of the loop the switch you create even having the same name is a different switch, because it's a new scope.

can't get integer number from EditText

Hello I am very new in android
I am trying to get integer value from an EditText, But When I am parsing string to Integer I got NumberFormatException.
Please help me to come out of this error.
thanks in advance.
Program is:
int day,month,year;
EditText expense,ammount;
String[] exp=new String[10];
int[] amt=new int[10];
int count=0;
/** Called when the activity is first created. */
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final Calendar cal=Calendar.getInstance();
day=cal.get(Calendar.DAY_OF_MONTH);
month=cal.get(Calendar.MONTH)+1;
year=cal.get(Calendar.YEAR);
final TextView txtdate=(TextView)findViewById(R.id.txtdate);
expense=(EditText)findViewById(R.id.exp);
ammount=(EditText)findViewById(R.id.amnt);
final Button add=(Button)findViewById(R.id.btnadd);
final Button cancel=(Button)findViewById(R.id.btncancel);
final Button done=(Button)findViewById(R.id.btndone);
txtdate.setText(day+"/"+month+"/"+year);
add.setOnClickListener(new OnClickListener() {
public void onClick(final View v) {
getval();
}
});
cancel.setOnClickListener(new OnClickListener() {
public void onClick(final View v) {
clean();
}
});
done.setOnClickListener(new OnClickListener() {
public void onClick(final View v) {
total();
getval();
clean();
final TextView tv=(TextView)findViewById(R.id.textView1);
tv.setText(Integer.toString(total()));
}
private int total() {
int total = 0;
// TODO Auto-generated method stub
for(int i=0;i<=count;i++)
{
total+=amt[i];
}
return total;
}
});
}
protected void clean() {
// TODO Auto-generated method stub
expense.setText(" ");
ammount.setText(" ");
}
protected void getval() {
// TODO Auto-generated method stub
final Editable e2=expense.getText();
final Editable e1=ammount.getText();
final int i=Integer.parseInt(e1.toString());
amt[count]=i;
exp[count]=e2.toString();
System.out.println(amt[count]);
System.out.println(exp[count]);
count++;
}
}
Exception is:
java.lang.NumberFormatException: unable to parse ' 600' as integer
Remove any leading or trailing spaces from the number first:
int inputNumber = Integer.parseInt(editText.getText().toString().trim());
Alternatively, you can remove all non-numeric characters from the string using regular expressions:
String cleanInput = editText.getText().toString().replaceAll("[^\\d]", "");
int inputNumber = Integer.parseInt(cleanInput);
Though if non-numeric input characters is a problem you'd probably want to restrict the EditText to numeric only. See this question. It says to add the following attribute to the EditText:
android:inputType="number"
You have a space in your integer.
Add the following attribute to your EditText in your xml to only allow entering integers:
android:inputType="number"
Try this..
final int i=Integer.parseInt(e1.toString().trim());
bacause there is a space before that number see ' 600' that's why that error..
Hope this will help..
use this code
final int f = -1; // or other invalid value
if (edittext.getText().toString().length() > 0)
f = Integer.parseInt(edittext.getText().toString());

Categories

Resources