The first if statement works but once the value is set too true the second if statement should trigger but it does not see code below:
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
TextView Serial = (TextView) findViewById((R.id.LastSerialScanned));
TextView Location = (TextView) findViewById((R.id.LastLocationScanned));
if(hasSerial == false)// does trigger
{
if(Scan.getText().length() == 8)
{
Serial.setText(Scan.getText());
hasSerial = true;
Location.setText("");
Scan.setText("");
}
}
if(hasSerial == true)// does not trigger
{
Location.setText(Scan.getText());
hasSerial = false;
}
}
Any idea why? I am sure it is obvious but this is my first time working with android studio so I am just missing something. It also did not trigger when I had a simple else statement there
When the first block
if(hasSerial == false)// does trigger
{
if(Scan.getText().length() == 8)
{
Serial.setText(Scan.getText());
hasSerial = true;
Location.setText("");
Scan.setText("");
}
}
triggers it changes hasSerial to true and changes Location and Scan to empty strings.
Because hasSerial is now true, this following block:
if(hasSerial == true)// does not trigger
{
Location.setText(Scan.getText());
hasSerial = false;
}
is also executed (in the same call to onTextChanged()) and sets hasSerial back to false.
The other line in this block has no effect, since both Scan and Location have been set to empty strings just before.
What you probably intended to do was something like:
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
TextView Serial = (TextView) findViewById((R.id.LastSerialScanned));
TextView Location = (TextView) findViewById((R.id.LastLocationScanned));
if (!hasSerial) { // does trigger
if (Scan.getText().length() == 8) {
Serial.setText(Scan.getText());
hasSerial = true;
Location.setText("");
Scan.setText("");
}
} else {
Location.setText(Scan.getText());
hasSerial = false;
}
}
Related
I am using this code to add a dash('-') in a phone number after the 3rd and 4th number. The code is working just fine. My problem is that when I press backspace, I can't remove the dash. I can even add dots and I can delete them if I press backspace, but with dash it's just impossible.
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
MainActivity.headerName.setText("Verification");
phoneNumber = (EditText) getActivity().findViewById(R.id.phoneEditText);
int grup = 1;
phoneNumber.addTextChangedListener(new TextWatcher() {
int keyDel;
String a= phoneNumber.getText().toString();
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
phoneNumber.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KEYCODE_DEL) {
a = a.replace("-" , "");
phoneNumber.setText(a);
keyDel = 1;
}
return false;
}
});
if (keyDel == 0) {
int len = phoneNumber.getText().length();
if(len == 3 || len == 7) {
phoneNumber.setText(phoneNumber.getText() + "-");
phoneNumber.setSelection(phoneNumber.getText().length());
}
} else {
if(KeyEvent.isModifierKey(KEYCODE_DEL)) {
a = a.replace("-" , "");
phoneNumber.getText().toString().replace("-" , "");
phoneNumber.setText(a);
}
keyDel = 0;
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
I'm guessing that your UI widget is formatting its text. So, after you remove the hyphen, the widget is putting it back.
I suggest you leave the widget alone. Instead, when you need to use the phone number, remove the formatting characters from the value.
String.replaceAll("[^\\d]", "")
You would use this code when retrieving the value from the widget for some external use. So, you might have a method
public String getPhoneNumberUnformatted() {...}
That returns only the digits of the widget's value.
I'm getting this error when i'm implementing footer within recycler view.
This is how i have done it. I was using two types for showing different views in list, but something is not set well in method getItemCount() or maybe when i'm getting position of clicked item model in list.
This is what i have so far:
private final int VIEW_TYPE_ITEM = 0;
private final int VIEW_TYPE_FOOTER = 1;
#Override
public int getItemCount() {
return mUsers == null ? 0 : mUsers.size() + 1;
}
#Override
public int getItemViewType(int position) {
if (isFooterPosition(position)) {
return VIEW_TYPE_FOOTER;
}
return VIEW_TYPE_ITEM;
}
private boolean isFooterPosition(int position) {
return position == mUsers.size() + 1;
}
private User getUser (int position) {
return mUsers.get(position - 1); // Here i'm getting an error mentioned in title
}
Edit:
if (holder instanceof UserHolder) {
final User user = getUser(position);
UserHolder userViewHolder = (UserHolder) holder;
userViewHolder.tvUserName.setText(user.getName());
userViewHolder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mOnItemClickListener.onItemClick(v, position);
}
});
} else if (holder instanceof FooterViewHolder) {
FooterViewHolder footerViewHolder = (FooterViewHolder) holder;
Typeface typeface = Typeface.createFromAsset(mContext.getAssets(), "Lato-Thin.ttf");
footerViewHolder.mButton.setTypeface(typeface);
}
I have some items for normal holder view in list and one item for footer view.
mUsers.get(position - 1); will crash when the position is 0 because you're looking for the item at index -1 which is invalid.
If you're adding a footer, which will be present after all of the previous items, then do you need do the substraction?
Position 0 => User 0
Position 1 => User 1
Position N => User N
Position N + 1 => Footer
It might be better to just return mUsers.get(position).
Edit: There's another small issue:
Here's an issue:
private boolean isFooterPosition(int position) {
return position == mUsers.size() + 1;
}
mUsers.size() is 20, so users will have positions 0-19.
isFooterPosition should return true for 20 (users size + 1). However, that will return false because the footer is at position 21.
Thus, you have a spot (20) that is completely invalid.
private boolean isFooterPosition(int position) {
return position == mUsers.size();
}
I think you can modify getUser() method like following:
private boolean isValidPos(int position){
return position >= 0 && position < mUsers.size();
}
private User getUser (int position) {
if (isFooterPosition(position)) return null;
return isValidPos(position) ? mUsers.get(position) : null;
}
I can't see exactly what you want to do, but, as someone said before me, the error is in mUsers.get(position - 1);, because it's gonna search for a negative index if position == 0.
So, if you really need the subtraction, you can do like this:
private User getUser (int position) {
if(position != 0)
return mUsers.get(position - 1);
else
return mUsers.get(position);
}
But, as you can see, for position == 0, it will return the same output as position == 1.
I have found a solution and i have also extended RecyclerView with one more typeview for showing one view where there is no item:
First i have declared these variables in my adapter:
public static final int COUNT_FOOTER = 1;
public static final int COUNT_NO_ITEMS = 1;
private final int VIEW_TYPE_ITEM = 0;
private final int VIEW_TYPE_FOOTER = 1;
private final int VIEW_TYPE_NO_ITEM = 2;
After that i have define three view types for my list:
#Override
public int getItemViewType(int position) {
if (!mUsers.isEmpty()) {
if (position < mUsers.size()) {
return VIEW_TYPE_ITEM;
} else {
return VIEW_TYPE_FOOTER;
}
} else {
if (position == 0) {
return VIEW_TYPE_NO_ITEM;
} else {
return VIEW_TYPE_FOOTER;
}
}
}
#Override
public int getItemCount() {
if (!mUsers.isEmpty()) {
return mUsers.size() + COUNT_FOOTER;
} else {
return COUNT_NO_ITEMS + COUNT_FOOTER;
}
}
private User getUser (int position) {
return mUsers.get(position);
}
I'm creating a PV = nRT calculator that has the user enter any of the three given variables. Without the use of a button, the program will automatically detect that three variables have been given and will calculate the fourth missing variable automatically. This is my code so far:
Thread calculate = new Thread(new Runnable() {
#Override
public void run() {
try {
if (Calculations.isCalcable(pressure.getText().toString(),
volume.getText().toString(),
moles.getText().toString(),
temperature.getText().toString()) == true) {
if (pressure.getText().toString().length() == 0) {
pressure.setText("1010");
} else if (volume.getText().toString().length() == 0) {
volume.setText("1010");
} else if (moles.getText().toString().length() == 0) {
moles.setText("1010");
} else {
temperature.setText("1010");
}
}
} catch (Exception e){
}
}
});
calculate.start();
This doesn't work. Also I'm not sure if I'm actually supposed to use a Thread or not. Here's what happens when I enter three variables (The R variable is a constant):
Imgur
In this case the Temperature text should've changed to "1010".
Here's my isCalcable class:
public class Calculations {
public static boolean isCalcable (String pressure, String volume, String moles, String temperature){
int hasNumber = 0;
if (pressure.length() > 0){
hasNumber++;
}
if (volume.length() > 0){
hasNumber++;
}
if (moles.length() > 0){
hasNumber++;
}
if (temperature.length() > 0){
hasNumber++;
}
if (hasNumber == 3){
return true;
}
return false;
}
}
What do I do?
What you need is to detect whether value has been inputted on the
text fields right? Then have you looked at TextWatcher?
Here is an example on how to use it.
editText.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//code
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
//code
}
#Override
public void afterTextChanged(Editable s) {
//code
}
});
Basically you apply the TextWatcher to the three fields and watch.
If all three fields have the values you need, then do the calculation.
Maybe you can add global variables to the activity and check these global variables on the onTextChanged() method of the text field, and if three of the variables are already complete, set the value of the fourth one.
How can I detect when I press the return button on the on-screen keyboard which creates a newline in the EditText field.
I don't really care if I have to check for newline characters or the return key, but I want to send a message by pressing the return key on the keyboard.
I already tried a few different things, but I can't seem to get it working.
My EditText object is called chatInputET if you want to know.
add listener to your input:
chatInputET.addTextChangedListener( new TextWatcher(){
#Override
public void onTextChanged( CharSequence txt, int start, int before, int count ) {
if( -1 != txt.toString().indexOf("\n") ){
doSendMsg();
}
}
} );
chatInputET.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String string = s.toString();
if (string.length() > 0 && string.charAt(string.length() - 1) == '\n') {
// do stuff
}
}
});
Here's what I came up with. I put it in the onCreate when I set up the editText.
editText = (EditText) findViewById(R.id.editText1);
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) {
String string = s.toString();
if (string.length() > 0 && string.charAt(string.length() - 1) == '\n') {
// do stuff
// for me i get the string and write to a usb serial port
String data = editText.getText().toString();
if (usbService != null)
{
// if UsbService was correctly binded, Send data
usbService.write(data.getBytes());
editText.setText("");//i clear it.
}
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
For anybody with a multi line EditText wanting to detect a "\n" typed anywhere this is what I came up with:
editText.addTextChangedListener(object : TextWatcher {
private var oldText = editText.text.toString()
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { }
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { }
override fun afterTextChanged(s: Editable?) {
if (s == null) return
val oldLineBreakCount = oldText.count { it == '\n' }
val newLineBreakCount = s.count { it == '\n' }
if (oldLineBreakCount < newLineBreakCount) {
nestedScroll.smoothScrollBy(0, 64) // Scroll by the line height
}
if (oldLineBreakCount > newLineBreakCount) {
nestedScroll.smoothScrollBy(0, -64)
}
oldText = s.toString()
}
})
private fun isChangeLigne(s: String?): Boolean{
if (s != null && s.isNotEmpty()) {
if (s[s.length - 1] == '\n') {
return true
}
}
return false
}
This kotlin function can be used in onTextChanged callback with text string as parameter. Another solution is to use editText.lineCount property. You can check the line number with some code like:
var lineNumber = editText.lineCount
// in onTextChange callack
if(lineNumber!=editText.lineCount){
// detect line change
}
I have a TextWatcher set up and working (nearly) exactly as I want it. However, I would like this TextWatcher to stop as soon as the user enters a '.'. The only solution I have found so far crashes the app if the user entirely deletes the text. It is also important that the ENTIRE TextWatcher ends at the moment the user enters a '.'.
I have tried placing the TextWatcher within the loop, however it doesn't seem to work.
private TextWatcher userEnterListener = new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
if(after==0) {
shownText = "Please try again";
}
else if(after==1) {
shownText = "A";
}
else if(after==2) {
shownText = "An";
}
else if(after==3) {
shownText = "And";
}
else if(after==4) {
shownText = "Andr";
}
else if(after==5) {
shownText = "Andro";
}
else if(after==6) {
shownText = "Androi";
}
else if(after==7) {
shownText = "Android";
}
else if(after==8) {
shownText = "Android A";
}
else if(after==9) {
shownText = "Android Ap";
}
else if(after==10) {
shownText = "Android App";
}
else {
shownText = "Please try again";
}
}
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
recordedString = (s.toString());
update();
}
};
maybe this could work:
public void onTextChanged(CharSequence s, int start, int before,
int count) {
if(s.toString().equals("Android App") && start == '.'){
//here add an Empty TextWatcher to the EditText who has this TextWatcher added.
}
recordedString = (s.toString());
update();
}