I have an EditText and when I set it to Empty and Click on my Button, my App crashes.
When I view it in Android Monitor it points to the line:
final int addTm = Integer.parseInt(Teaching);
Here is my code:
LinearLayout
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="2dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:text="" />
<EditText
android:id="#+id/tM"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="24dp"
android:layout_marginRight="50dp"
android:ems="1"
android:inputType="number"
android:maxLength="1"
android:text="0" />
<Button
android:id="#+id/submitBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Submit" />
</LinearLayout>
And my Java Code:
Submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String Teaching = Tm.getText().toString();
final int addTm = Integer.parseInt(Teaching);
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("sub").child("TM");
myRef.runTransaction(new Transaction.Handler() {
#Override
public Transaction.Result doTransaction(MutableData mutableData) {
Integer currentValue = mutableData.getValue(Integer.class);
if (currentValue == null) {
mutableData.setValue(0);
} else {
mutableData.setValue(currentValue + addTm);
}
return Transaction.success(mutableData);
}
#Override
public void onComplete(DatabaseError databaseError, boolean committed, DataSnapshot dataSnapshot) {
System.out.println("Transaction completed");
}
});
}
});
The other answers are good, but I'd recommend wrapping with a try/catch for the NumberFormatException. I know you have the input set to accept numbers only, but always better safe than sorry.
Lowercase the String variable Teaching. In Java we only upper case Type names. (classes, interfaces, etc.) Notice how StackOverflow is highlighting the variable Teaching blue, a bit disorienting no?
Do this for your member fields as well Tm and Submit. They should be written tm and submit. Also, Tm is not a very descriptive name for a variable either. Imagine another programmer coming in and looking at your code, and wondering what a tm is. What is the context of this tm, where does it come from... what does it do? Is it a Teenage Mutant?
Regardless when using Integer.parseInt wrap it in a try/catch:
#Override
public void onClick(View view){
final int addTm;
try {
String teaching = Tm.getText().toString();
addTm = Integer.parseInt(teaching);
} catch (NumberFormatException e) {
addTm = 0;
}
// ...
}
Why should you do this? What if I enter a decimal number into your number input?
Using your accepted answer you will still crash. Integer.parseInt does not parse decimal numbers.
Or how about, if I switch the locale of the device and enter a number with odd characters that Integer.parseInt won't expect.
Gotta catch that exception to be full proof.
When executing Integer.parseInt() on an empty string it throws an NumberFormatException.
First, check the value of Teaching, and verify it's not empty string, or - try/catch for NumberFormatException, and set the value you want for Teaching in that case.
Related
I have a problem with counting the number of items in ListView.
I'm pushing values into a folder in the firebase database. When I pull them on a separate activity, I get a list of the values I pushed .
The problem is I want to know how many items the list has. I tried to use listView.getCount() and also with arrayList.size() and both show zero, even though in the list itself I do see the values. Why is it happening ?
Here is my Java code:
list = (ListView) findViewById(R.id.listViewId2);
check2 = findViewById(R.id.check3);
arrayList = new ArrayList<String>();
keyList = new ArrayList<String>();
arrayAdapter = new ArrayAdapter<String>(recommendations_weight.this ,android.R.layout.simple_list_item_1,arrayList);
list.setAdapter(arrayAdapter);
mDatabase = FirebaseDatabase.getInstance();
mAuth = FirebaseAuth.getInstance();
mDatabaseReference= FirebaseDatabase.getInstance().getReference().child("Recommendations").child("Blood").child("WBC").child("High").child("Weight").child("1");
mDatabaseReference.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
String value = dataSnapshot.getValue(String.class);
arrayList.add(value); // include the scan values
keyList.add(dataSnapshot.getKey()); //include the id of each tests
arrayAdapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
//check if we have item
if (list.getAdapter().getCount() != 0){
check2.setText("number");
}
and this is my xml -
<ListView
android:id="#+id/listViewId2"
android:layout_width="350dp"
android:layout_height="200dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:visibility="visible"
android:textAlignment="center" />
<Button
android:id="#+id/returnButton"
android:layout_width="200dp"
android:layout_height="50dp"
android:text="return to test page"
android:textAllCaps="false"
android:background="#60000000"
android:layout_marginTop="30dp"
android:textColor="#FFFFFF"
android:textSize="20dp"
android:layout_gravity="center_horizontal"
/>
<TextView
android:id="#+id/check3"
android:layout_marginTop="19dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="check"
/>
One simply cannot expect the ArrayAdapter to be already populated, when entering asynchronous execution and then instantly checking in a synchronous manner, if there are any items contained.
As your code currently works (or better said: won't work):
at first, it requests remote data (entering asynchronous execution).
then it instantly checks the item-count in the adapter (synchronous execution).
then the items are being added (asynchronous execution).
asynchronous execution finishes.
Asynchronous execution requires callbacks, else you won't know when it had finished.
Just add verbose logging, in order to understand what is going on and in which order.
You're getting 0 because you are checking list.getAdapter().getCount(). I think you want to check whatever list variable holds the data you pass in (I doubt it's adapter).
So maybe: list.getAdapter.getArrayList().getCount()?
public void onClick(View v) {
if (v == button1){
counter++;
textView2.setText(Integer.toString(counter));
textView2.setText(counter);
}
}
I have tried to create a program that counts the number of clicks on a button, but for some reason it is not displaying it. Here is my textview component.
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="180dp"
android:layout_alignParentTop="true"
android:layout_above="#+id/button1"
android:layout_toRightOf="#+id/textView1"
android:layout_centerHorizontal="true"
android:textColor="#000000"/>
I can't seem to find an attribute for display the number of clicks. Is this because it interprets it as an interger instead of a string?
textView2.setText(String.valueOf(counter));
This takes your Integer and converts it to its String value, and sets it to your TextView.
try casting your counter variable to string variable and then try assigning it to button text as:
public void onClick(View v) {
if (v == button1){
counter++;
String s=counter.toString();
textView2.setText(S);
}
}
what your code might be doing as of what you have posted you are trying to pass an integer which is creating problem here..
Need some help debugging my code. I am very new to the Android SDK and am working on learning it. From what I can glean from several posts on SO and other google search results... I formulated this code.
public class MainMenu extends Activity {
private int str = 8, dex = 8, inte = 8, luk = 8, stats = 20;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().setDisplayShowHomeEnabled(false);
getActionBar().setDisplayShowTitleEnabled(false);
setContentView(R.layout.activity_main_menu);
}
As you can see, I have created a few private variables my app is going to use to store data. In order to interact with these values, I will redraw the TextView each time they are modified. *Feel free to correct me here if this is not an ideal strategy.
public void strup(View view) {
if(stats > 0) {
TextView tv = (TextView)findViewById(R.id.textView4);
TextView st = (TextView)findViewById(R.id.textView18);
str++;
stats--;
tv.setText(str);
st.setText(stats);
} else {
Toast.makeText(this, "Out of stats!", Toast.LENGTH_SHORT).show();
}
I use a button with the following format.
Str [X] [+1]
Where Str [X] is TextView with X a dynamic value.
Also where [+1] is a button with an Onclick function preset by the XML file.
<TextView
android:id="#+id/textView9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Str [" />
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="8" />
<TextView
android:id="#+id/textView13"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="]" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="strup"
android:text="+1" />
Now for simplicity, I have altered the "android:text="" " lines to reflect their actual values instead of linking to #string/... I don't think this makes of much difference but I wanted to acknowledge it.
So my question is why does my Application crash when I click the "+1" button? All my app is trying to do is to redraw the TextView with a higher value (under str) and a lower value (under stats).
Thanks for any and all help!
You are passing integer value in settext. Either cast integer to string or you can try changing settext like this:
tv.setText(""+str);
st.setText(""+stats);
You tried to create this object:
TextView st = (TextView)findViewById(R.id.textView18);
where is textView18 in the xml?
u can caste using toString method like this:
tv.setText(str.toString());
st.setText(stats.toString());
Try this change the position of your setContentView(R.layout.activity_main_menu);
public class MainMenu extends Activity {
private int str = 8, dex = 8, inte = 8, luk = 8, stats = 20;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_menu);
getActionBar().setDisplayShowHomeEnabled(false);
getActionBar().setDisplayShowTitleEnabled(false);
}
I have an editText that fills half the screens width, and all of it's height. When I append text to it the text always starts halfway down the edit text height and when it gets to the edge to the editText it keeps writing, scrolling to the right. I want it to go to a new line, why isn't it? and why does it start half way down? At the moment the text on the left should be replicated on the right. AppendToEMulator writes to the terminal fine, but when i'm ssetting the text in the editText on the right there are no newlines from either the bytes received, probably as I convert it to a string and also none from when the end of the editText is reached, just keeps going right.
<jackpal.androidterm.emulatorview.EmulatorView
android:id="#+id/emulatorView"
android:layout_width="500dp"
android:layout_height="wrap_content"
android:layout_above="#+id/term_entry"
android:layout_below="#+id/deviceConnect"
android:layout_toRightOf="#+id/scrllyout"
android:focusable="true"
android:focusableInTouchMode="true" />
<EditText android:id="#+id/outputBox"
android:layout_toRightOf="#+id/emulatorView"
android:layout_alignParentRight="true"
android:layout_width="200dp"
android:layout_height="fill_parent"
android:background="#ffffff"
android:textColor="#FF043241"
android:inputType="text|textImeMultiLine" />
In Java:
public void onDataReceived(int id, byte[] data) {
dataReceived = new String(data);
dataReceivedByte = dataReceived.getBytes();
statusBool = true;
((MyBAIsWrapper) bis).renew(data);
runOnUiThread(new Runnable(){
#Override
public void run() {
mSession.appendToEmulator(dataReceivedByte, 0, dataReceivedByte.length);
}});
final String ReceivedText = mReceiveBox.getText().toString() + " "
+ new String(data);
runOnUiThread(new Runnable() {
public void run() {
mReceiveBox.setText(ReceivedText);
mReceiveBox.setSelection(ReceivedText.length());
}
});
viewHandler.post(updateView);
}
Answer was that setting an inputType disables wordwrap via:
android:singleLine="true"
Even if I specify
android:singleLine="false"
it was still getting overridden.
As I do not need to type in the editText I simply removed the input type.
Hi All I have followed the following example http://www.google.com/codesearch#search/&q=NumberFormattingTextWatcher&exact_package=android&type=cs
I have CurrencyTextWatcher as a seperate class. I need this as I will be applying to several pages.
I can't figure out why, but if I use setContentView(text) it will work as only 1 big text box, then I can't see the rest of my xml .
If I use setContentView(R.layout.main); my xml works properly except for the TextWatcher wont fire for my txta EditText box
Java
public class CalcTestActivity extends Activity {
private EditText txta;
private TextView txtb;
private TextView txtc;
private EditText text;
private double a = 0;
private double b = 0;
private double c = 0;
private Button buttonCalc;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initControls();
text = new EditText(this);
text.addTextChangedListener(new CurrencyTextWatcher());
//setContentView(text);
}
private String FormatValue(double value)
{
NumberFormat nf = NumberFormat.getInstance();
return "$ "+ nf.format(value);
}
private void initControls() {
txta = (EditText)findViewById(R.id.txta);
txtb = (TextView)findViewById(R.id.txtb);
txtc = (TextView)findViewById(R.id.txtc);
buttonCalc = (Button)findViewById(R.id.buttonCalc);
buttonCalc.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {calculate(); }
private void calculate() {
a=Double.parseDouble(txta.getText().toString());
b=Math.round(a*.88);
txtb.setText(FormatValue(b));
c=Math.round((a*.87)-(b*.28));
txtc.setText(FormatValue(c));
}
});
}
}
CurrencyTextWatcher Class
public class CurrencyTextWatcher implements TextWatcher {
boolean mEditing;
public CurrencyTextWatcher() {
mEditing = false;
}
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
if(!mEditing) {
mEditing = true;
String digits = s.toString().replaceAll("\\D", "");
NumberFormat nf = NumberFormat.getCurrencyInstance();
try{
String formatted = nf.format(Double.parseDouble(digits)/100);
s.replace(0, s.length(), formatted);
} catch (NumberFormatException nfe) {
s.clear();
}
mEditing = false;
}
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
}
}
XML
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Number1"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="#+id/txta"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:numeric="integer"/>
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Number2"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/txtb"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Your Answer is"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/txtc"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:hint="0" />
<Button
android:id="#+id/buttonCalc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Calculate" />
</LinearLayout>
I took your code. I observed that the code you have shared here is getting all views from xml.
In this case you are calling
text.addTextChangedListener(new CurrencyTextWatcher());
in your onCreate method, wherein text is done using java. You wont get a call back for your onTextChanged, beforeTextChanged or afterTextChanged because all your views are taken from xml. So please after your
initControls();
in onCreate() add below line
txta.addTextChangedListener(new CurrencyTextWatcher());
and comment
text.addTextChangedListener(new CurrencyTextWatcher());
that line is not needed. I have verified its working fine.
if works vote and accept the answer
what the code you have implemented in afterTextChanged implement the same for onTextChanged. It will fire and gives the call back.
Secondly, If there is problem in views check your layout and their params. if it is not proper it wont appear properly in the UI